diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE new file mode 100644 index 000000000..6ebda693f --- /dev/null +++ b/.github/ISSUE_TEMPLATE @@ -0,0 +1,31 @@ + + + +### Issue Type + + + - Bug Report / Support Request + - Feature Idea + - Documentation Report + +### Your Environment + + +``` + +``` + +### Your OS + + + - **macOS** (version) + - **Windows** (version) + - **Linux** (version) + +### Full console output + + + +### Summary + + diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..71587e092 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,99 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "20 3 * * 0" + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Set up Ruby. + uses: actions/setup-ruby@v1 + with: + ruby-version: 2.6 + + - name: Install test dependencies. + run: | + pip3 install yamllint + gem install rubocop + + - name: Lint code. + run: | + yamllint . + rubocop ./Vagrantfile ./lib/drupalvm \ + --except Metrics/LineLength,Security/Eval,Style/MutableConstant,Metrics/BlockLength,Metrics/MethodLength,Style/ConditionalAssignment,Style/IfUnlessModifier,Style/CaseLikeIf + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + include: + # Defaults. + - distro: ubuntu1804 + playbook: converge.yml + - distro: debian10 + playbook: converge.yml + - distro: centos8 + playbook: converge.yml + + # TODO: Add PHP 7.4 test. + # local_config: tests/ubuntu1804-php74.config.yml + # test_extras: false + # - distro: ubuntu1804 + # playbook: TODO + + # TODO: Add Postgresql test. + # local_config: tests/ubuntu1804-postgresql.config.yml + # config_dir: /var/www/drupalvm/config + # test_extras: false + # - distro: ubunt1804 + # playbook: TODO + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + # See: https://github.com/geerlingguy/ansible-role-mysql/issues/422 + - name: Disable AppArmor on Debian. + run: | + set -x + sudo apt-get install apparmor-profiles + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + if: ${{ startsWith(matrix.distro, 'debian') }} + + - name: Copy test scaffold files into place. + run: | + cp example.drupal.make.yml drupal.make.yml + cp example.drupal.composer.json drupal.composer.json + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} diff --git a/.gitignore b/.gitignore index 4d91e90e0..930d79a11 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,25 @@ +# OS-specific files. .DS_Store + +# Editor and language files. +.idea/ +.project/ +.bundle/ + +# Ansible files. +*.retry +.galaxy_install_info + +# Vagrant files. .vagrant/ vagrant_ansible_inventory_default -config.yml -drupal.make.yml -examples/prod/inventory + +# Drupal VM specific files. +drupal.composer.json +local.config.yml +Vagrantfile.local +/config.yml +/docker-compose.yml +/drupal.make.yml +/scripts/ +/drupal/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e14aae626..000000000 --- a/.travis.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- -language: python -python: "2.7" - -install: - # Install Ansible. - - pip install ansible - - # Add ansible.cfg to set local roles path. - - "{ echo '[defaults]'; echo 'roles_path = ../'; } >> ansible.cfg" - -script: - # Copy example files into place. - - cp example.config.yml config.yml - - cp example.drupal.make.yml drupal.make.yml - - # Make sure Ansible requirements install correctly. - - 'ansible-galaxy install -r provisioning/requirements.txt' - - # Run Ansible's syntax and playbook check on the main playbook. - - 'ansible-playbook -i "localhost," -c local provisioning/playbook.yml --syntax-check' - - # Check the config file and drupal make file YAML syntax. - - > - python -c "import yaml; yaml.load( open('example.config.yml', 'r'), Loader=yaml.CLoader )" - - > - python -c "import yaml; yaml.load( open('example.drupal.make.yml', 'r'), Loader=yaml.CLoader )" diff --git a/.yamllint b/.yamllint new file mode 100644 index 000000000..8fc434d23 --- /dev/null +++ b/.yamllint @@ -0,0 +1,18 @@ +--- +extends: default + +rules: + line-length: + max: 200 + level: warning + truthy: + allowed-values: ['true', 'false', 'yes', 'no'] + braces: + min-spaces-inside: 1 + max-spaces-inside: 1 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: -1 + +ignore: | + */stale.yml + provisioning/roles/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..52c075e98 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,1298 @@ +# Drupal VM Changelog + + +## 7.0.0 (2023-02-12) + +This version shall never be released :'-( + +Drupal VM is no longer maintained. See #2164 for details. + + +## 6.0.4 (2021-05-28) + +### Breaking Changes + +N/A + +### New/changed variables in default.config.yml + + * Added variable `vagrant_nfs_fix_enabled: false` - See #2154. If you are having trouble with NFS going away on macOS Big Sur, override this variable and set it to `true` to overcome a Vagrant bug in the latest version of macOS. + +### Improvements + + * Upgraded php-versions, solr, memcached, nginx, and mysql roles to latest versions. + +### Bugfixes + + * #2154: Add new `vagrant-nfs-fix` role to solve NFS issues on macOS Big Sur. + * #2166: Fix ansible version output regex matching for new core/community version output. + + +## 6.0.3 (2021-02-13) + +### Breaking Changes + +N/A + +### New/changed variables in default.config.yml + + * Replaced obsolete variable `php_opcache_enabled_in_ini` with `php_opcache_enable`. + +### Improvements + + * #2109: Switch CI test environment from homegrown script and Travis CI to Molecule and GitHub Actions. + * Updated Postgres role to latest version. + * Updated Composer role to latest version to allow switching between Composer major versions. + +### Bugfixes + + * #2137: Use pip3 inside VM if using ansible_local provisioner. + * #2144: Update docs for native synced folder usage due to changed typing of the variable in Vagrant. + * #2121: Replace php_opcache_enabled_in_ini with php_opcache_enable. + * Updated Drush role for better Composer v2 compatibility. + + +## 6.0.2 (2020-10-27) + +### Breaking Changes + +N/A + +### New/changed variables in default.config.yml + +The `hirak/prestissimo` package was removed from `composer_global_packages` (and that variable is now empty). + +### Improvements + + * N/A + +### Bugfixes + + * #2100: Remove hirak/prestissimo, for Composer v2 compatibility. + * #2095: Fix syntax errors in example drupal.composer.json file. + + +## 6.0.1 (2020-09-29) + +### Breaking Changes + +N/A + +### New/changed variables in default.config.yml + +N/A + +### Improvements + + * #2083: Improve README guide for installing Drupal 8 instead of default Drupal 9. + * Updated roles: security, nginx, mysql, php, php-mysql, solr, elasticsearch, repo-remi, composer. + +### Bugfixes + + * #2076: Fix bug when switching PHP versions to/from PHP 7.4. + + +## 6.0.0 "Rectifier" (2020-07-14) + +Drupal VM 6 drops support for some older OS distributions, to increase stability under the latest versions of Ubuntu, CentOS, and Debian, and to finally drop all support for the now-unsupported Python 2. + +The Drupal VM Docker container image is now based on Debian 10 Buster, though the default Drupal VM box when running as a VirtualBox VM is still based on Ubuntu 18.04. + +The default PHP version is now PHP 7.4, which works great with all the latest versions of Drupal 7, 8, and 9. + +### Breaking Changes + + * #2065: Drop official support for Debian 9, CentOS 7, and Ubuntu 16.04 and Python 2. + * #2061: Default to PHP 7.4. + * Drupal VM Docker container now based on Debian 10 Buster. + +### New/changed variables in default.config.yml + + * Removed `centos7`, `debian9`, and `ubuntu1604` from `vagrant_box` options. + * `ansible_python_interpreter` now defaults to `python3` (was `/usr/bin/python3`). + * `drupal_composer_dependencies` now includes both `"drush/drush:^10"` and `"drupal/devel:^4.0"`. + * `drupal_composer_project_package` now defaults to the recommended Drupal project: `"drupal/recommended-project:^9@dev"`. + * `drupal_major_version` is now `9` (was `8`). + * `php_version` is now `"7.4"` (was `"7.2"`). + * Added `php_xdebug_version: 2.9.5`. + +### Improvements + + * #2050: Default to Drupal 9. + * #1997: Include `php_xdebug_version` in default config for visibility. + * Updated roles: varnish, solr, elasticsearch, java, memcached, postgresql, adminer, php, drupal. + +### Bugfixes + + * #2041: Point to Python 3 interpreter in `$PATH`. + * #2062: Allow Composer to use more memory since it runs out at 1.5 GB. + * #2063: Update Devel version to work with Drupal 9. + * #2064: Explicitly require Drush on new sites to work with Drupal 9. + * #2066: Fix postfix service failure on CentOS 8 test container. + * #2059: Improve docs for Windows usage. + + +## 5.2.0 "The Game Has Changed" (2020-03-20) + +This release defaults to Python 3 for all Ansible-related tasks, which means some older OSes require a new variable to be overridden to work correctly. For most users, no change is required, however. The release also updates the order in which Postgresql updates + +### Breaking Changes + + * #2025: Ansible's Python interpreter now defaults to `python3` (was using default which was `python`). + * #2024: Postgresql database and user order of setup reversed, so users should not have 'db'/'priv' set, but database needs 'owner' set. + * #2025: Minimum required Ansible version is now 2.8. + * #2025: Minimum required Vagrant version is now 2.2.0. + +### New/changed variables in default.config.yml + + * `ansible_python_interpreter`: defaults to `/usr/bin/python3`, override to `/usr/bin/python` if using CentOS 7, Ubuntu 16.04, or Debian 9. + * `drupalvm_vagrant_version_min`: was `'1.8.6'`, now `'2.2.0'`. + * `drupalvm_ansible_version_min`: was `'2.5'`, now `'2.8'`. + * `postgresql_databases`: added `owner` parameter, set to `"{{ drupal_db_user }}"` + * `postgresql_users`: removed `db` and `priv` parameters. + * `solr_version`: was `"5.5.5"`, now `"7.7.2"`. + * `java_packages`: new variable, set to `openjdk-8-jdk` for Debian/Ubuntu, `java-1.8.0-openjdk` for RHEL/CentOS. + +### Improvements + + * #1960: Use latest Solr 7.x version for better install experience. + * #2025: Use Python 3 for Ansible on all the latest OSes. + * Updated roles: php-pecl, postgresql, php, mysql. + +### Bugfixes + + * #2024: Fix chicken-and-egg ordering of postgresql database and user ownership. + * #1675: Get CI tests for Postgresql working again. + + +## 5.1.1 (2020-02-27) + +### Breaking Changes + + * Removed 'official' support for CentOS 6 and Debian 8. These older OSes may still work, but [it would be extremely painful](https://www.youtube.com/watch?v=RZhp-Uctd-c) to keep using them. + +### New/changed variables in default.config.yml + +N/A + +### Improvements + + * Improved CentOS 8 compatibility. + * Updated roles: drupal, php-xdebug, php-xhprof, php-versions, java, security, nodejs, elasticsearch, firewall, varnish, blackfire, daemonize, mysql, postgresql, ruby, php-pecl + +### Bugfixes + + * #2011: Fix broken link in Solr documentation. + + +## 5.1.0 "Recognizer" (2019-12-03) + +This release adds support for PHP 7.4, and completely drops PHP 5.6 support (in the past, brave and daring souls could attempt to run 5.6—it is almost impossible to do so in Drupal VM as of this release). + +### Breaking Changes + + * #1987: Minimum required Ansible version is now 2.5. + * #1993: Dropped support for old unsupported PHP versions: 5.6, 7.0, 7.1. + +### New/changed variables in default.config.yml + + * `drupalvm_ansible_version_min: '2.5'` (was `'2.4'`) + * `php_version` supports `"7.2"`, `"7.3"`, or `"7.4"` (5.6, 7.0, and 7.1 dropped) + +### Improvements + + * #1993: Add PHP 7.4 support. Drop 5.6, 7.0, and 7.1 support. + * Updated roles: mailhog, postgresql, php-versions. + * Update `config.yml` documentation to use modern PHP version. + +### Bugfixes + +N/A + + +## 5.0.2 (2019-11-04) + +### Breaking Changes + +N/A + +### New/changed variables in default.config.yml + +N/A + +### Improvements + + * #1982: Updated Dashboard to Boostrap 4 for improved accessibility. + * Updated various roles to ensure Ansible 2.9 compatibility. + * Tested Drupal VM on macOS Catalina with latest versions of Vagrant and VirtualBox. + * Updated roles: postgresql, firewall, git, php-versions, varnish + +### Bugfixes + + * #1969: Documentation typo fix for Linux installation. + * #1973: Fix site-install error in certain circumstances. + + +## 5.0.1 (2019-08-29) + +### Breaking Changes + +N/A + +### New/changed variables in default.config.yml + +N/A + +### Improvements + + * #1943: Update drupal console remote site example. + * Updated roles: php-versions, nginx, composer, postgresql, apache, git, mysql, solr, drupal. + +### Bugfixes + + * #1920: Update git sandbox URL for pareview script. + * #1953: Fix typo in Linux installation guide. + * #1963, #1903, #1962, #1964: Fix PHP version mismatch when switching versions from 7.2 to 7.1. + + +## 5.0.0 "Flynn Lives" (2019-04-09) + +There are no major architectural changes in this release, which speaks to the current maturity of the Drupal VM platform; instead, this release focuses on updating all the default versions—most especially of the base OS to Ubuntu 18.04 'Bionic'. If you need to remain on Ubuntu 16.04 for now, please make sure you explicitly set `vagrant_box: geerlingguy/ubuntu1604` in your `config.yml`, or use a version of the `geerlingguy/drupal-vm` Vagrant box _older than_ `2.0.0`. + +### Breaking Changes + + * #1881: Ubuntu 18.04 is now the default OS version (and is used in the `geerlingguy/drupal-vm` base image `2.0.0` and later) + * Ubuntu 14.04 is no longer supported. + * #1874: PHP 7.2 is now the default PHP version + * PHP 5.6 is no longer supported (though you may be able to install it for some time). + * #1885: Node.js 10.x is now the default Node.js version. + * Node.js 0.10, 0.12, 4.x, and 5.x are no longer supported (though you may be able to install some of them for some time). + +### New/changed variables in default.config.yml + + * `php_version` changed from `7.1` to `7.2` + * `nodejs_version` changed from `6.x` to `10.x` + +### Improvements + + * #1919: Ran out of songs from original Tron soundtrack; releases shall now be named after Tron: Legacy tracks. + +### Bugfixes + + * #1895: Fixed typo in Drush docs. + + +## 4.9.2 (2019-01-03) + +### Breaking Changes + + * Ubuntu 14.04 is still supported as long as the LTS release is receiving security updates, but some functionality may start breaking for Ubuntu 14.04, as more and more upstreams are dropping support for the old Ubuntu version. + +### New/changed variables in default.config.yml + + * #1774: `vagrant_box` was changed to `geerlingguy/drupal-vm`. This box is faster to start in all cases, and should work fine even when switching between Apache/Nginx or MySQL/PostgreSQL. You can always override and switch back to `geerlingguy/ubuntu1604` or whatever base box you prefer. + +### Improvements + + * #1760: Add test and support for Ubuntu 18.04 Bionic Beaver. + * #1883: Drop 'official-ish' support for using Drupal VM for prod. + * #1851: Remove Ubuntu 14.04 from test suite as more upstreams are dropping support. + * #1774: Switch to default Drupal VM base box for faster provisioning. + * #532: Update BigPipe docs slightly. + * #1619: Add an example of what to put in secrets.yml. + * Updated roles: apache, php-versions, composer, php, java, varnish, elasticsearch, php-pecl, tideways, nginx, security, postgresql + +### Bugfixes + + * #1843: Drush 9.5.0 was breaking due to some pathing issues. + * #1846: Fixed typo in build-composer.yml that caused composer install to fail. + * #1854: Document older Varnish version requirement for CentOS 6. + * #1880: Disable audio driver in VirtualBox VM. + + +## 4.9.1 (2018-10-10) + +### Breaking Changes + +N/A + +### New/changed variables in default.config.yml + + * The Devel module dependency in `drupal_composer_dependencies` was changed from `1.x-dev` (which no longer seems to work) to `^1.2`. + +### Improvements + + * #1827: Improve Tideways documentation. + * #1589: Add name to Ansible provisioner. + * #1823: Remove Debian 8 CI test, Debian 9 suffices. + * Updated roles: solr, ruby, varnish, nodejs, java, mysql, composer, php, firewall, apache, and many others with fixes for Ansible 2.7+ and linting issues. + +### Bugfixes + + * #1761: Fix deprecation warnings in Ansible 2.7.0. + * #1822: Update composer role to fix CentOS 7 Composer download bug. + * #1743, #1831: Use stable version of Devel via Composer. + + +## 4.9.0 "Creation of Tron" (2018-06-01) + +This release improves compatibility with Ansible 2.4, 2.5 and beyond, and updates almost every Ansible role in Drupal VM. + +### Breaking Changes + +N/A + +### New/changed variables in default.config.yml + + - Removed unused `php_xdebug_cli_enable` variable. + - Added `php_xdebug_cli_disable: yes`. + +### Improvements + + * #619, #1720: Add documentation for using Eclipse and Visual Studio Code with xdebug. + * #1552: Better PHP 7.2 compatibility with XDebug. + * #1553: Fix use of deprecated 'include' syntax in Ansible playbooks. + * #1566: Remove unused `php_xdebug_cli_enable` variable. + * #1778: Remove Ansible 2.2 compatibility-related tasks. + * Updated roles: selenium, php-tideways, firewall, solr, nginx, drupal console, apache, varnish, postgres, new relic, java, composer, php, mysql, blackfire, elasticsearch, drush, drupal, node.js, php-redis, php-tideways, php-versions, xhprof, redis, security, ruby. + +### Bugfixes + + * #1736: Better Ansible version parsing in Vagrantfile. + * #1654: Make sure Tideways can be installed. + * #1518: Improve use of old versions of Solr on newer OS releases. + + +## 4.8.1 (2018-03-10) + +### Breaking Changes + +Drupal VM now requires Ansible 2.4+ if you are using the version installed on your host. (Used to require 2.2+). + +### New/changed variables in default.config.yml + + * `drupalvm_ansible_version_min` is now `2.4`. Make sure to upgrade if you're on an older version! + +### Improvements + + * #1701: Ansible required version is TOO DARN LOW! + * #1682: Add documentation for setting up Atom with XDebug. + * Updated roles: git, ruby, apache-php-fpm, solr, security, java, git, php. + +### Bugfixes + + * #1692: Fix the install-drupal command on the Docker image. + * #1704: Ansible version check is done on host even when force_ansible_local is true. + * #1708: Selenium paths value in docs should be quoted. + + +## 4.8.0 "Tower Music / Let Us Pray" (2018-01-30) + +This release is all about Drush. Please read my blog post [Drupal VM 4.8 and Drush 9.0.0 - Some major changes](https://www.jeffgeerling.com/blog/2018/drupal-vm-48-and-drush-900-some-major-changes) for details and more background. + +If you have Drush 8 installed on your host machine, primarily use Drush _outside_ of Drupal VM, and don't use a Drush make file, none of the breaking changes should affect you. + +### Breaking Changes + + * Drush is no longer installed inside Drupal VM if you have `drush` in `installed_extras`. Drush Launcher is installed by default. + * The `drush_version` configuration option is no longer used by default. + * Drush make files cannot be built with Drush 9+. If you have `drupal_build_makefile: true` in your `config.yml`, you _must_ add configuration to install an older version of Drush inside Drupal VM. See the [Drupal VM Drush make docs](http://docs.drupalvm.com/en/latest/deployment/drush-make/). + +### New/changed variables in default.config.yml + + * Added the following variables to support Drush 9: + * `drush_aliases_host_template_yml: "templates/drupalvm.aliases.yml.j2"` + * `drush_aliases_guest_template_yml: "templates/drupalvm-local.aliases.yml.j2"` + * Removed now-unused variable: `drush_version: "8.1.15"` (Drush Launcher is installed by default inside Drupal VM). + +### Improvements + + * #1672: Upgrade Drupal VM to use Drush Launcher and natively support Drush 9.0.0. + * #1595: Create Drush global aliases that work for Drush 9+ and work outside Drupal VM. + * Updated roles: drush. + +### Bugfixes + +N/A + + +## 4.7.2 (2018-01-29) + +### Breaking Changes + +N/A + +### New/changed variables in default.config.yml + + * #1624: Added `beet/box` to list of recommended base boxes (for faster Ubuntu 16.04 provisioning). + * #1668: Fixed some comments which had incorrect variable references. + * Updated `drush_version` to `"8.1.15"` (was `"8.1.14"`). + +### Improvements + + * Updated roles: drush. + +### Bugfixes + + * #1659: Mention changes required for CentOS when using specialized synced folder methods. + * #1539: Update Drush role so Drush installs correctly on Debian 8 and 9. + + +## 4.7.1 (2018-01-23) + +### Breaking Changes + +N/A + +### New/changed variables in default.config.yml + + * `nodejs_npm_global_packages` now adds `npm` by default (see #1651). + * `solr_version` is now `5.5.5` by default (was `5.5.3`). + +### Improvements + + * #1602: Add machine name to dashboard header. + * #1651: Update NPM when provisioning (as per NPM's recommendation). + * Solr default version updated to `5.5.5`. + * Updated roles: php-xdebug, solr, mysql, postfix. + +### Bugfixes + + * #1606: Fix vagrant-cachier for modern nfs installations with udp disabled. + * #1585: Fix typo in README.md + * #1653: Fix typo in mkdocs.yml + * #1617: Fix typos in PHP.md + + +## 4.7.0 "Water, Music, and Tronaction" (2017-10-06) + +### Breaking Changes + + * In Issue #1520, the precedence of configuration override files was changed slightly. Previously, `[environment].config.yml` overrode all other configuration files, including `local.config.yml`. The intention of the local config file is that it is always the final override. The order of config file precedence (from lowest to highest) is now: + 1. `config.yml` + 2. `secrets.yml` + 3. `[environment].config.yml` + 4. `local.config.yml` + +### New/changed variables in default.config.yml + + * Removed `geerlingguy/ubuntu1204` support (LTS support ended in April). + * Default `vagrant_hostname` is now `drupalvm.test` (Google owns `.dev` and some DNS issues have forced us to switch to `.test` as the default). + * Added `drupal_db_host: localhost` to fix a DB connection issue with Debian 9 'Stretch'. + * Added `headers.load` to `apache_mods_enabled`. + * Updated `drush_version` to `8.1.14`. + * Updated example `post_provision_scripts` path to include the full `playbook_dir`-based path. + +### Improvements + + * #1551: Add PHP 7.2 support via php-versions role. + * #1427: Use drupalvm.test for local development default. + * #1521: Remove Ubuntu 12.04 support, officially. + * #1521: Install Ansible with pip if provisioning inside the VM. + * #1527: Revamp dashboard for better layout, especially on mobile. + * #1476: Update Drupal role to speed up initial Drupal project generation. + * #1487: Install mod_headers for Apache by default. + * #1528: ALways enable linked clones in VirtualBox. + * #1520: Let local.config.yml override environment.config.yml. + * #1564: Allow spaces in `DRUPALVM_ANSIBLE_ARGS` to make it more useful. + * #1560, #1558: Various improvements to test scripts. + * #1451: Bump the Drupal VM Docker image base to Debian 9 'Stretch'. + * #1451: Add full support and automated tests for Debian 9 'Stretch'. + * #1504: Display (this may take a while) for long-running Composer tasks. + * #1507: Use https URL to download Adminer. + * #1495: Update Drupal role so composer install can be skipped on deploy. + * #1573: Update default Drupal version to 8.4.x, Drush to 8.1.14. + * Updated roles: postgresql, firewall, nginx, php-pecl, mysql, varnish, ruby, adminer, nodejs, php, php-versions. + +### Bugfixes + + * #1456: Default Docker example uses incorrect image. + * #1481: Use absolute paths for example post_provision_scripts. + * #1468: Fix various Linux issues with NFS by defaulting to TCP. + * #1508: Switch to using localhost for MySQL so install-drupal works on Debian 9. + * #1540: Fix incorrect IP address in some docs. + * #1558: Update Daemonize role to work on Ubuntu 14.04 with Ansible 2.4. + * #1572: Fix broken link to Drupal Console documentation. + + +## 4.6.0 "Water, Music, and Tronaction" (2017-06-28) + +### Breaking Changes + + * If you have `varnish` in your `installed_extras`, then the newest version of the Varnish role included in this release changes the Varnish package repository (on all OSes) to use the latest supported Varnish packages from Varnish's official packagecloud.io repos. This allows you to specify Varnish versions anywhere from the latest (currently 5.1) to early 2.x versions (and everything in-between)... but you might either have to uninstall Varnish before updating existing VMs, or just rebuild your VM to take advantage of the latest role version. + +### New/changed variables in default.config.yml + + * `vagrant_box` still defaults to Ubuntu 16.04, but you can now use Debian 9 ('Stretch') if you set the variable to `geerlingguy/debian9`. + * `vagrant_plugins` was added (see #1378), and contains a list of Vagrant plugins that—if not already installed—will be installed for use by Vagrant. + +### Improvements + + * #1455: Update Varnish role to allow for Varnish 5.1, 5.0, and any older version. + * #1451: Document the availability of `geerlingguy/debian9` base box (and Docker base container). + * #1378: Automatically install a configurable list of Vagrant plugins (`hostsupdater` and `vbguest` by default). + * #1423: Add documentation on using the official Docker image for quick Drupal testing environments. + * #1388, #1389: Use `geerlingguy/drupal-vm` docker image by default in Docker Compose file. + * #1437: Allow list of paths in `pre_provision_tasks_dir` and `post_provision_tasks_dir` (used to just be one path maximum). + * #1443: Add IRC badge linking to `#drupal-vm` freenode IRC room on Riot. + * #1171: Support using XDebug to debug Drush commands inside Drupal VM. + * #1368: Ensure private filesystem works correctly when using Nginx. + * #1375: Allow /vagrant default synced folder to be managed like other synced folders. + * #1406: Minor doc improvement for using Tideways instead of XHprof when using PHP 7+. + * #1431: Minor doc improvement for `composer docker-bake` command. + * #1386: Remove dated Acquia example and point to BLT's configuration instead. + * #1418: Allow PHP configuration to be overridden so default system packages can be used instead of Ondrej Sury's repo (allowing PHP 5.3, 5.4, and 5.5 to be used when absolutely necessary). + * #1424: Add support for RFC 5785 (`.well-known`) when using Nginx. + * #1451: Use 192.168.89.89 for default Docker Drupal VM IP. + * Updated roles: PostgreSQL, PHP Versions, Redis, Nginx, Varnish. + +### Bugfixes + + * #1403: Ensure PostgreSQL works correctly on all supported OSes. + * #1399: Fix bug where Drupal would reinstall on reprovision if not using English as the default language. + * #1384, #1420: Update docs in Solr example for more clarity concerning use with Drupal 8. + * #1444: Fix outdated comment for `drupal_install_site` variable. + * #1411: Fix `.gitignore` file applying rules to files in subdirectories. + + +## 4.5.0 "Break In (For Strings, Flutes, and Celesta)" (2017-05-24) + +### Breaking Changes + + * The default `nodejs_version` is now set to `6.x`; if you need to stay on `0.12` or some other version, be sure to set the version explicitly in your own `config.yml`. + +### New/changed variables in default.config.yml + + * Changed variables: + * `nodejs_version: "6.x"` (was `0.12`) + * New variables: + * Reconfigurable templates for Drush Aliases: + * `drush_aliases_host_template: "templates/drupalvm.aliases.drushrc.php.j2"` + * `drush_aliases_guest_template: "templates/drupalvm-local.aliases.drushrc.php.j2"` + * Reconfigurable template for Nginx hosts: + * `nginx_vhost_template: "templates/nginx-vhost.conf.j2"` + * `firewall_enabled: true` (allows the disabling of Drupal VM's default firewall, e.g. for Docker usage) + * `php_xdebug_remote_host: "{{ ansible_default_ipv4.gateway }}"` (prevents warnings when using Xdebug) + * New Docker configuration options: + * `docker_container_name: drupal-vm` + * `docker_image_name: drupal-vm` + * `docker_image_path: ~/Downloads` + * New hostname configuration options: + * `hostname_configure: true` + * `hostname_fqdn: "{{ vagrant_hostname }}"` + +### Improvements + + * #1206: Add instructions for running Drupal VM inside Docker. + * #1356: Add an official geerlingguy/drupal-vm image on Docker Hub. + * #1366: Make Drupal VM Docker image easier to use for single-site installations. + * #1377: Extract php-versions (version switching tasks) into standalone role so anyone can use it. + * #1353: Update default Node.js version to 6.x. + * #1327: Refactor task includes into drupalvm Ansible roles. + * #1329: Update Nginx role, allowing use of extensible Nginx templates. + * #1254: Refactor Drupal VM's Nginx templates to allow for extensibility. + * #1349: Make it easier to install Node.js global packages by name. + * #1258: Finalize documentation for Git-based deployment. + * Updated roles: Firewall, Nginx, Node.js, Apache, Selenium. + +### Bugfixes + + * #1351: Fix documentation bug concerning paths in example.drupal.composer.json. + * #1304: Fix documentation bug concerning Behat paths. + * #1350: Set the `php_xdebug_remote_host` to prevent Xdebug warnings. + * #1347: Fix LoadError message on vagrant up/down. + + +## 4.4.5 (2017-04-24) + +### New/changed variables in default.config.yml + + * `drupalconsole` is no longer enabled globally by default (see #1335 and #1338). + +### Improvements + + * #1333: Add docs on using Drupal VM with Wordpress and other PHP apps. + +### Bugfixes + + * #1335: Update Drupal Console Role so it works correctly with rc17 and beyond. + * #1338: Remove drupalconsole from default installed_extras list. + + +## 4.4.4 (2017-04-22) + +### New/changed variables in default.config.yml + + * N/A + +### Improvements + + * #1271: Don't run PHP role for 'drupal' tag. + * Updated Ansible roles: `postgresql`, `drupal`. + * #1323: Default synced folder type to `vagrant_synced_folder_default_type` if unset. + +### Bugfixes + + * #1324: Only depend on `geerlingguy.nginx` when `drupalvm_webserver` is `nginx`. + + +## 4.4.3 (2017-04-20) + +### New/changed variables in default.config.yml + + * Added `ssh_home: "{{ drupal_core_path }}"` so `vagrant ssh` drops you directly into the core path by default. + +### Improvements + + * Updated Ansible roles: `mysql`, `solr`, `nodejs`, `drupal`, `varnish`. + * #1177: Mention the availability of the `geerlingguy/debian8` base box. + * #1265: Document reverse-mount shares. Also scaffolds Issue #1258. + * #1272: Set ssh_home by default since it's really helpful. + * #1259: Update some performance-related docs. + * #1317: Remove duplicate handler and extract www tasks into new role. + +### Bugfixes + + * #1294: Fix 'Cannot load Zend OPcache' notice. + * #1306: Fix Ansible 2.3-related bug with jinja2 inside when statement. + * #1302: Remove `ansible_ssh_user` variable to avoid upstream bugs. + * #1314: Revert "Move simple `include_vars` statement to `vars_files`" + + +## 4.4.2 (2017-04-12) + +### New/changed variables in default.config.yml + + * N/A + +### Improvements + + * Updated Ansible roles: `firewall`, `mailhog`, `apache`, `git`, `mysql`, `solr`, `adminer`, and `varnish`. + * #1289: Update Linux host docs to mention encryption as primary reason for NFS issues. + +### Bugfixes + + * #1280: Documentation bugfix for a Quick Start Guide link. + * #1275: Update Adminer role to prevent download timeouts. + * #1281: Avoid TypeError when a configuration file is empty. + * #1291: Teensy tiny docs grammar fix. + + +## 4.4.1 (2017-04-01) + +### New/changed variables in default.config.yml + + * N/A + +### Improvements + + * Updated Ansible roles: `drupal`, `drush`, and `solr`. + +### Bugfixes + + * #1245: Follow-up to make sure VM initial provisioning works as expected. + * #1261: Run hostname.yml tasks for `drupal` tag to prevent errors. + * Fixed pareview.sh script configuration example. + * Tweaked docs for Selenium and Production for clarity. + + +## 4.4.0 "Sea of Simulation" (2017-03-24) + +### Breaking Changes + + * No breaking changes. + +### New/changed variables in default.config.yml + + * `php_version` now defaults to `"7.1"` (was `"7.0"`). + +### Improvements + + * #1252: Allow Drupal to be deployed into Drupal VM from a Git repository. + * #1177: Add full and CI-tested support for Debian 8. + * #1213: Add `DRUPALVM_ANSIBLE_TAGS` environment variable to specify tags to run. + * #1031: Switch default PHP version to `7.1`. + * #1211: Add mcrypt PHP extension on RedHat-based installs. + * #1215: Document alternative method of running Drupal Console commands. + * Removed logic supporting PHP 5.5, as it's no longer supported. + * #1233: Tidy up the main Drupal VM playbook. + * #1198: Use VAGRANT_HOME to get the SSH `insecure_private_key` directory for Drush. + * #1238: Add a configurable intro message for `vagrant up` and `vagrant reload`. + * #1230: Allow `Vagrantfile.local` to be either in project _or_ config directory. + * #1244: Add support for a `secrets.yml` file for use with Ansible Vault. + * #1135: Improve Sublime Text XDebug documentation. + * Updated roles: Drush, Drupal, Firewall, Varnish. + +### Bugfixes + + * #1199: Make sure `rsync` synced folders' `owner` and `group` are applied correctly. + * #1212: Fixes Drush make builds after Drush role installation technique changed. + * #1237: Raise a `VagrantError` for clearer error messaging. + * #1220: Ensure `www-data` is in the group of the NFS synced directory (file permissions). + * #1245: Ensure production `init.yml` playbook works on Ubuntu 16.04. + * #1250: Document use of `DRUPALVM_ENV` variable in production docs. + * #1253: Ensure `geerlingguy.php` role is run when `drupal` tag is used. + + +## 4.3.1 (2017-03-14) + +### New/changed variables in default.config.yml + + * Removed now-unneccessary `drush_keep_updated` and `drush_composer_cli_options` vars. + * Default to Drush version `8.1.10` (since we use the Phar-based install by default now). + +### Improvements + + * #1197: Add PAReview.sh script setup to Drupal VM. + * #1213: Add task-specific tags for supercharged reprovisioning. + * #1212: Update Drush role and shave a minute or so off every build, ever! + * #1215: Add docs on using Drupal Console with `vagrant exec`. + * Update roles with bugfixes and improvements: Drush, Drupal. + +### Bugfixes + + * #1211: Add mcrypt PHP extension on RedHat-based installs. + + +## 4.3.0 "Ring Game and Escape" (2017-03-09) + +### Breaking Changes + + * No _explicit_ breaking changes; however, you should update any of the changed variables in the 'Updated Drupal-specific variable names' section below. + +### New/changed variables in default.config.yml + + * `vagrant_gui: false` added (allows UI to appear after running `vagrant up` - Issue #1175). + * Updated Drupal-specific variable names (Issue #1192): + * `drupalvm_database` changed to `drupal_db_backend` + * `build_makefile` changed to `drupal_build_makefile` + * `build_composer` changed to `drupal_build_composer` + * `build_composer_project` changed to `drupal_build_composer_project` + * `install_site` changed to `drupal_install_site` + * `drupal_core_owner` added (defaults to `drupalvm_user` - Issue #1192) + * `tideways` added (commented out) to `installed_extras` (Issue #1181) + +### Improvements + + * #1192: Move Drupal build and install code into revamped `geerlingguy.drupal` role. + * #1175: Add `vagrant_gui` option to allow GUI to show when running `vagrant up`. + * #1200: Only install necessary development packages (for faster, lighter builds). + * Roles updated to latest version: Composer, Solr, Java, Selenium, Drush, Firewall, and Varnish. + +### Bugfixes + + * #1167, #1181, #1168, #1188: Documentation tweaks. + * #420: Update Drush role so 'run drush to set it up' doesn't fail. + * #1182: Clean up Tideways documentation. + + +## 4.2.1 (2017-02-08) + +### Improvements + + * Update Nginx, Java, Composer, and Selenium roles to latest version. + +### Bugfixes + + * #1158: Fix Drupal 7 and Nginx breaking install.php access. + * #1155: Fix failure installing Chrome on Ubuntu 14.04 (Selenium role). + * #1151: PHP docs fix. + + +## 4.2.0 "Theme From Tron" (2017-01-30) + +### Breaking Changes + + * N/A + +### New/changed variables in default.config.yml + + * `apache_packages_state: latest` added to ensure latest Apache version is installed. + * `firewall_disable_firewalld: true` and `firewall_disable_ufw: true` to ensure the system default firewalls are disabled on CentOS and Ubuntu, respectively (we set up our own rules, so this prevents weird problems). + +### Improvements + + * #1123: Add Tideways support and updated documentation for use. + * #1107: Allow additions to PHP packages via php_packages_extra. + * #1092: Docs makeover. + * #1134: Make Solr core work out of the box with Drupal 8 Search API Solr more easily. + * #1110: Move `cron` example to the Docs. + * #649: Document how to use `vagrant-lxc` with Drupal VM. + * Update roles to latest versions: firewall, elasticsearch, nodejs, solr, nginx. + +### Bugfixes + + * #1093: Upgrade Apache packages on provision so latest release is installed. + * #1101: Update Selenium role so it works on systemd systems (e.g. Ubuntu 16.04, CentOS 7). + * #1102: Update ruby role to add gem bin directory to `$PATH`. + * #1131: Fixes solr < 5 on Ubuntu 16, CentOS 7 with Ansible 2.2. + + +## 4.1.1 (2016-12-30) + +### Bugfixes + + * #1093: Install correct version of Apache on Ubuntu 12.04 and 14.04 for `SetHandler`. + + +## 4.1.0 "Anthem" (2016-12-30) + +### Breaking Changes + + * N/A + +### New/changed variables in default.config.yml + + * There's a new `apache_vhost_php_fpm_parameters` variable that defines the PHP-FPM handler Apache uses per-virtualhost. The old `extra_parameters` pre-4.1.0 will continue to work, but the new `SetHandler` technique is better for most scenarios than using `ProxyPassMatch`. + * The Dashboard entry in `nginx_hosts` now has `is_php: true`. + +### Improvements + + * #617: Switch to `SetHandler` instead of `ProxyPassMatch` (fixes #617, #876, #945, #1055). + * #1090: Update docs to reference `SetHandler`. + * #1047: Add docs on Drupal Console remote command execution. + * #1076: Update PHP XDebug role to latest version + * #1067: Configure hostname for environments other than VMs. + * #1068: Add php-yaml extension. + * #1078: Move Ansible version check to Vagrantfile for better UX. + * #1071: Improve docs for SSL under Apache and Nginx. + * #455: Move prod readme to docs instead of README file. + +### Bugfixes + + * #1076: Fix PHP modules not re-compiling on PHP version changes. + * #1061: Allow user defined post-provision-tasks to use tags. + * #1060: Fix bug where dashboard assumes optional vhost docroot is defined. + * #1062: Allow post-provision tasks to use the item variable. + * #1059: Fix hostsupdater trying to add wildcard aliases. + * #1054: Update Solr role to prevent permissions error. + + +## 4.0.0 "We've Got Company" (2016-12-10) + +### Breaking Changes + + * Drush is now an optional `installed_extra`. **If you use Drush, and it's not installed as part of your own project's dependencies**, make sure you add `drush` as one of the `installed_extras` in your `config.yml`. + * Vagrant 1.8.6 or later, VirtualBox 5.1.10 or later, and Ansible 2.2.0 or later (if installed on host) are now required. + * PHP 7.0 is still the default, but **you can install PHP 7.1**, or **switch to PHP 5.6** on-the-fly, thanks to #1043—on any supported OS! See the updated docs: [Using other versions of PHP](http://docs.drupalvm.com/en/latest/other/php/) + +### New/changed variables in default.config.yml + + * `drush` is now a default item in `installed_extras`. + * `upload-progress` is now an optional item in `installed_extras`. + * `drush_version` now defaults to `8.x` (`master` was causing issues with Drupal < 8). + * `php_install_recommends` was removed from the default set of variables. + * `solr_version` was bumped to `5.5.3` (was `5.5.2`). + +### Improvements + + * #1043: Make switching PHP versions easier, and add support for PHP 7.1. + * #711: Make Drush optional. + * #788: Add optional PHP upload_progress support. + * #992: Add optional `DRUPALVM_ANSIBLE_ARGS` support for Ansible CLI options. + * #1002: Allow shallow Drush clones for faster builds. + * #1007, #1009: Added a GitHub ISSUE_TEMPLATE to help my sanity. + * #1018: Fix Solr versioning error in Solr role. + * #823: Set composer.json type to `vm` instead of `project`. + * Update following Ansible roles to newer versions: Solr, Nginx, Git, PHP, Firewall, Apache, PHP-XDebug, PHP-Redis. + +### Bugfixes + + * #981: Bump minimum required Vagrant and VirtualBox versions. + * #1014: Fix path in extra tasks example. + * #1020: Switch to Drush `8.x` branch (instead of `master`/`9.x`) for Drupal 6/7 compatibility. + * #1004: Add note about `php_pgsql_package` for PHP 5.6 (superceded by later work). + * #1037: Fix Acquia configuration example for PHP 5.6 (superceded by later work). + + +## 3.5.2 (2016-11-17) + +### Improvements + + * #983: Added a CHANGELOG.md (this thing you're reading!). + * #872: Improve synced folder documentation for owner/group. + * #847: Add documentation on using `vagrant-proxyconf` in local Vagrantfile. + * #455: Environment-specific config file support (e.g. `prod.config.yml`). + * #991: Reduce tasks run during Travis CI validation, clean up tests. + * Update to latest role versions: PHP, PHP-PECL, Varnish, MySQL, Solr + +### Bugfixes + + * #998: Fix documentation search capability on http://docs.drupalvm.com/en/latest/. + * #947: Fix Varnish default configuration to purge correctly. + * #989: Use latest (correct) version of Varnish role. + * #980: CentOS install for Firewall and Mailhog fixed. + * (No issue) Fix PHP 5.6 documentation to make sure PHP 7 doesn't also get installed. + + +## 3.5.1 (2016-11-07) + +### Improvements + + * Update to latest version of Drush Ansible role for better composer performance. + +### Bugfixes + + * #968: Fix for Ansible 2.2.x and PostgreSQL as database server. + * #971: Fix for PHP 5.5 PPA usage on Ubuntu 12/14. + * #912: Fix for Vagrant 1.8.6+ not mounting synced folders if `mount_options` is empty. + + +## 3.5.0 "Tron Scherzo" (2016-11-02) + +### Breaking changes + + * Latest `geerlingguy/*` Vagrant box versions recommend VirtualBox 5.1.6+ and Vagrant 1.8.6+. + * Roles should work with any Ansible version later than 2.0... but 2.2+ is now recommended. + +### New/changed variables in default.config.yml + + * `drupalvm_vagrant_version_min` is now `1.8.6` (was `1.8.5`) + +### Improvements + + * #950: Use default sync folder type for `vagrant-cachier` if present. + * #957: Update various roles for better Ansible 2.2.x compatibility. + * #962: Allow configuration of PHP `disable_functions`. + * #963: Bump required Vagrant version. + +### Bugfixes + + * #925: Fix MySQL install on CentOS 6. + * #870: Fix invalid cron example syntax. + * #956: Fix Apache failure if using Nginx as webserver. + * #928: Fix rubocop test on Travis. + * #927: Fix PHP docs duplicate config vars. + * #936: Fix `mysql_*`/`db_*` variable names in documentation. + + +## 3.4.0 "Anthem for Keyboard Solo" (2016-10-12) + +### Breaking changes + + * _If you have `selenium` in installed extras_: The `arknoll.selenium` role now defaults to installing Google Chrome / chromedriver instead of Firefox. See the role's [documentation](https://github.com/arknoll/ansible-role-selenium#variables) to see which variables should be set if you want to stick with Firefox (see: #924). + * _If you're running PHP 5.6 with the `geerlingguy/ubuntu1404` box_: PHP 5.6 under Ubuntu 14.04 was using a deprecated PPA. Since switching to Ondrej's updated PPA, we had to also update the list of packages/paths in the [documentation for running PHP 5.6 under Drupal VM](http://docs.drupalvm.com/en/latest/other/php-56/). If you are using PHP 5.6, be sure to update your `php_*` variables (see: #921). + +### New/changed variables in default.config.yml + + * `vagrant_memory` has been increased to `2048` (was `1024`). + +### Improvements + + * #924: Upgrade to `arknoll.selenium` 2.0.0 role, adding support for Chrome/chromedriver with Selenium. + * #922: Increase default memory usage from 1024 MB to 2048 MB. + * #916: Document setup within Windows Subsystem for Linux / Ubuntu Bash environment. + +### Bugfixes + + * #921: Switch to mainline/supported PHP 5.6.x releases instead of deprecated PPA releases. + + +## 3.3.2 (2016-10-06) + +### New/changed variables in default.config.yml + + * You can now add `java` to `installed_extras` if you want Java installed without installing any of the other dependent extras (e.g. Apache Solr, Elasticsearch, or Selenium). + +### Improvements + + * #915: Add 'java' as valid option in installed_extras + + +## 3.3.1 (2016-10-05) + +### New/changed variables in default.config.yml + + * Updated the devel module version number in the `drupal_composer_dependencies` variable: formerly `"drupal/devel:8.*"`, now `"drupal/devel:1.x-dev"`. + +### Bugfixes + + * #911: Document how to bypass/replace MailHog correctly. + * #913: Update project version conventions for Composer-based installs since upstream drupal-project switched to using the drupal.org-hosted packagist. + +## 3.3.0 "1990's Theme" (2016-09-30) + +### Breaking changes + + * Update the three `drupal_mysql_*` variables to `drupal_db_*`. + * Update the default `mysql_databases` and `mysql_users` variables to use the new variable names. + +### New/changed variables in default.config.yml + + * `vagrant_cpus` set to `1` instead of `2` (see #855) + * Added two variables to control minimum required dependency versions: + * `drupalvm_vagrant_version_min: '1.8.5'` + * `drupalvm_ansible_version_min: '2.1'` + * Added `drupalvm_database` variable (defaults to `mysql`) to control database engine (see #146) + * Changed `drupal_mysql_*` variables to `drupal_db_*` for better compatibility: + * `drupal_mysql_user` is now `drupal_db_user` + * `drupal_mysql_password` is now `drupal_db_password` + * `drupal_mysql_name` is now `drupal_db_name` + * Updated `mysql_databases` and `mysql_users` to use the new variable names listed above + * Added `postgresql_databases` and `postgresql_users` (same kind of structure as the `mysql_*` variables) + +### Improvements + + * #146: Add PostgreSQL support. + * #908: Require minimum version of Ansible 2.1.0, Vagrant 1.8.5. + * #855: Default to 1 vCPU core for better VirtualBox performance. + * Update PHP-MySQL Ansible role. + * #421, #367: Add to Behat/Selenium documentation. + +### Bugfixes + + * Ensure Debian apt caches are updated when running tests on Travis. + + +## 3.2.3 (2016-09-27) + +### Improvements + + * Updated all Ansible roles to latest releases (stability fixes). + * Updated Travis CI tests to use more efficient Docker setup. + +### Bugfixes + + * Nothing substantial, just a few typo corrections in comments. + + +## 3.2.2 (2016-09-09) + +### Breaking changes + +N/A + +### New/changed variables in default.config.yml + +N/A + +### Improvements + + * #870: Use more compact and legible object syntax for cron example. + * #886: Allow forcing use of ansible_local even if ansible is present on host. + +### Bugfixes + + * #889: Document Parallels requires paid version. + * #845: Fix missing config.yml file in newrelic role. + * #896: Update Node.js role to fix Nodesource SSL issues on older OSes. Update other roles too. + + +## 3.2.1 (2016-08-16) + +### New/changed variables in default.config.yml + + * Default database defined in `mysql_databases` now uses `utf8mb4` encoding and `utf8mb4_general_ci` collation. + * `selenium_version` now defaults to `2.53.0` + +### Improvements + + * #866: Use latest Selenium release. + * #859: Only set `mysql_enablerepo` when not defined. + * #856: Link Nginx CGI timeout time to PHP timeout time. + * #846: Default to Drupal 8.1.8. + * #839: Don't throw warning if `VAGRANTFILE_API_VERSION` is set twice. + * (No issue): Bump required role versions to latest point releases. + +### Bugfixes + + * #853: Add `/web` to directory in Drupal Console instructions. + + +## 3.2.0 "Tronaction" (2016-07-26) + +### Breaking changes + +Drupal VM now uses Vagrant's `ansible_local` provisioner if you don't have Ansible installed on your host. Make sure you're running Vagrant 1.8.2 or later (1.8.5+ recommended!). + +### New variables in default.config.yml + + * `drush_make_options: "--no-gitinfofile"` added to allow overriding of the default options passed into the `drush make` command. + * `elasticsearch` is now an optional `installed_extra` + * port `9200` is now included in the list of `firewall_allowed_tcp_ports` (to support optional Elasticsearch installation) + * `solr_version: "5.5.2"` – the default Solr version was bumped from 5.5.1 to 5.5.2. + +### Improvements + + * #814 / #815: Include roles in Drupal VM codebase (for faster/more stable install). + * #803: Add optional Elasticsearch installation. + * #450: Switch to Vagrant 1.8.2+'s `ansible_local` provisioner. + * #807: Add ability to override `drush make` CLI options. + * #775: Recommend manual VirtualBox installation as part of Quick Start guide. + * #777: Document how to switch Java versions for newer Apache Solr versions. + +### Bugfixes + + * #800: Add php5-apcu to default Acquia Cloud package list. + * #798: Update selenium role so it doesn't cause build failure. + * #821: Bump upstream Solr role version to fix some Solr install bugs. + * #825: Fix typo in dashboard. + * #799: Quote the Drupal core version in the example makefile to avoid duck typing problems. + + +## 3.1.4 (2016-07-11) + +### Breaking changes + + * `php_sendmail_path` now defaults to `"/opt/mailhog/mhsendmail"` (see https://github.com/geerlingguy/drupal-vm/commit/2d835826de127e427b9a8287bdd2d84a65779761) + +### Improvements + + * #776: Switch from ssmtp to mhsendmail. + * #782: Favicon for Drupal VM dashboard page. + * #791: Update URLs to https (yay Let's Encrypt!). + * #794: Bump PHP role version so FPM user is configurable. + * (No issue): Bump MySQL role version so large innodb prefixes are configurable. + +### Bugfixes + + * #795: Fix Your Site links on dashboard for certain Nginx configs. + * #793: Document composer.json devel module dependency for default config. + + +## 3.1.3 (2016-06-29) + +## Improvements + + * #762: Support including extra_parameters for nginx vhosts. + +## Bugfixes + + * #744: Fix npm_config_prefix directory created under root instead of vagrant. + * #766: Document requirement of `vagrant_box: ubuntu1404` for PHP 5.6. + * #726: Fix permissions on the synced folder for composer project build. + + +## 3.1.2 (2016-06-16) + +### Improvements + + * #730: Improve dashboard for users who have ip set to `0.0.0.0`. + * #733: Update example composer.json to work with Drupal.org packagist. + +### Bugfixes + + * #736: Fix hardcoded NFS reference that broke on Windows with vagrant-cachier plugin. + * #734: Fix a setting that caused Vagrant 1.8.3/1.8.4 to fail to mount shared folders. + * #733 and #741: Adjust composer and timeout values to be more robust with slower filesystems. + * Bumped composer role version. + + +## 3.1.1 (2016-06-12) + +### New variables in default.config.yml + + * `#ssh_home: "{{ drupal_core_path }}"` - The `SSH_HOME` the default Drupal VM user would be redirected to upon SSH login (e.g. `vagrant ssh`). This new variable is entirely optional and commented by default. + +### Improvements + + * #709: Add strict vagrant version requirement for easier debugging. + * #707: Use official packages.drupal.org for Composer drupal package repository. + * #724: Add default www.drupalvm.dev alias to Apache and Nginx vhosts. + * #725: Better ordering and description of Drupal-related variables in `default.config.yml`. + * #665: Add ssh_home var as default pwd for SSH. + +### Bugfixes + + * #715: Set node global install directory to a location writable by the vagrant user. + * #726: Ensure correct permissions when using Composer create-project. + * #650: Bump MySQL role version to fix root user account password. + + +## 3.1.0 "Love Theme" (2016-06-06) + +### New variables in default.config.yml + + * `local_path: .` - the default Vagrant synced folder `local_path` is set to the Drupal VM directory. This way multiple copies of Drupal VM can have independent Drupal codebases by default. + * `build_makefile: false` - Drupal VM now defaults to a composer-based workflow. To keep using a makefile, set this `true` and set all the `build_composer*` variables to `false`. + * `build_composer`, `drupal_composer_*`, `build_composer_project`, `drupal_composer_project_*` - New variables to support `composer.json` or `composer create-project` site builds. + * `extra_parameters` added to the default Apache vhost definition for the Drupal VM dashboard (to support displaying PHP information on the dashboard). + * `hirak/prestissimo` added to `composer_global_packages` (to speed up Composer operations inside the VM). + * `solr_version: "5.5.1"` - New default version of Apache Solr, if `solr` is in `installed_extras`. + * `configure_local_drush_aliases` has been changed to `configure_drush_aliases` (there is a shim to allow the use of the old variable name). + +### Improvements + + * #648: Make config.yml optional (always load default configuration). + * #693: Default to Apache Solr 5.x. + * #687: Default the synced folder to the Drupal VM directory. + * #688: Add docs on how to run custom Ansible playbooks using a local Vagrantfile. + * #694, #701: Add support for, and default to, Composer-based Drupal 8 site builds. + * #698: Add docs about `vagrant-bindfs` to help those with NFS permissions issues. + * #703: Include default `vagrant-cachier` configuration, with an :apt bucket and a :generic bucket for Composer. + * #705: Add Packagist project badge. + * #706: Updated docs for 3.1.0 and default Composer workflow. + +### Bugfixes + + * #654: Remove ansible.cfg because role install is handled by Vagrant. + * #653: Update docs for PHP 5.6 and apcu. + * #663: Change `configure_local_drush_aliases` to `configure_drush_aliases` so it's purpose is clearer. + * #678: Clarify requirement of Ansible on host for host Drush alias setup. + + +## 3.0.0 "The Light Sailer" (2016-05-19) + +Read the [Drupal VM 3 announcement blog post](http://www.jeffgeerling.com/blog/2016/drupal-vm-3-here). + +### Breaking changes + + * Some new defaults (e.g. PHP 7 or upgrading to Ubuntu 16.04) require a full box rebuild (`vagrant destroy` and `vagrant up`) + * Requirements: Vagrant 1.8.1+, VirtualBox 5.0.20+, and (if using Ansible installed locally) Ansible 2.0.1+. + +### New variables in config.yml + + * `vagrant_box` now defaults to `geerlingguy/ubuntu1604` (was `geerlingguy/ubuntu1404`) + * `drush_makefile_path` is now `"{{ config_dir }}/drupal.make.yml"` (to support Drupal VM in a subdirectory) + * `memcached`, `xdebug`, and `xhprof` are now commented from `installed_extras` by default + * `extra_packages` now includes `sqlite` by default + * `php_version` is now `"7.0"` + +### Improvements + + * #522: Add SQLite support to Drupal VM. + * #455: Add support for local.config.yml. + * #608: Automate `ansible-galaxy` role installation (requires Vagrant 1.8+). + * #609: Default to Ubuntu 16.04, PHP 7, and MySQL 5.7. + * #616: Update Travis CI automated tests to test on Ubuntu 16.04 in addition to other OSes. + * #618: Use latest stable Drupal 8 release instead of working-copy (git clone) by default. + * #633: Support custom pre/post provision Ansible task files. + * #378: Decouple Drupal VM from it's existing directory so it can be managed in other directories. + * #378: Add a composer.json ([Drupal VM is on Packagist!](https://packagist.org/packages/geerlingguy/drupal-vm)) + * #526: Added Blackfire.io support (PHP 7 or 5.x). + +### Bugfixes + + * #614: Install cron jobs as the SSH user instead of as root. + * #620: Update JJG-Ansible-Windows to latest version. + * #635: PHP 5.6 documentation didn't include required `php_fpm_pool_conf_path`. + * #619: Fix OpCache CLI error caused by conflicting ini files. + + +## 2.5.1 (2016-05-11) + +## 2.5.0 "Magic Landings" (2016-05-10) + +## 2.4.0 "A New Tron and the MCP" (2016-03-30) + +## 2.3.1 (2016-02-23) + +## 2.3.0 "Miracle and Magician" (2016-02-20) + +## 2.2.1 (2016-01-25) + +## 2.2.0 "Wormhole" (2016-01-15) + +## 2.1.2 (2015-12-04) + +## 2.1.1 (2015-10-07) + +## 2.1.0 (2015-09-22) + +## 2.0.1 (2015-08-21) + +## 2.0.0 (2015-07-29) + +... + +## 1.0.0 (2014-03-24) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..fbfe84796 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM geerlingguy/docker-debian10-ansible:latest +LABEL maintainer="Jeff Geerling" + +# Copy provisioning directory, variable overrides, and scripts into container. +COPY ./ /etc/ansible/drupal-vm +COPY ./provisioning/docker/vars/docker-hub-overrides.yml /etc/ansible/drupal-vm/local.config.yml +COPY ./provisioning/docker/bin/* /usr/local/bin + +# Provision Drupal VM inside Docker. +RUN ansible-playbook /etc/ansible/drupal-vm/provisioning/playbook.yml \ + -e "ansible_python_interpreter=/usr/bin/python3" \ + # Enable FPM. See https://github.com/geerlingguy/drupal-vm/issues/1366. + && systemctl enable php7.4-fpm.service + +EXPOSE 80 443 3306 8025 + +CMD ["/lib/systemd/systemd"] diff --git a/README.md b/README.md index a65c8c1fc..811c142d8 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,46 @@ -

Drupal VM Logo

+![Drupal VM Logo](https://raw.githubusercontent.com/geerlingguy/drupal-vm/master/docs/images/drupal-vm-logo.png) -[![Build Status](https://travis-ci.org/geerlingguy/drupal-vm.svg?branch=master)](https://travis-ci.org/geerlingguy/drupal-vm) [![Documentation Status](https://readthedocs.org/projects/drupal-vm/badge/?version=latest)](http://docs.drupalvm.com) +> **DEPRECATION NOTICE**: Drupal VM is no longer maintained, and no new releases will be made. See issue #2164 for details. Thank you to all users and maintainers over the past decade! -[Drupal VM](http://www.drupalvm.com/) is A VM for local Drupal development, built with Vagrant + Ansible. +[![CI](https://github.com/geerlingguy/drupal-vm/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/drupal-vm/actions?query=workflow%3ACI) [![Documentation Status](https://readthedocs.org/projects/drupal-vm/badge/?version=latest)](http://docs.drupalvm.com) [![Packagist](https://img.shields.io/packagist/v/geerlingguy/drupal-vm.svg)](https://packagist.org/packages/geerlingguy/drupal-vm) [![Docker Automated build](https://img.shields.io/docker/automated/geerlingguy/drupal-vm.svg?maxAge=2592000)](https://hub.docker.com/r/geerlingguy/drupal-vm/) [![](https://images.microbadger.com/badges/image/geerlingguy/drupal-vm.svg)](https://microbadger.com/images/geerlingguy/drupal-vm "Get your own image badge on microbadger.com") [![irc://irc.freenode.net/drupal-vm](https://img.shields.io/badge/irc.freenode.net-%23drupal--vm-brightgreen.svg)](https://riot.im/app/#/room/#drupal-vm:matrix.org) -This project aims to make spinning up a simple local Drupal test/development environment incredibly quick and easy, and to introduce new developers to the wonderful world of Drupal development on local virtual machines (instead of crufty old MAMP/WAMP-based development). +[Drupal VM](https://www.drupalvm.com/) is a VM for Drupal, built with Ansible. -It will install the following on an Ubuntu 14.04 (by default) linux VM: +Drupal VM makes building Drupal development environments quick and easy, and introduces developers to the wonderful world of Drupal development on virtual machines or Docker containers (instead of crufty old MAMP/WAMP-based development). - - Apache 2.4.x - - PHP 5.5.x (configurable) - - MySQL 5.5.x - - Drush (configurable) - - Drupal Console (if using Drupal 8+) - - Drupal 6.x, 7.x, or 8.x.x (configurable) +There are two ways you can use Drupal VM: + + 1. With Vagrant and VirtualBox. + 2. With Docker. + +The rest of this README assumes you're using Vagrant and VirtualBox (this is currently the most flexible and widely-used method of using Drupal VM). If you'd like to use Drupal VM with Docker, please read the [Drupal VM Docker documentation](http://docs.drupalvm.com/en/latest/other/docker/). + +Drupal VM installs the following on an Ubuntu 18.04 (by default) linux VM: + + - Apache (or Nginx) + - PHP (configurable version) + - MySQL (or MariaDB, or PostgreSQL) + - Drupal 7, 8, or 9 - Optional: - - Varnish 4.x - - Apache Solr 4.10.x (configurable) + - Drupal Console + - Drush + - Varnish + - Apache Solr + - Elasticsearch + - Node.js - Selenium, for testing your sites via Behat + - Ruby - Memcached - - XHProf, for profiling your code + - Redis + - SQLite + - Blackfire, XHProf, or Tideways for profiling your code - XDebug, for debugging your code - Adminer, for accessing databases directly - - Pimp my Log, for easy viewing of log files - MailHog, for catching and debugging email It should take 5-10 minutes to build or rebuild the VM from scratch on a decent broadband connection. -Please read through the rest of this README and the [Drupal VM Wiki](https://github.com/geerlingguy/drupal-vm/wiki) for help getting Drupal VM configured and integrated with your development workflow. +Please read through the rest of this README and the [Drupal VM documentation](http://docs.drupalvm.com/) for help getting Drupal VM configured and integrated with your workflow. ## Documentation @@ -37,91 +50,120 @@ Full Drupal VM documentation is available at http://docs.drupalvm.com/ There are a couple places where you can customize the VM for your needs: - - `config.yml`: Contains variables like the VM domain name and IP address, PHP and MySQL configuration, etc. - - `drupal.make.yml`: Contains configuration for the Drupal core version, modules, and patches that will be downloaded on Drupal's initial installation (more about [Drush make files](https://www.drupal.org/node/1432374)). + - `config.yml`: Override any of the default VM configuration from `default.config.yml`; customize almost any aspect of any software installed in the VM (more about [configuring Drupal VM](http://docs.drupalvm.com/en/latest/getting-started/configure-drupalvm/). + - `drupal.composer.json` or `drupal.make.yml`: Contains configuration for the Drupal core version, modules, and patches that will be downloaded on Drupal's initial installation (you can build using Composer, Drush make, or your own codebase). + +If you want to use Drupal 8 on the initial install, do the following: -If you want to switch from Drupal 8 (default) to Drupal 7 or 6 on the initial install, do the following: + 1. Set `drupal_major_version: 8` inside `config.yml`. + 2. Set `drupal_composer_project_package: "drupal/recommended-project:^8@dev"` inside `config.yml`. + + +If you want to use Drupal 7 on the initial install, do the following: - 1. Update the Drupal `version` and `core` inside the `drupal.make.yml` file. - 2. Update `drupal_major_version` inside `config.yml`. + 1. Switch to using a [Drush Make file](http://docs.drupalvm.com/en/latest/deployment/drush-make/). + 1. Update the Drupal `version` and `core` inside your `drupal.make.yml` file. + 2. Set `drupal_major_version: 7` inside `config.yml`. ## Quick Start Guide -This Quick Start Guide will help you quickly build a Drupal 8 site on the Drupal VM using the included example Drush make file. You can also use the Drupal VM with a [Local Drupal codebase](https://github.com/geerlingguy/drupal-vm/wiki/Local-Drupal-codebase) or even a [Drupal multisite installation](https://github.com/geerlingguy/drupal-vm/wiki/Drupal-multisite). +This Quick Start Guide will help you quickly build a Drupal 9 site on the Drupal VM creating a new Composer project. You can also use Drupal VM with [Composer](http://docs.drupalvm.com/en/latest/deployment/composer/), a [Drush Make file](http://docs.drupalvm.com/en/latest/deployment/drush-make/), with a [Local Drupal codebase](http://docs.drupalvm.com/en/latest/deployment/local-codebase/), or even a [Drupal multisite installation](http://docs.drupalvm.com/en/latest/deployment/multisite/). + +If you want to install a Drupal site locally with minimal fuss, just: -### 1 - Install dependencies (VirtualBox, Vagrant, Ansible) + 1. Install [Vagrant](https://www.vagrantup.com/downloads.html) and [VirtualBox](https://www.virtualbox.org/wiki/Downloads). + 2. Download or clone this project to your workstation. + 3. `cd` into this project directory and run `vagrant up`. - 1. Download and install [VirtualBox](https://www.virtualbox.org/wiki/Downloads) (Drupal VM also works with Parallels or VMware, if you have the [Vagrant VMware integration plugin](http://www.vagrantup.com/vmware)). - 2. Download and install [Vagrant](http://www.vagrantup.com/downloads.html). - 3. [Mac/Linux only] Install [Ansible](http://docs.ansible.com/intro_installation.html). +But Drupal VM allows you to build your site exactly how you like, using whatever tools you need, with almost infinite flexibility and customization! -Note for Windows users: *Ansible will be installed inside the VM, and everything will be configured internally (unlike on Mac/Linux hosts). See [JJG-Ansible-Windows](https://github.com/geerlingguy/JJG-Ansible-Windows) for more information.* +### 1 - Install Vagrant and VirtualBox -Note for Linux users: *If NFS is not already installed on your host, you will need to install it to use the default NFS synced folder configuration. See guides for [Debian/Ubuntu](https://www.digitalocean.com/community/tutorials/how-to-set-up-an-nfs-mount-on-ubuntu-14-04), [Arch](https://wiki.archlinux.org/index.php/NFS#Installation), and [RHEL/CentOS](https://www.digitalocean.com/community/tutorials/how-to-set-up-an-nfs-mount-on-centos-6).* +Download and install [Vagrant](https://www.vagrantup.com/downloads.html) and [VirtualBox](https://www.virtualbox.org/wiki/Downloads). -Note on versions: *Please make sure you're running the latest stable version of Vagrant, VirtualBox, and Ansible, as the current version of Drupal VM is tested with the latest releases. As of June 2015: Vagrant 1.7.2, VirtualBox 4.3.26, and Ansible 1.9.2.* +You can also use an alternative provider like Parallels or VMware. (Parallels Desktop 11+ requires the "Pro" or "Business" edition and the [Parallels Provider](http://parallels.github.io/vagrant-parallels/), and VMware requires the paid [Vagrant VMware integration plugin](http://www.vagrantup.com/vmware)). + +Notes: + + - **For faster provisioning** (macOS/Linux only): *[Install Ansible](http://docs.ansible.com/intro_installation.html) on your host machine, so Drupal VM can run the provisioning steps locally instead of inside the VM.* + - **For stability**: Because every version of VirtualBox introduces changes to networking, for the best stability, you should install Vagrant's `vbguest` plugin: `vagrant plugin install vagrant-vbguest`. + - **NFS on Linux**: *If NFS is not already installed on your host, you will need to install it to use the default NFS synced folder configuration. See [nfs instructions for Linux](http://docs.drupalvm.com/en/latest/getting-started/installation-linux/#mounting-nfs-shared-folders-hangs)* + - **Versions**: *Make sure you're running the latest releases of Vagrant, VirtualBox, and Ansible—as of 2020, Drupal VM recommends: Vagrant 2.2.x, VirtualBox 6.1.x, and Ansible 2.9.x* ### 2 - Build the Virtual Machine 1. Download this project and put it wherever you want. - 2. Make copies of both of the `example.*` files, and modify to your liking: - - Copy `example.drupal.make.yml` to `drupal.make.yml`. - - Copy `example.config.yml` to `config.yml`. + 2. (Optional) Copy `default.config.yml` to `config.yml` and modify it to your liking. 3. Create a local directory where Drupal will be installed and configure the path to that directory in `config.yml` (`local_path`, inside `vagrant_synced_folders`). - 4. Open Terminal, cd to this directory (containing the `Vagrantfile` and this README file). - 5. [Mac/Linux only] Install Ansible Galaxy roles required for this VM: `$ sudo ansible-galaxy install -r provisioning/requirements.txt --force` - 6. Type in `vagrant up`, and let Vagrant do its magic. + 4. Open Terminal, `cd` to this directory (containing the `Vagrantfile` and this README file). + 5. Type in `vagrant up`, and let Vagrant do its magic. + +Once the process is complete, you will have a Drupal codebase available inside the `drupal/` directory of the project. Note: *If there are any errors during the course of running `vagrant up`, and it drops you back to your command prompt, just run `vagrant provision` to continue building the VM from where you left off. If there are still errors after doing this a few times, post an issue to this project's issue queue on GitHub with the error.* -### 3 - Configure your host machine to access the VM. +### 3 - Access the VM. - 1. [Edit your hosts file](http://www.rackspace.com/knowledge_center/article/how-do-i-modify-my-hosts-file), adding the line `192.168.88.88 drupalvm.dev` so you can connect to the VM. Alternatively, you can install a Vagrant plugin to automatically add and remove the entry from your hosts file; run `vagrant plugin install vagrant-hostsupdater`. The plugin will also add in all other hosts defined via `apache_vhosts`. - 2. Open your browser and access [http://drupalvm.dev/](http://drupalvm.dev/). The default login for the admin account is `admin` for both the username and password. +Open your browser and access [http://drupalvm.test/](http://drupalvm.test/). The default login for the admin account is `admin` for both the username and password. + +Note: *By default Drupal VM is configured to use `192.168.88.88` as its IP, if you're running multiple VM's the `auto_network` plugin (`vagrant plugin install vagrant-auto_network`) can help with IP address management if you set `vagrant_ip` to `0.0.0.0` inside `config.yml`.* ## Extra software/utilities -By default, this VM includes the extras listed in the `config.yml` option `installed_extras`: +By default, this VM includes the extras listed in the `config.yml` option `installed_extras`, for example: installed_extras: - adminer + # - blackfire + # - drupalconsole + - drush + # - elasticsearch + # - java - mailhog - - memcached - - pimpmylog - # - solr - # - selenium - - varnish - - xdebug - - xhprof + [...] If you don't want or need one or more of these extras, just delete them or comment them from the list. This is helpful if you want to reduce PHP memory usage or otherwise conserve system resources. ## Using Drupal VM -Drupal VM is built to integrate with every developer's workflow. Many guides for using Drupal VM for common development tasks are available on the [Drupal VM Wiki](https://github.com/geerlingguy/drupal-vm/wiki): - - - [Syncing Folders](http://docs.drupalvm.com/en/latest/extras/syncing-folders/) - - [Connect to the MySQL Database](http://docs.drupalvm.com/en/latest/extras/mysql/) - - [Use Apache Solr for Search](http://docs.drupalvm.com/en/latest/extras/solr/) - - [Use Drush with Drupal VM](http://docs.drupalvm.com/en/latest/extras/drush/) - - [Use Drupal Console with Drupal VM](http://docs.drupalvm.com/en/latest/extras/drupal-console/) - - [Use Varnish with Drupal VM](http://docs.drupalvm.com/en/latest/extras/varnish/) - - [Use MariaDB instead of MySQL](http://docs.drupalvm.com/en/latest/extras/mariadb/) - - [View Logs with Pimp my Log](http://docs.drupalvm.com/en/latest/extras/pimpmylog/) - - [Profile Code with XHProf](http://docs.drupalvm.com/en/latest/extras/xhprof/) - - [Debug Code with XDebug](http://docs.drupalvm.com/en/latest/extras/xdebug/) - - [Catch Emails with MailHog](http://docs.drupalvm.com/en/latest/extras/mailhog/) - - [Test with Behat and Selenium](http://docs.drupalvm.com/en/latest/extras/behat/) - - [PHP 7 on Drupal VM](http://docs.drupalvm.com/en/latest/other/php-7/) - - [Drupal 6 Notes](http://docs.drupalvm.com/en/latest/other/drupal-6/) +Drupal VM is built to integrate with every developer's workflow. Many guides for using Drupal VM for common development tasks are available on the [Drupal VM documentation site](http://docs.drupalvm.com). + +## Updating Drupal VM + +Drupal VM follows semantic versioning, which means your configuration should continue working (potentially with very minor modifications) throughout a major release cycle. Here is the process to follow when updating Drupal VM between minor releases: + + 1. Read through the [release notes](https://github.com/geerlingguy/drupal-vm/releases) and add/modify `config.yml` variables mentioned therein. + 2. Do a diff of your `config.yml` with the updated `default.config.yml` (e.g. `curl https://raw.githubusercontent.com/geerlingguy/drupal-vm/master/default.config.yml | git diff --no-index config.yml -`). + 3. Run `vagrant provision` to provision the VM, incorporating all the latest changes. + +For major version upgrades (e.g. 4.x.x to 5.x.x), it may be simpler to destroy the VM (`vagrant destroy`) then build a fresh new VM (`vagrant up`) using the new version of Drupal VM. + +## System Requirements + +Drupal VM runs on almost any modern computer that can run VirtualBox and Vagrant, however for the best out-of-the-box experience, it's recommended you have a computer with at least: + + - Intel Core processor with VT-x enabled + - At least 4 GB RAM (higher is better) + - An SSD (for greater speed with synced folders) ## Other Notes - To shut down the virtual machine, enter `vagrant halt` in the Terminal in the same folder that has the `Vagrantfile`. To destroy it completely (if you want to save a little disk space, or want to rebuild it from scratch with `vagrant up` again), type in `vagrant destroy`. + - To log into the virtual machine, enter `vagrant ssh`. You can also get the machine's SSH connection details with `vagrant ssh-config`. - When you rebuild the VM (e.g. `vagrant destroy` and then another `vagrant up`), make sure you clear out the contents of the `drupal` folder on your host machine, or Drupal will return some errors when the VM is rebuilt (it won't reinstall Drupal cleanly). - You can change the installed version of Drupal or drush, or any other configuration options, by editing the variables within `config.yml`. - Find out more about local development with Vagrant + VirtualBox + Ansible in this presentation: [Local Development Environments - Vagrant, VirtualBox and Ansible](http://www.slideshare.net/geerlingguy/local-development-on-virtual-machines-vagrant-virtualbox-and-ansible). - - Learn about how Ansible can accelerate your ability to innovate and manage your infrastructure by reading [Ansible for DevOps](https://leanpub.com/ansible-for-devops). + - Learn about how Ansible can accelerate your ability to innovate and manage your infrastructure by reading [Ansible for DevOps](http://www.ansiblefordevops.com/). + +## Tests + +To run basic integration tests using Docker and Molecule: + + 1. [Install Docker](https://docs.docker.com/engine/installation/). + 2. Install Molecule: `pip3 install ansible molecule[docker]` + 2. In this project directory, run: `composer run-tests` + +The project's automated tests are run via GitHub Actions, and the more comprehensive test suite covers multiple Linux distributions and many different Drupal VM use cases and deployment techniques. ## License @@ -129,4 +171,4 @@ This project is licensed under the MIT open source license. ## About the Author -[Jeff Geerling](http://jeffgeerling.com/), owner of [Midwestern Mac, LLC](http://www.midwesternmac.com/), created this project in 2014 so he could accelerate his Drupal core and contrib development workflow. This project, and others like it, are also featured as examples in Jeff's book, [Ansible for DevOps](https://leanpub.com/ansible-for-devops). +[Jeff Geerling](https://www.jeffgeerling.com/) created Drupal VM in 2014 for a more efficient Drupal site and core/contrib development workflow. This project is featured as an example in [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/Vagrantfile b/Vagrantfile index d48105325..68d413548 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,80 +1,147 @@ +# frozen_string_literal: true + # -*- mode: ruby -*- # vi: set ft=ruby : -VAGRANTFILE_API_VERSION = "2" -# Use config.yml for basic VM configuration. -require 'yaml' -dir = File.dirname(File.expand_path(__FILE__)) -if !File.exist?("#{dir}/config.yml") - raise 'Configuration file not found! Please copy example.config.yml to config.yml and try again.' +require_relative 'lib/drupalvm/vagrant' + +# Absolute paths on the host machine. +host_drupalvm_dir = File.dirname(File.expand_path(__FILE__)) +host_project_dir = ENV['DRUPALVM_PROJECT_ROOT'] || host_drupalvm_dir +host_config_dir = ENV['DRUPALVM_CONFIG_DIR'] ? "#{host_project_dir}/#{ENV['DRUPALVM_CONFIG_DIR']}" : host_project_dir + +# Absolute paths on the guest machine. +guest_project_dir = '/vagrant' +guest_drupalvm_dir = ENV['DRUPALVM_DIR'] ? "/vagrant/#{ENV['DRUPALVM_DIR']}" : guest_project_dir +guest_config_dir = ENV['DRUPALVM_CONFIG_DIR'] ? "/vagrant/#{ENV['DRUPALVM_CONFIG_DIR']}" : guest_project_dir + +drupalvm_env = ENV['DRUPALVM_ENV'] || 'vagrant' + +default_config_file = "#{host_drupalvm_dir}/default.config.yml" +unless File.exist?(default_config_file) + raise_message "Configuration file not found! Expected in #{default_config_file}" end -vconfig = YAML::load_file("#{dir}/config.yml") -# Use rbconfig to determine if we're on a windows host or not. -require 'rbconfig' -is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/) +vconfig = load_config( + [ + default_config_file, + "#{host_config_dir}/config.yml", + "#{host_config_dir}/#{drupalvm_env}.config.yml", + "#{host_config_dir}/local.config.yml" + ] +) + +provisioner = vconfig['force_ansible_local'] ? :ansible_local : vagrant_provisioner +if provisioner == :ansible + playbook = "#{host_drupalvm_dir}/provisioning/playbook.yml" + config_dir = host_config_dir -Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + # Verify Ansible version requirement. + require_ansible_version ">= #{vconfig['drupalvm_ansible_version_min']}" +else + playbook = "#{guest_drupalvm_dir}/provisioning/playbook.yml" + config_dir = guest_config_dir +end + +# Verify Vagrant version requirement. +Vagrant.require_version ">= #{vconfig['drupalvm_vagrant_version_min']}" + +ensure_plugins(vconfig['vagrant_plugins']) + +Vagrant.configure('2') do |config| + # Set the name of the VM. See: http://stackoverflow.com/a/17864388/100134 + config.vm.define vconfig['vagrant_machine_name'] + + # Networking configuration. config.vm.hostname = vconfig['vagrant_hostname'] - config.vm.network :private_network, ip: vconfig['vagrant_ip'] + config.vm.network :private_network, + ip: vconfig['vagrant_ip'], + auto_network: vconfig['vagrant_ip'] == '0.0.0.0' && Vagrant.has_plugin?('vagrant-auto_network') + + unless vconfig['vagrant_public_ip'].empty? + config.vm.network :public_network, + ip: vconfig['vagrant_public_ip'] != '0.0.0.0' ? vconfig['vagrant_public_ip'] : nil + end + + # SSH options. config.ssh.insert_key = false config.ssh.forward_agent = true + # Vagrant box. config.vm.box = vconfig['vagrant_box'] - # If hostsupdater plugin is installed, add all servernames as aliases. - if Vagrant.has_plugin?("vagrant-hostsupdater") - config.hostsupdater.aliases = [] - for host in vconfig['apache_vhosts'] - # Add all the hosts that aren't defined as Ansible vars. - unless host['servername'].include? "{{" - config.hostsupdater.aliases.push(host['servername']) - end - end + # Display an introduction message after `vagrant up` and `vagrant provision`. + config.vm.post_up_message = vconfig.fetch('vagrant_post_up_message', get_default_post_up_message(vconfig)) + + # If a hostsfile manager plugin is installed, add all server names as aliases. + aliases = get_vhost_aliases(vconfig) - [config.vm.hostname] + if Vagrant.has_plugin?('vagrant-hostsupdater') + config.hostsupdater.aliases = aliases + elsif Vagrant.has_plugin?('vagrant-hostmanager') + config.hostmanager.enabled = true + config.hostmanager.manage_host = true + config.hostmanager.aliases = aliases + end + + # Sync the project root directory to /vagrant + unless vconfig['vagrant_synced_folders'].any? { |synced_folder| synced_folder['destination'] == '/vagrant' } + vconfig['vagrant_synced_folders'].push( + 'local_path' => host_project_dir, + 'destination' => '/vagrant' + ) end - for synced_folder in vconfig['vagrant_synced_folders']; - config.vm.synced_folder synced_folder['local_path'], synced_folder['destination'], - type: synced_folder['type'], - rsync__auto: "true", + # Synced folders. + vconfig['vagrant_synced_folders'].each do |synced_folder| + options = { + type: synced_folder.fetch('type', vconfig['vagrant_synced_folder_default_type']), rsync__exclude: synced_folder['excluded_paths'], - rsync__args: ["--verbose", "--archive", "--delete", "-z", "--chmod=ugo=rwX"], + rsync__args: ['--verbose', '--archive', '--delete', '-z', '--copy-links', '--chmod=ugo=rwX'], id: synced_folder['id'], - create: synced_folder.include?('create') ? synced_folder['create'] : false, - mount_options: synced_folder.include?('mount_options') ? synced_folder['mount_options'] : [] + create: synced_folder.fetch('create', false), + mount_options: synced_folder.fetch('mount_options', []), + nfs_udp: synced_folder.fetch('nfs_udp', false) + } + synced_folder.fetch('options_override', {}).each do |key, value| + options[key.to_sym] = value + end + config.vm.synced_folder synced_folder.fetch('local_path'), synced_folder.fetch('destination'), options end - if is_windows - # Provisioning configuration for shell script (for Windows). - config.vm.provision "shell" do |sh| - sh.path = "#{dir}/provisioning/JJG-Ansible-Windows/windows.sh" - sh.args = "/provisioning/playbook.yml" - end - else - # Provisioning configuration for Ansible (for Mac/Linux hosts). - config.vm.provision "ansible" do |ansible| - ansible.playbook = "#{dir}/provisioning/playbook.yml" - ansible.sudo = true - end + config.vm.provision 'drupalvm', type: provisioner do |ansible| + ansible.compatibility_mode = '2.0' + ansible.playbook = playbook + ansible.extra_vars = { + config_dir: config_dir, + drupalvm_env: drupalvm_env, + ansible_python_interpreter: vconfig['ansible_python_interpreter'] + } + ansible.raw_arguments = Shellwords.shellsplit(ENV['DRUPALVM_ANSIBLE_ARGS']) if ENV['DRUPALVM_ANSIBLE_ARGS'] + ansible.tags = ENV['DRUPALVM_ANSIBLE_TAGS'] + # Use pip to get the latest Ansible version when using ansible_local. + provisioner == :ansible_local && ansible.install_mode = 'pip3' end # VMware Fusion. config.vm.provider :vmware_fusion do |v, override| # HGFS kernel module currently doesn't load correctly for native shares. - override.vm.synced_folder ".", "/vagrant", type: 'nfs' + override.vm.synced_folder host_project_dir, '/vagrant', type: 'nfs' - v.gui = false - v.vmx["memsize"] = vconfig['vagrant_memory'] - v.vmx["numvcpus"] = vconfig['vagrant_cpus'] + v.gui = vconfig['vagrant_gui'] + v.vmx['memsize'] = vconfig['vagrant_memory'] + v.vmx['numvcpus'] = vconfig['vagrant_cpus'] end # VirtualBox. config.vm.provider :virtualbox do |v| + v.linked_clone = true v.name = vconfig['vagrant_hostname'] v.memory = vconfig['vagrant_memory'] v.cpus = vconfig['vagrant_cpus'] - v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] - v.customize ["modifyvm", :id, "--ioapic", "on"] + v.customize ['modifyvm', :id, '--natdnshostresolver1', 'on'] + v.customize ['modifyvm', :id, '--ioapic', 'on'] + v.customize ['modifyvm', :id, '--audio', 'none'] + v.gui = vconfig['vagrant_gui'] end # Parallels. @@ -83,9 +150,24 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| p.name = vconfig['vagrant_hostname'] p.memory = vconfig['vagrant_memory'] p.cpus = vconfig['vagrant_cpus'] + p.update_guest_tools = true end - # Set the name of the VM. See: http://stackoverflow.com/a/17864388/100134 - config.vm.define vconfig['vagrant_machine_name'] do |d| + # Cache packages and dependencies if vagrant-cachier plugin is present. + if Vagrant.has_plugin?('vagrant-cachier') + config.cache.scope = :box + config.cache.auto_detect = false + config.cache.enable :apt + # Cache the composer directory. + config.cache.enable :generic, cache_dir: '/home/vagrant/.composer/cache' + config.cache.synced_folder_opts = { + type: vconfig['vagrant_synced_folder_default_type'], + nfs_udp: false + } + end + + # Allow an untracked Vagrantfile to modify the configurations + [host_config_dir, host_project_dir].uniq.each do |dir| + eval File.read "#{dir}/Vagrantfile.local" if File.exist?("#{dir}/Vagrantfile.local") end end diff --git a/composer.json b/composer.json new file mode 100644 index 000000000..f0a4ca336 --- /dev/null +++ b/composer.json @@ -0,0 +1,33 @@ +{ + "name": "geerlingguy/drupal-vm", + "type": "vm", + "description": "A VM for local Drupal development, built with Vagrant + Ansible", + "keywords": ["vagrant", "vm", "virtual machine", "drupal"], + "homepage": "https://www.drupalvm.com", + "license": "MIT", + "authors": [ + { + "name": "Jeff Geerling", + "homepage": "https://www.jeffgeerling.com" + }, + { + "name": "Oskar Schöldström", + "homepage": "http://oxy.fi" + } + ], + "support": { + "issues": "https://github.com/geerlingguy/drupal-vm/issues", + "source": "https://github.com/geerlingguy/drupal-vm", + "docs": "http://docs.drupalvm.com" + }, + "require": {}, + "config": { + "process-timeout": 1800 + }, + "scripts": { + "run-tests": "molecule test", + "docker-bake": "./provisioning/docker/bake.sh", + "docker-save-image": "./provisioning/docker/save-image.sh", + "docker-load-image": "./provisioning/docker/load-image.sh" + } +} diff --git a/default.config.yml b/default.config.yml new file mode 100644 index 000000000..dae1105cb --- /dev/null +++ b/default.config.yml @@ -0,0 +1,343 @@ +--- +# Available `vagrant_box` values include: +# - geerlingguy/drupal-vm (pre-provisioned, based on Ubuntu 18.04) +# - geerlingguy/centos8 +# - geerlingguy/debian10 +# - geerlingguy/ubuntu1804 +vagrant_box: geerlingguy/drupal-vm + +vagrant_user: vagrant +vagrant_synced_folder_default_type: nfs +vagrant_gui: false + +# If you need to run multiple instances of Drupal VM, set a unique hostname, +# machine name, and IP address for each instance. +vagrant_hostname: drupalvm.test +vagrant_machine_name: drupalvm +vagrant_ip: 192.168.88.88 + +# Allow Drupal VM to be accessed via a public network interface on your host. +# Vagrant boxes are insecure by default, so be careful. You've been warned! +# See: https://docs.vagrantup.com/v2/networking/public_network.html +vagrant_public_ip: "" + +# A list of synced folders, with the keys 'local_path', 'destination', and +# a 'type' of [nfs|rsync|smb] (leave empty for slow native shares). See +# http://docs.drupalvm.com/en/latest/getting-started/syncing-folders/ for more. +vagrant_synced_folders: + # The first synced folder will be used for the default Drupal installation, if + # any of the build_* settings are 'true'. By default the folder is set to + # the drupal-vm folder. + - local_path: . + destination: /var/www/drupalvm + type: nfs + create: true + +# Memory and CPU to use for this VM. +vagrant_memory: 2048 +vagrant_cpus: 1 + +# Ensure vagrant plugins are installed. +vagrant_plugins: + - name: vagrant-vbguest + - name: vagrant-hostsupdater + +# Automatically fix timeout issues with NFS on macOS. See +# https://github.com/geerlingguy/drupal-vm/issues/2154 +vagrant_nfs_fix_enabled: false + +ansible_python_interpreter: python3 + +# Minimum required versions. +drupalvm_vagrant_version_min: '2.2.0' +drupalvm_ansible_version_min: '2.8' + +# Force use of ansible_local provisioner, even if Ansible is installed on host. +force_ansible_local: false + +# The web server software to use. Can be either 'apache' or 'nginx'. +drupalvm_webserver: apache + +# The database system to use. Can be either 'mysql' or 'pgsql'. +drupal_db_backend: mysql + +# Set this to 'false' if you are using a different site deployment strategy and +# would like to configure 'vagrant_synced_folders' and 'apache_vhosts' manually. +drupal_build_makefile: false +drush_makefile_path: "{{ config_dir }}/drupal.make.yml" +drush_make_options: "--no-gitinfofile" + +# Set 'drupal_build_makefile' to 'false' and this to 'true' if you are using a +# composer based site deployment strategy. +drupal_build_composer: false +drupal_composer_path: "{{ config_dir }}/drupal.composer.json" +drupal_composer_install_dir: "/var/www/drupalvm/drupal" +drupal_composer_dependencies: + - "drush/drush:^10" + - "drupal/devel:^4.0" + +# Set this to 'true' and 'drupal_build_makefile', 'drupal_build_composer' to 'false' +# if you are using Composer's create-project as a site deployment strategy. +drupal_build_composer_project: true +drupal_composer_project_package: "drupal/recommended-project:^9@dev" +drupal_composer_project_options: "--prefer-dist --stability dev --no-interaction" + +# Set this to 'false' if you don't need to install drupal (using the drupal_* +# settings below), but instead copy down a database (e.g. using drush sql-sync). +drupal_install_site: true + +# Required Drupal settings. +drupal_core_path: "{{ drupal_composer_install_dir }}/web" +drupal_core_owner: "{{ drupalvm_user }}" +drupal_db_user: drupal +drupal_db_password: drupal +drupal_db_name: drupal +drupal_db_host: localhost + +# Settings for installing a Drupal site if 'drupal_install_site:' is 'true'. +drupal_major_version: 9 +drupal_domain: "{{ vagrant_hostname }}" +drupal_site_name: "Drupal" +drupal_install_profile: standard +drupal_enable_modules: ['devel'] +drupal_account_name: admin +drupal_account_pass: admin + +# Additional arguments or options to pass to `drush site-install`. +drupal_site_install_extra_args: [] + +# Cron jobs are added to the vagrant user's crontab. Keys include name +# (required), minute, hour, day, weekday, month, job (required), and state. +drupalvm_cron_jobs: [] + +# Drupal VM automatically creates a drush alias file in your ~/.drush folder if +# this variable is 'true'. +configure_drush_aliases: true +drush_aliases_host_template: "templates/drupalvm.aliases.drushrc.php.j2" +drush_aliases_host_template_yml: "templates/drupalvm.aliases.yml.j2" +drush_aliases_guest_template: "templates/drupalvm-local.aliases.drushrc.php.j2" +drush_aliases_guest_template_yml: "templates/drupalvm-local.aliases.yml.j2" + +# Helper variable to configure the PHP-FPM connection for each Apache +# VirtualHost in the `apache_vhosts` list. +apache_vhost_php_fpm_parameters: | + + SetHandler "proxy:fcgi://{{ php_fpm_listen }}" + + +# Apache VirtualHosts. Add one for each site you are running inside the VM. For +# multisite deployments, you can point multiple servernames at one documentroot. +# View the geerlingguy.apache Ansible Role README for more options. +apache_vhosts: + - servername: "{{ drupal_domain }}" + serveralias: "www.{{ drupal_domain }}" + documentroot: "{{ drupal_core_path }}" + extra_parameters: "{{ apache_vhost_php_fpm_parameters }}" + + - servername: "adminer.{{ vagrant_hostname }}" + documentroot: "{{ adminer_install_dir }}" + extra_parameters: "{{ apache_vhost_php_fpm_parameters }}" + + - servername: "xhprof.{{ vagrant_hostname }}" + documentroot: "{{ php_xhprof_html_dir }}" + extra_parameters: "{{ apache_vhost_php_fpm_parameters }}" + + - servername: "{{ vagrant_ip }}" + serveralias: "dashboard.{{ vagrant_hostname }}" + documentroot: "{{ dashboard_install_dir }}" + extra_parameters: "{{ apache_vhost_php_fpm_parameters }}" + +apache_packages_state: latest +apache_remove_default_vhost: true +apache_mods_enabled: + - expires.load + - headers.load + - ssl.load + - rewrite.load + - proxy.load + - proxy_fcgi.load + +# Nginx hosts. Each site will get a server entry using the configuration defined +# here. Set the 'is_php' property for document roots that contain PHP apps like +# Drupal. +nginx_hosts: + - server_name: "{{ drupal_domain }} www.{{ drupal_domain }}" + root: "{{ drupal_core_path }}" + is_php: true + + - server_name: "adminer.{{ vagrant_hostname }}" + root: "{{ adminer_install_dir }}" + is_php: true + + - server_name: "xhprof.{{ vagrant_hostname }}" + root: "{{ php_xhprof_html_dir }}" + is_php: true + + - server_name: "{{ vagrant_ip }} dashboard.{{ vagrant_hostname }}" + root: "{{ dashboard_install_dir }}" + is_php: true + +nginx_remove_default_vhost: true +nginx_ppa_use: true +nginx_vhost_template: "templates/nginx-vhost.conf.j2" + +# MySQL databases and users. +mysql_databases: + - name: "{{ drupal_db_name }}" + encoding: utf8mb4 + collation: utf8mb4_general_ci + +mysql_users: + - name: "{{ drupal_db_user }}" + host: "%" + password: "{{ drupal_db_password }}" + priv: "{{ drupal_db_name }}.*:ALL" + +# PostgreSQL databases and users. +postgresql_users: + - name: "{{ drupal_db_user }}" + password: "{{ drupal_db_password }}" + +postgresql_databases: + - name: "{{ drupal_db_name }}" + owner: "{{ drupal_db_user }}" + +# Comment out any extra utilities you don't want to install. If you don't want +# to install *any* extras, set this value to an empty set, e.g. `[]`. +installed_extras: + - adminer + # - blackfire + # - drupalconsole + - drush + # - elasticsearch + # - java + - mailhog + # - memcached + # - newrelic + # - nodejs + # - redis + # - ruby + # - selenium + # - solr + # - tideways + # - upload-progress + - varnish + # - xdebug + # - xhprof # use `tideways` if you're installing PHP 7+ + +# Add any extra apt or yum packages you would like installed. +extra_packages: + - sqlite + +# You can configure almost anything else on the server in the rest of this file. +extra_security_enabled: false + +firewall_enabled: true +firewall_allowed_tcp_ports: + - "22" + - "25" + - "80" + - "81" + - "443" + - "4444" + - "8025" + - "8080" + - "8443" + - "8983" + - "9200" +firewall_log_dropped_packets: false +firewall_disable_firewalld: true +firewall_disable_ufw: true + +# PHP Configuration. Currently-supported versions: 7.2, 7.3, 7.4. +# See version-specific notes: http://docs.drupalvm.com/en/latest/configurations/php/ +php_version: "7.4" +php_install_recommends: no +php_memory_limit: "192M" +php_display_errors: "On" +php_display_startup_errors: "On" +php_realpath_cache_size: "1024K" +php_sendmail_path: "/opt/mailhog/mhsendmail" +php_opcache_enable: "1" +php_opcache_memory_consumption: "192" +php_opcache_max_accelerated_files: 4096 +php_max_input_vars: "4000" + +# Drupal VM defaults to using PHP-FPM with either Apache or Nginx. If you wish +# to instead use Apache + mod_php with an Ubuntu base box, make sure you add +# libapache2-mod-php7.0 to `extra_packages` elsewhere in this config file. +php_enable_php_fpm: true +php_fpm_listen: "127.0.0.1:9000" + +composer_path: /usr/bin/composer +composer_home_path: "/home/{{ drupalvm_user }}/.composer" +composer_home_owner: "{{ drupalvm_user }}" +composer_home_group: "{{ drupalvm_user }}" +composer_global_packages: [] + +# Run specified scripts before or after VM is provisioned. Use {{ playbook_dir }} +# to reference the provisioning/ folder in Drupal VM or {{ config_dir }} to +# reference the directory where your `config.yml` is. +pre_provision_scripts: [] +post_provision_scripts: [] +# - "{{ playbook_dir }}/../examples/scripts/configure-solr.sh" + +# MySQL Configuration. +mysql_root_password: root +mysql_slow_query_log_enabled: true +mysql_slow_query_time: 2 +mysql_wait_timeout: 300 +adminer_install_filename: index.php + +# Node.js configuration (if enabled above). +# Valid examples: "6.x", "8.x", "10.x", etc. +nodejs_version: "10.x" +nodejs_npm_global_packages: + - name: npm +nodejs_install_npm_user: "{{ drupalvm_user }}" +npm_config_prefix: "/home/{{ drupalvm_user }}/.npm-global" + +# Ruby Configuration (if enabled above). +ruby_install_gems_user: "{{ drupalvm_user }}" +ruby_install_gems: [] + +# Varnish Configuration (if enabled above). +varnish_listen_port: "81" +varnish_default_vcl_template_path: templates/drupalvm.vcl.j2 +varnish_default_backend_host: "127.0.0.1" +varnish_default_backend_port: "80" + +# XDebug configuration. XDebug is disabled by default for better performance. +php_xdebug_version: 2.9.5 +php_xdebug_default_enable: 0 +php_xdebug_coverage_enable: 0 +php_xdebug_cli_disable: yes +php_xdebug_remote_enable: 1 +php_xdebug_remote_connect_back: 1 +php_xdebug_idekey: PHPSTORM +php_xdebug_max_nesting_level: 256 +php_xdebug_remote_host: "{{ ansible_default_ipv4.gateway }}" + +# Java configuration. +java_packages: + - "{{ 'openjdk-8-jdk' if ansible_os_family == 'Debian' else 'java-1.8.0-openjdk' }}" + +# Solr configuration. +solr_version: "7.7.2" +solr_xms: "64M" +solr_xmx: "128M" + +# Selenium configuration. +selenium_version: 2.53.0 + +# Docker configuration. +docker_container_name: drupal-vm +docker_image_name: drupal-vm +docker_image_path: ~/Downloads + +# Other configuration. +dashboard_install_dir: /var/www/dashboard +known_hosts_path: ~/.ssh/known_hosts +hostname_configure: true +hostname_fqdn: "{{ vagrant_hostname }}" +ssh_home: "{{ drupal_core_path }}" diff --git a/docs/configurations/base-os.md b/docs/configurations/base-os.md new file mode 100644 index 000000000..f376f9d28 --- /dev/null +++ b/docs/configurations/base-os.md @@ -0,0 +1,26 @@ +Drupal VM's configuration is designed to work with RedHat and Debian-compatible operating systems. Therefore, if you switch the `vagrant_box` in `config.yml` to any compatible OS, Drupal VM and all it's configuration should _Just Work™_... but that's not always the case. + +Currently-supported OSes are: + + - Ubuntu 18.04 'Bionic' (default) + - RedHat Enterprise Linux / CentOS 8 + - Debian 10 'Buster' + +For certain OSes, there are a couple other caveats and tweaks you may need to perform to get things running smoothly—the main features and latest development is only guaranteed to work with the default OS as configured in `default.config.yml`. + +Some other OSes may work, but are not regularly tested with Drupal VM, and may require extra work to make everything work, depending on the version of Drupal you're using. + +## Ubuntu 18.04 Bionic LTS + +Everything should work out of the box with Ubuntu 18.04. + +## RedHat Enterprise Linux / CentOS 8 + +Everything should work out of the box with RHEL 8. + +## Debian 10 Buster + +Most everything should work out of the box with Debian 10. If you are installing `java` or `solr` in the `installed_extras`, you need to override the `java_packages` in your `config.yml`: + + java_packages: + - openjdk-11-jdk diff --git a/docs/extras/mariadb.md b/docs/configurations/databases-mariadb.md similarity index 81% rename from docs/extras/mariadb.md rename to docs/configurations/databases-mariadb.md index 4989bf833..29329d6a7 100644 --- a/docs/extras/mariadb.md +++ b/docs/configurations/databases-mariadb.md @@ -9,9 +9,9 @@ mysql_packages: - python-mysqldb ``` -This set of packages works out of the box with the default Ubuntu 14.04 installation that comes with Drupal VM. +This set of packages works out of the box with Ubuntu 18.04 installation that comes with Drupal VM. -Alternatively, if you want to use RedHat 7 or CentOS 7 instead of Ubuntu, you can set the following variables to install and configure MariaDB instead of MySQL: +Alternatively, if you want to use RedHat 8 or CentOS 8 instead of Ubuntu, you can set the following variables to install and configure MariaDB instead of MySQL: ```yaml mysql_packages: @@ -25,4 +25,4 @@ mysql_socket: /var/lib/mysql/mysql.sock mysql_log_error: /var/log/mariadb/mariadb.log mysql_syslog_tag: mariadb mysql_pid_file: /var/run/mariadb/mariadb.pid -``` \ No newline at end of file +``` diff --git a/docs/configurations/databases-mysql.md b/docs/configurations/databases-mysql.md new file mode 100644 index 000000000..24a0e3411 --- /dev/null +++ b/docs/configurations/databases-mysql.md @@ -0,0 +1,20 @@ +By default, this VM is set up so you can manage MySQL databases on your own. The default root MySQL user credentials are `drupal` for username and password, but you can change the password via `config.yml` (changing the `drupal_db_password` variable). I use [Sequel Pro](http://www.sequelpro.com/) (macOS-only) to connect to and manage databases, and Drush to sync databases (sometimes I'll just do a dump and import, but Drush is usually quicker, and is easier to do over and over again when you need it). + +## Connect using Adminer + +If you have `adminer` listed as one of the `installed_extras` inside `config.yml`, you can use Adminer's web-based interface to interact with databases. With Drupal VM running, visit [http://adminer.drupalvm.test/](http://adminer.drupalvm.test/), and log in with `drupal` as the username and the password you set in `config.yml` (`drupal_db_password`). Leave the "Server" field blank. The "Database" field is optional. + +More about how to use Adminer: [Adminer website](http://www.adminer.org/). + +## Connect using Sequel Pro (or a similar client): + + 1. Use the SSH connection type. + 2. Set the following options: + - MySQL Host: `127.0.0.1` + - Username: `drupal` + - Password: `drupal` (or the password configured in `config.yml`) + - SSH Host: `192.168.88.88` (or the IP configured in `config.yml`) + - SSH User: `vagrant` + - SSH Key: (browse to your `~/.vagrant.d/` folder and choose `insecure_private_key`) + +You should be able to connect as the root user and add, manage, and remove databases and users. diff --git a/docs/configurations/databases-postgresql.md b/docs/configurations/databases-postgresql.md new file mode 100644 index 000000000..8d7a390a1 --- /dev/null +++ b/docs/configurations/databases-postgresql.md @@ -0,0 +1,9 @@ +Since Drupal VM is built in a modular fashion, you can swap out the database engine and use [PostgreSQL](https://www.postgresql.org/) instead of MySQL (as long as the version of Drupal you're using supports it!). + +To switch from MySQL to PostgreSQL, switch the `drupal_db_backend` setting in your local `config.yml` to `pgsql`: + +```yaml +drupal_db_backend: pgsql +``` + +For more PostgreSQL configuration options, see the [`geerlingguy.postgresql` Ansible role's README](https://github.com/geerlingguy/ansible-role-postgresql#readme). diff --git a/docs/configurations/php.md b/docs/configurations/php.md new file mode 100644 index 000000000..34d72583c --- /dev/null +++ b/docs/configurations/php.md @@ -0,0 +1,26 @@ +Drupal VM defaults to PHP 7.4, but you can also install and use 7.2 or 7.3. + +## Ubuntu + +Ondřej Surý's PPA for PHP is used to install PHP 7.4, but you can switch versions by changing `php_version` inside `config.yml` to `"7.2"` or `"7.3"`. + +If you're using Apache with `mod_php` you should also add `libapache2-mod-php{{ php_version }}` to the `extra_packages` list. + +_Note: XHProf does currently not work with PHP 7.1+, make sure you don't have it listed in `installed_extras`._ + +## RedHat/CentOS 8 + +Remi's RPM repository is included with Drupal VM, and you can make the following changes to use it to install a different version of PHP than 7.4: + + 1. Make sure you've followed the directions for switching to CentOS 8 in the [use a different base OS](base-os.md) guide. + 2. Change `php_version` inside `config.yml` to `"7.2"` or `"7.3"`. + +## PHP 5.6 EOL + +PHP 5.6 was end-of-lifed (meaning no more community support or security fixes) at the end of 2018, and is not supported by Drupal VM. + +## Using default distribution packages + +If you want parity with your production environment and wish to install the default distribution packages, set `php_version: ''` inside your `config.yml` to avoid adding Remi's or Ondřej's repositories. Doing this will use the default packages set in the [`geerlingguy.php`](https://github.com/geerlingguy/ansible-role-php) Ansible role. + +_Note: If you're using a base OS with a PHP version older than what's assumed in the `geerlingguy.php` role, you will also need to override some of the default variables set by that role in your `config.yml`. See the [`geerlingguy.php` Ansible role's README](https://github.com/geerlingguy/ansible-role-php#readme) for more information._ diff --git a/docs/configurations/webservers-apache.md b/docs/configurations/webservers-apache.md new file mode 100644 index 000000000..2edce6b34 --- /dev/null +++ b/docs/configurations/webservers-apache.md @@ -0,0 +1,37 @@ +Drupal VM's configuration works with multiple operating systems _and_ with multiple webservers. You can switch between Apache and Nginx (depending on which server you prefer) with ease. Apache is the webserver used out of the box. + +You have complete control over all aspects of Apache VirtualHosts using the `apache_vhosts` configuration. A few simple examples are shown in `default.config.yml`, but this configuration can be much more complex. + +See the examples included in the [`geerlingguy.apache` Ansible role's README](https://github.com/geerlingguy/ansible-role-apache#readme) for more info, as well as many other variables you can override to configure Apache exactly how you like it. + +## Enable SSL Support with Apache + +To enable SSL support for you virtual hosts you first need a certificate file. You can generate a self-signed certificate with a command like + + openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout example.key -out example.crt + +_If you're using an actual production certificate you should of course **NOT** track it in git but transfer it to the VM before running `vagrant provision`_ + +Add the following to your `config.yml`: + +```yaml +apache_vhosts_ssl: + - servername: "{{ drupal_domain }}" + documentroot: "{{ drupal_core_path }}" + certificate_file: "/vagrant/example.crt" + certificate_key_file: "/vagrant/example.key" + extra_parameters: "{{ apache_vhost_php_fpm_parameters }}" +``` + +### Using Ubuntu's snakeoil certificate + +If you are using Ubuntu as your base OS and you want to get started quickly with a local development environment you can use the snakeoil certificate that is already generated. + +```yaml +apache_vhosts_ssl: + - servername: "{{ drupal_domain }}" + documentroot: "{{ drupal_core_path }}" + certificate_file: "/etc/ssl/certs/ssl-cert-snakeoil.pem" + certificate_key_file: "/etc/ssl/private/ssl-cert-snakeoil.key" + extra_parameters: "{{ apache_vhost_php_fpm_parameters }}" +``` diff --git a/docs/configurations/webservers-nginx.md b/docs/configurations/webservers-nginx.md new file mode 100644 index 000000000..0bd6b67e0 --- /dev/null +++ b/docs/configurations/webservers-nginx.md @@ -0,0 +1,81 @@ +To use Nginx instead of Apache, change the `drupalvm_webserver` variable inside your customized `config.yml`, from `apache` to `nginx`. + +Because Nginx server directives behave a little differently than Apache's VirtualHosts, Drupal VM includes a custom Drupal-optimized Nginx server block configuration, and you can control all the servers ('virtual hosts') Nginx will run using the `nginx_vhosts` configuration. A few simple examples are shown in `default.config.yml`, but you have some extra flexibility if you need it. See the `nginx-vhost.conf.j2` template for more information. + +Also, see the examples included in the [`geerlingguy.nginx` Ansible role's README](https://github.com/geerlingguy/ansible-role-nginx#readme) for more info, as well as many other variables you can override to configure Nginx exactly how you like it. + +_Note: if you're using php-fpm, you may want to reflect your use of nginx by setting `php_fpm_pool_user` and `php_fpm_pool_group` in your `config.yml`._ + +## Enable SSL Support with Nginx + +To enable SSL support for you virtual hosts you first need a certificate file. See the same section under the [Apache documentation](webservers-apache.md#enable-ssl-support-with-apache) for how to generate a self-signed certficiate. + +Modify your nginx host configuration by adding the following `extra_parameters` to the first entry in `nginx_vhosts`: + +```yaml +- server_name: "{{ drupal_domain }} www.{{ drupal_domain }}" + root: "{{ drupal_core_path }}" + is_php: true + extra_parameters: | + listen 443 ssl; + ssl_certificate /vagrant/example.crt; + ssl_certificate_key /vagrant/example.key; + ssl_protocols TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!MD5; +``` + +### Using Ubuntu's snakeoil certificate + +If you are using Ubuntu as your base OS and you want to get started quickly with a local development environment you can use the snakeoil certificate that is already generated. + +```yaml +- server_name: "{{ drupal_domain }} www.{{ drupal_domain }}" + root: "{{ drupal_core_path }}" + is_php: true + extra_parameters: | + listen 443 ssl; + ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; + ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; + ssl_protocols TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!MD5; +``` + +## Customizing server block configuration + +If you can't customize via variables because an option isn't exposed, you can override the template used to generate the the virtualhost configuration file. + +```yaml +nginx_vhost_template: "{{ config_dir }}/templates/nginx-vhost.conf.j2" +``` + +You can either copy and modify the provided `nginx-vhost.conf.j2` template, or extend it and use [template inheritace](http://jinja.pocoo.org/docs/2.9/templates/#template-inheritance) to override the specific template block you need to change. + +_If you extend Drupal VM's provided base template, the path referenced should to be relative to playbook.yml._ + +``` +{% extends 'templates/nginx-vhost.conf.j2' %} + +{% block location_primary %} +location / { + try_files $uri @rewrite; # For Drupal <= 6 +} +{% endblock %} + +{% block location_image_styles %} +location ~ ^/sites/.*/files/imagecache/ { + try_files $uri @rewrite; # For Drupal <= 6 +} +{% endblock %} +``` + +If you need to append or prepend content to a block, you can use the `{{ super() }}` Jinja2 function to return the original block content from the base template. + +``` +{% block location_deny %} +{{ super() }} +location ~* \.(txt|log)$ { + allow 192.168.0.0/16; + deny all; +} +{% endblock %} +``` diff --git a/docs/deployment/composer-dependency.md b/docs/deployment/composer-dependency.md new file mode 100644 index 000000000..6450ea6ef --- /dev/null +++ b/docs/deployment/composer-dependency.md @@ -0,0 +1,141 @@ +To make future Drupal VM updates easier to integrate with an existing project, you might consider the more complex setup of installing Drupal VM as a `composer` dependency. Using a delegating `Vagrantfile` you are able to run `vagrant` commands anywhere in your project as well as separate your custom configuration files from Drupal VM's own files. + +### Add Drupal VM as a Composer dependency + +Add Drupal VM as a development dependency to your `composer.json`. + +``` +composer require --dev geerlingguy/drupal-vm +``` + +### Setup your configuration files + +Add and configure the `config.yml` anywhere you like, in this example we place it in a `config/` directory. + +_Note: This will be the directory where Drupal VM looks for other local configuration files as well. Such as `drupal_build_makefile` and `local.config.yml`._ + +``` +├── composer.json +├── config/ +│ ├── config.yml +│ ├── local.config.yml +│ └── Vagrantfile.local +├── docroot/ +│ ├── ... +│ └── index.php +└── vendor/ + ├── ... + └── geerlingguy/ + └── drupal-vm/ +``` + +Change the [build strategy to use your `composer.json`](composer.md#using-composer-when-drupal-vm-is-a-composer-dependency-itself) file by setting: + +```yaml +drupal_build_composer_project: false +drupal_build_composer: true +drupal_composer_path: false +drupal_composer_install_dir: "/var/www/drupalvm" +drupal_core_path: "{{ drupal_composer_install_dir }}/docroot" +``` + +If you intend to use the devel module, it must be added as a requirement to your `composer.json` file. Alternatively, if you do not intend to use it remove it from `drupal_enable_modules` in your `config.yml` file: + +```yaml +drupal_enable_modules: [] +``` + +### Create a delegating `Vagrantfile` + +Create a delegating `Vagrantfile` that will catch all your `vagrant` commands and send them to Drupal VM's own `Vagrantfile`. Place this file in your project's root directory. + +```ruby +# The absolute path to the root directory of the project. Both Drupal VM and +# the config file need to be contained within this path. +ENV['DRUPALVM_PROJECT_ROOT'] = "#{__dir__}" +# The relative path from the project root to the config directory where you +# placed your config.yml file. +ENV['DRUPALVM_CONFIG_DIR'] = "config" +# The relative path from the project root to the directory where Drupal VM is located. +ENV['DRUPALVM_DIR'] = "vendor/geerlingguy/drupal-vm" + +# Load the real Vagrantfile +load "#{__dir__}/#{ENV['DRUPALVM_DIR']}/Vagrantfile" +``` + +When you issue `vagrant` commands anywhere in your project tree this file will be detected and used as a delegator for Drupal VM's own Vagrantfile. + +Your project structure should now look like this: + +``` +├── Vagrantfile +├── composer.json +├── config/ +│ ├── config.yml +│ ├── local.config.yml +│ └── Vagrantfile.local +├── docroot/ +│ ├── ... +│ └── index.php +└── vendor/ + ├── ... + └── geerlingguy/ + └── drupal-vm/ +``` + +### Provision the VM + +Finally provision the VM using the delegating `Vagrantfile`. + +```sh +vagrant up +``` + +_Important: you should never issue `vagrant` commands through Drupal VM's own `Vagrantfile` from now on. If you do, it will create a secondary VM in that directory._ + +## Drupal VM in a subdirectory without composer + +If you're not using `composer` in your project you can still download Drupal VM (or add it as a git submodule) to any subdirectory in your project. As an example let's name that directory `box/`. + +``` +├── docroot/ +│ ├── ... +│ └── index.php +└── box/ + ├── ... + ├── default.config.yml + └── Vagrantfile +``` + +Configure your `config.yml` as mentioned in the [`composer` section](#setup-your-configuration-files) above. + +```yaml +post_provision_scripts: + # The default provided in `default.config.yml`: + - "../../examples/scripts/configure-solr.sh" + # With Drupal VM in a toplevel subdirectory + - "{{ config_dir }}/../examples/scripts/configure-solr.sh" +``` + +Your directory structure should now look like this: + +``` +├── Vagrantfile +├── config/ +│ ├── config.yml +│ ├── local.config.yml +│ └── Vagrantfile.local +├── docroot/ +│ ├── ... +│ └── index.php +└── box/ + ├── ... + ├── default.config.yml + └── Vagrantfile +``` + +Provision the VM using the delegating `Vagrantfile`. + +```sh +vagrant up +``` diff --git a/docs/deployment/composer-package.md b/docs/deployment/composer-package.md new file mode 100644 index 000000000..e0a56508b --- /dev/null +++ b/docs/deployment/composer-package.md @@ -0,0 +1,18 @@ +Out of the box Drupal VM is configured to use `composer create-project` to build a Drupal codebase. + +This is set up with the following variables in `config.yml`: + + - Composer will build the project if `drupal_build_composer_project` is `true`, and `drupal_build_makefile` and `drupal_build_composer` are both `false`. + - The Composer package is defined by `drupal_composer_project_package`. + - Adjust the create-project CLI options in `drupal_composer_project_options` as well as add additional dependencies in `drupal_composer_dependencies`. + - Ensure that the webroot configured in the Composer package matches the one set in `drupal_core_path`. The default is set to `web/`. + +With [acquia/lightning-project](https://github.com/acquia/lightning-project) as an example your `config.yml` settings would be: + +```yaml +drupal_composer_project_package: "acquia/lightning-project:^8.8.1" +drupal_composer_project_options: "--prefer-dist --stability rc --no-interaction" +drupal_core_path: "{{ drupal_composer_install_dir }}/docroot" +``` + +_Opting for composer based installs will most likely increase your VM's time to provision considerably. Find out how you can [improve composer build performance](../other/performance.md#improving-composer-build-performance)._ diff --git a/docs/deployment/composer.md b/docs/deployment/composer.md new file mode 100644 index 000000000..fbfb8e967 --- /dev/null +++ b/docs/deployment/composer.md @@ -0,0 +1,28 @@ +Drupal VM is configured to use `composer create-project` to build a Drupal 8 codebase by default but supports building Drupal from a custom `composer.json` file as well. + +1. Copy `example.drupal.composer.json` to `drupal.composer.json` and modify it to your liking. +2. Use the Composer build system by setting `drupal_build_composer: true` in your `config.yml` (make sure `drupal_build_makefile` and `drupal_build_composer_project` are set to `false`). +3. Ensure `drupal_core_path` points to the webroot directory: `drupal_core_path: {{ drupal_composer_install_dir }}/web` + +```yaml +drupal_build_makefile: false +drupal_build_composer_project: false +drupal_build_composer: true +drupal_core_path: "{{ drupal_composer_install_dir }}/web" +``` + +_The file set in `drupal_composer_path` (which defaults to `drupal.composer.json`) will be copied from your host computer into the VM's `drupal_composer_install_dir` and renamed `composer.json`._ + +## Using Composer when [Drupal VM is a composer dependency itself](composer-dependency.md) + +In the scenario where you have an existing `composer.json` in the root of your project, follow the usual steps for installing with a composer.json but instead of creating a `drupal.composer.json` file, disable the transfering of the file by setting `drupal_composer_path: false`, and change `drupal_composer_install_dir` to point to the the directory where it will be located. If `drupal_composer_path` is not truthy, Drupal VM assumes it already exists. + +```yaml +drupal_build_composer_project: false +drupal_build_composer: true +drupal_composer_path: false +drupal_composer_install_dir: "/var/www/drupalvm" +drupal_core_path: "{{ drupal_composer_install_dir }}/docroot" +``` + +_Opting for composer based installs will most likely increase your VM's time to provision considerably. Find out how you can [improve composer build performance](../other/performance.md#improving-composer-build-performance)._ diff --git a/docs/deployment/drush-make.md b/docs/deployment/drush-make.md index b777221b9..c8265b805 100644 --- a/docs/deployment/drush-make.md +++ b/docs/deployment/drush-make.md @@ -1,5 +1,23 @@ -Drupal VM is configured by default to use a Drush make file to build a Drupal site on the VM inside `/var/www/drupal` (in a folder that's synced to your local machine, so you can work with the Drupal codebase either locally or inside the VM). +If you want to build a Drupal site using a [Drush make file](http://www.drush.org/en/master/make/) instead of Composer, you will need to do the following: -You can use any make file you want, just copy it or symlink it into the root of the Drupal VM folder with the filename `drupal.make.yml`. You can also set a separate path to the makefile using the `drush_makefile_path` variable. + - Set `drupal_build_composer_project: false` + - Set `drupal_build_makefile: true` + - Use the `example.drupal.make.yml` file as a base (copy it to a new file named `drupal.make.yml`), or use your own Drush make file + - (You can also set a separate path to the makefile using the `drush_makefile_path` variable.) + - Set the following options to force an install an older version of Drush (Drush 9+ no longer supports Drush make files): -Leave the rest of the settings in `config.yml` as defaults from `example.config.yml`, or tweak the settings as you'd like, then run `vagrant up` as in the Quick Start Guide. Within a few minutes, you should have your site running and available at the `drupal_domain` configured in `config.yml`. \ No newline at end of file +```yaml +drush_launcher_install: no +drush_install_from_source: yes +drush_source_install_version: "8.9.1" +``` + +Have a look at the defaults in `default.config.yml` and tweak the settings as you'd like in your `config.yml`, then run `vagrant up` as in the Quick Start Guide. Within a few minutes, you should have your site running and available at the `drupal_domain` configured in `config.yml`, falling back to the default `http://drupalvm.test` set in `default.config.yml`. + +With the default settings the Drupal site will be built on the VM inside `/var/www/drupalvm/drupal/web` but the `web/` subdirectory is only required for `composer` based projects and you can simplify this directory structure by setting `drupal_core_path` to `/var/www/drupalvm/drupal`. + +```yaml +drupal_build_composer_project: false +drupal_build_makefile: true +drupal_core_path: "/var/www/drupalvm/drupal" +``` diff --git a/docs/deployment/git.md b/docs/deployment/git.md new file mode 100644 index 000000000..3fffb373d --- /dev/null +++ b/docs/deployment/git.md @@ -0,0 +1,25 @@ +You can deploy a codebase directly inside Drupal VM via Git. You can deploy a Git-based Drupal site directly into a shared folder, or you can even deploy inside Drupal VM's own filesystem. The latter option offers better performance than any of the other deployment methods, since Drupal VM can use native filesystem caches and disk access. + +This is also the recommended method for deploying Drupal sites to Drupal VM when used [in production](../other/production.md) + +## Deploying Drupal via Git + +Drupal VM uses the [`geerlingguy.drupal`](https://github.com/geerlingguy/ansible-role-drupal) Ansible role to deploy and manage Drupal codebases. + +To deploy your Drupal project inside Drupal VM during provisioning, you need to set the following variables inside `config.yml`: + + drupal_deploy: true + drupal_deploy_repo: "git@github.com:username/example.git" + drupal_deploy_dir: /var/www/drupal + +The above settings assume you want to deploy a Drupal codebase in the GitHub repository `username/example.git` (or any other valid Git URL to which you have access). And it will place that codebase inside `/var/www/drupal`, which you might have mounted as a shared folder, or if you want even better performance, you could configure a 'reverse mount' or just work on the codebase inside the VM. + +If you want to disable Drupal VM's default synced folder, set the following variable in `config.yml`: + + vagrant_synced_folders: [] + +When you run `vagrant provision` or deploy Drupal VM to a production server, the `geerlingguy.drupal` role will check out the Git repository into the `drupal_deploy_dir`. + +> Note: For private repositories, you can use your own SSH key if you use `ssh-agent`. On Mac or Linux, you can run `ssh-add -K` to add your default private key to the SSH Agent, or on Windows you can either use [Pageant](https://winscp.net/eng/docs/ui_pageant), an SSH agent built into your CLI emulator, or if you're on Windows 10, the SSH Agent that's installed with Ubuntu Bash. + +For more information about this technique, please read Jeff Geerling's blog post, [Drupal VM on Windows - a fast container for BLT project development](https://www.jeffgeerling.com/blog/2017/drupal-vm-on-windows-fast-container-blt-project-development). Note that this technique is great for better performance on Windows, but it can be used on any platform where Drupal VM is used. diff --git a/docs/deployment/local-codebase.md b/docs/deployment/local-codebase.md index a70f1870b..d0d887be0 100644 --- a/docs/deployment/local-codebase.md +++ b/docs/deployment/local-codebase.md @@ -8,30 +8,48 @@ Update the `vagrant_synced_folders` configuration to sync your local Drupal code vagrant_synced_folders: - local_path: ~/Sites/my-drupal-site destination: /var/www/my-drupal-site - id: drupal type: nfs ``` -## Disable the Drush make build and site install +_If you have Drupal VM installed within your codebase, you can also set the `local_path` to a location relative to the `Vagrantfile`. This is the default setup in `default.config.yml`._ -Set `build_makefile` and `install_site` to `false`: +## Disable the Composer project build and site install + +Set all the `drupal_build_*` variables and `install_site` to `false`: ```yaml -build_from_makefile: false +drupal_build_makefile: false +drupal_build_composer: false +drupal_build_composer_project: false ... -install_site: false +drupal_install_site: false ``` -_If you aren't copying back a database, and want to have Drupal VM run `drush si` for your Drupal site, you can leave `install_site` set to `true` and it will run a site install on your Drupal codebase using the `drupal_*` config variables. +If you aren't copying back a database, and want to have Drupal VM run `drush si` for your Drupal site, you can leave `drupal_install_site` set to `true` and it will run a site install on your Drupal codebase using the `drupal_*` config variables. + +## Update `drupal_core_path` + +Set `drupal_core_path` to the same value as the `destination` of the synced folder you configured earlier: + +```yaml +drupal_core_path: "/var/www/my-drupal-site" +``` -## Update `apache_vhosts` +This variable will be used for the document root of the webserver. + +## Set the domain + +By default the domain of your site will be `drupalvm.test` but you can change it by setting `drupal_domain` to the domain of your choice: + +```yaml +drupal_domain: "local.my-drupal-site.com" +``` -Add your site to `apache_vhosts`, setting the `documentroot` to the same value as the `destination` of the synced folder you configured earlier: +If you prefer using your domain as the root of all extra packages installed, ie. `adminer` and `xhprof`, set it as the value of `vagrant_hostname` instead. ```yaml -apache_vhosts: - - {servername: "local.my-drupal-site.com", documentroot: "/var/www/my-drupal-site"} - - {servername: "local.xhprof.com", documentroot: "/usr/share/php/xhprof_html"} +vagrant_hostname: "my-drupal-site.com" +drupal_domain: "{{ vagrant_hostname }}" ``` ## Update MySQL info @@ -40,4 +58,4 @@ If you have your Drupal site configured to use a special database and/or user/pa ## Build the VM, import your database -Run `vagrant up` to build the VM with your codebase synced into the proper location. Once the VM is created, you can connect to the MySQL database (see the sidebar topic "MySQL - Connecting to the DB") and import your site's database to the Drupal VM, or use a command like `drush sql-sync` to copy a database from another server. \ No newline at end of file +Run `vagrant up` to build the VM with your codebase synced into the proper location. Once the VM is created, you can [connect to the MySQL database](../configurations/databases-mysql.md) and import your site's database to the Drupal VM, or use a [command like `drush sql-sync`](../extras/drush.md#using-sql-sync) to copy a database from another server. diff --git a/docs/deployment/multisite.md b/docs/deployment/multisite.md index d1551378d..15afd8a0a 100644 --- a/docs/deployment/multisite.md +++ b/docs/deployment/multisite.md @@ -1,11 +1,24 @@ -For multisite installations, make the changes outlined in the [Local Drupal codebase](https://github.com/geerlingguy/drupal-vm/wiki/Local-Drupal-codebase) guide, but, using the `apache_vhosts` variable, configure as many domains pointing to the same docroot as you need: +For multisite installations, make the changes outlined in the [Local Drupal codebase](local-codebase.md) guide, but, using the `apache_vhosts` variable (or `nginx_vhosts` if using Nginx), configure as many domains pointing to the same docroot as you need: ```yaml +drupal_core_path: "/var/www/my-drupal-site" + +... + apache_vhosts: - - {servername: "local.my-drupal-site.com", documentroot: "/var/www/my-drupal-site"} - - {servername: "local.second-drupal-site.com", documentroot: "/var/www/my-drupal-site"} - - {servername: "local.third-drupal-site.com", documentroot: "/var/www/my-drupal-site"} - - {servername: "local.xhprof.com", documentroot: "/usr/share/php/xhprof_html"} + # Drupal VM's default domain, evaluating to whatever `vagrant_hostname` is set to (drupalvm.test by default). + - servername: "{{ drupal_domain }}" + serveralias: "www.{{ drupal_domain }}" + documentroot: "{{ drupal_core_path }}" + extra_parameters: "{{ apache_vhost_php_fpm_parameters }}" + + - servername: "local.second-drupal-site.com" + documentroot: "{{ drupal_core_path }}" + extra_parameters: "{{ apache_vhost_php_fpm_parameters }}" + + - servername: "local.third-drupal-site.com" + documentroot: "{{ drupal_core_path }}" + extra_parameters: "{{ apache_vhost_php_fpm_parameters }}" ``` If you need additional databases and database users, add them to the list of `mysql_databases` and `mysql_users`: diff --git a/docs/extending/ansible-args.md b/docs/extending/ansible-args.md new file mode 100644 index 000000000..69d56914d --- /dev/null +++ b/docs/extending/ansible-args.md @@ -0,0 +1,38 @@ +## Run a specific set of tagged tasks + +You can filter which part of the provisioning process to run by specifying a set of tags using the `DRUPALVM_ANSIBLE_TAGS` environment variable. + +```sh +# E.g. xdebug, drupal, webserver, database, cron... +DRUPALVM_ANSIBLE_TAGS=xdebug vagrant provision + +# Or combine them (e.g. if adding new databases and virtualhosts). +DRUPALVM_ANSIBLE_TAGS=webserver,database vagrant provision +``` + +## Passing arguments to ansible during a provision + +You can specify an additional argument to the `ansible-playbook` command by using the `DRUPALVM_ANSIBLE_ARGS` environment variable. This can be useful when debugging a task failure. + +> Note the following caveats: +> +> - Passing more than one argument may require special formatting. Read the [Ansible provisioner's `raw_arguments` docs](https://www.vagrantup.com/docs/provisioning/ansible_common.html#raw_arguments) for more info. +> - You should not quote a flag's value as you would normally do in the shell. + +Display verbose ansible output: + +```sh +DRUPALVM_ANSIBLE_ARGS='--verbose' vagrant provision +``` + +Begin the provisioning at a particular task: + +```sh +DRUPALVM_ANSIBLE_ARGS="--start-at-task '*post-provision shell*'" vagrant provision +``` + +Override a config variable: + +```sh +DRUPALVM_ANSIBLE_ARGS='--extra-vars "drupal_db_backend=pgsql"' vagrant provision +``` diff --git a/docs/extending/scripts.md b/docs/extending/scripts.md new file mode 100644 index 000000000..af42cf40d --- /dev/null +++ b/docs/extending/scripts.md @@ -0,0 +1,48 @@ +Drupal VM allows you to run extra shell scripts and ansible task files in the beginning and at the end of the provisioning process, in case you need to do extra setup, further configure the VM, or install extra software outside the purview of Drupal VM. + +## Shell scripts + +To use an extra script, configure the path to the script (relative to `provisioning/playbook.yml`) in `config.yml`: + +```yaml +pre_provision_scripts: + - "../scripts/pre-provision.sh" +post_provision_scripts: + - "../scripts/post-provision.sh" +``` + +The above example results in a `pre-provision.sh` script running before the provisioning starts and a `post-provision.sh` script running after the main Drupal VM setup is complete. Pre and post provision scripts run after the first `vagrant up`, and then any time you run Vagrant provisioning (e.g. `vagrant provision` or `vagrant up --provision`). + +_Note: The pre provision scripts run before any other packages are installed. If you want to use commands such as `git`, you need to install the packages yourself._ + +You can define as many scripts as you would like, and any arguments after the path will be passed to the shell script itself (e.g. `"- "../scripts/setup-paths.sh --option"`). + +Place your pre and post provision scripts inside a `scripts` directory in the root of your Drupal VM project directory; this directory is gitignored, so you can continue to update Drupal VM without overwriting your scripts. + +## Ansible task files + +To use an extra ansible task file, configure the path to the file (relative to `provisioning/playbook.yml`) in `config.yml`: + +```yaml +pre_provision_tasks_dir: "../scripts/pre/*" +post_provision_tasks_dir: "../scripts/post-provision.yml" +``` + +The path will be evaluated as a [glob pattern](https://docs.python.org/2/library/glob.html) so you can point to a single file or a directory matching a set of files. + +The files matched will run in alphabetical order, and as with shell scripts, pre-provision task files will run before any other packages are installed. + +## Ansible playbooks + +Out of the box Drupal VM does not support running additional playbooks or adding your own roles but using [`Vagrantfile.local` you can add any number of additional provisioners to vagrant](vagrantfile.md). + +As an example you might have a `local.playbook.yml` with it's own dependencies defined in `local.requirements.yml`. Place both of these next to your `config.yml` and add the following `Vagrantfile.local`. + +```rb +config.vm.provision 'ansible' do |ansible| + ansible.playbook = "#{host_config_dir}/local.playbook.yml" + ansible.galaxy_role_file = "#{host_config_dir}/local.requirements.yml" +end +``` + +When you run `vagrant provision` this playbook will run after Drupal VM's own playbook. diff --git a/docs/extending/vagrantfile.md b/docs/extending/vagrantfile.md new file mode 100644 index 000000000..4a5a0fcf8 --- /dev/null +++ b/docs/extending/vagrantfile.md @@ -0,0 +1,86 @@ +Out of the box Drupal VM supports having VirtualBox, Parallels as well as VMware as a provider. Besides these there are multitude of others available (for example `vagrant-aws`, `vagrant-digitalocean`). If you want to use an unsupported provider, or otherwise modify the vagrant configuration in a way that is not exposed by Drupal VM, you can create a `Vagrantfile.local` next to your `config.yml`. + +The file will be sourced at the end of the `Vagrant.configure` block so you will have access to Vagrant's `config.vm` object as well as the contents of the `config.yml` file within the `vconfig` hash. + +To add a configuration just create a `Vagrantfile.local` in the root like so: + +```ruby +config.vm.provider :virtualbox do |v| + # Enable GUI mode instead of running a headless machine. + v.gui = true + + # Cap the host CPU execution at 50% usage. + v.customize ["modifyvm", :id, "--cpuexecutioncap", "50"] +end +``` + +### Automatically install Vagrant plugins + +Drupal VM can be configured to ensure Vagrant plugins are installed by adding them to the `vagrant_plugins` list in your `config.yml` file. + +```yaml +vagrant_plugins: + - name: vagrant-vbguest + - name: vagrant-hostsupdater + - name: vagrant-aws +``` + +### Example: Using the `vagrant-aws` provider + +Add the following variables to your `config.yml`. + +```yaml +aws_keypair_name: 'keypair' +aws_ami: 'ami-7747d01e' +aws_tags_name: 'Drupal VM' +aws_ssh_username: 'ubuntu' +aws_ssh_private_key: '~/.ssh/aws.pem' +``` + +Create a `Vagrantfile.local` in the root directory of your project. + +```ruby +config.vm.provider :aws do |aws, override| + override.nfs.functional = false + + aws.access_key_id = ENV['AWS_ACCESS_KEY_ID'] + aws.secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] + aws.keypair_name = vconfig['aws_keypair_name'] + aws.tags['Name'] = vconfig['aws_tags_name'] + aws.ami = vconfig['aws_ami'] + + override.ssh.username = vconfig['aws_ssh_username'] + override.ssh.private_key_path = vconfig['aws_ssh_private_key'] +end +``` + +Add the `AWS_ACCESS_KEY_ID` and the `AWS_SECRET_ACCESS_KEY` environment variables to your shell. + +Then run `vagrant up --provider=aws` to provision the instance. + +_For additional configuration options read the [Vagrant AWS Provider's README](https://github.com/mitchellh/vagrant-aws#readme)._ + +### Example: Using Drupal VM behind a corporate proxy with `vagrant-proxyconf` + +Add the following variables to your `config.yml`. + +```yaml +proxy_http: 'http://192.168.0.2:3128/' +proxy_https: 'http://192.168.0.2:3128/' +proxy_ftp: 'http://192.168.0.2:3128/' +proxy_none: 'localhost,127.0.0.1,{{ drupal_domain }}' +``` + +Create a `Vagrantfile.local` in the root directory of your project. + +```ruby +if Vagrant.has_plugin?('vagrant-proxyconf') + config.proxy.http = vconfig['proxy_http'] + config.proxy.https = vconfig['proxy_https'] + config.git_proxy.http = vconfig['proxy_http'] + config.proxy.no_proxy = vconfig['proxy_none'] + config.proxy.ftp = vconfig['proxy_ftp'] +end +``` + +_For additional configuration options read [Vagrant Proxyconf's README](https://github.com/tmatilai/vagrant-proxyconf#readme)._ diff --git a/docs/extras/adminer.md b/docs/extras/adminer.md new file mode 100644 index 000000000..302560f13 --- /dev/null +++ b/docs/extras/adminer.md @@ -0,0 +1,3 @@ +If you have `adminer` listed as one of the `installed_extras` inside `config.yml`, you can use Adminer's web-based interface to interact with databases. With Drupal VM running, visit [http://adminer.drupalvm.test/](http://adminer.drupalvm.test/), and log in with `drupal` as the username and the password you set in `config.yml` (`drupal_db_password`). Leave the "Server" field blank. The "Database" field is optional. + +For a list of available role variables, see the [`geerlingguy.adminer` Ansible role's README](https://github.com/geerlingguy/ansible-role-adminer#readme). diff --git a/docs/extras/behat.md b/docs/extras/behat.md deleted file mode 100644 index 246dcb471..000000000 --- a/docs/extras/behat.md +++ /dev/null @@ -1,95 +0,0 @@ -Behat is an open source behavior-driven development tool for PHP. You can use Behat to build and run automated tests for site functionality on your Drupal sites, and Drupal VM has excellent built-in support for Behat, using Selenium to run tests in a headless instance of FireFox. - -## Getting Started - Installing Prerequisites - -To make Behat available globally for all your projects within Drupal VM, make the following changes inside `config.yml`, then run `vagrant up` (or `vagrant provision` if the VM is already built): - -```yaml -# Make sure selenium is not commented out in the list of installed_extras: -installed_extras: - [...] - - selenium - [...] - -# Make sure the following four packages are in composer_global_packages: -composer_global_packages: - - { name: behat/mink, release: '1.5.*@stable' } - - { name: behat/mink-goutte-driver, release: '*' } - - { name: behat/mink-selenium2-driver, release: '*' } - - { name: drupal/drupal-extension, release: '*' } -``` - -After Drupal VM is finished provisioning, you should be able to log in and run the following command to make sure Behat is installed correctly: - -``` -$ behat --version -behat version 3.0.15 -``` - -_You can also include the `behat/*` and `drupal/drupal-extension` directly in your project's `composer.json` file, and install the dependencies per-project. Either option (installing globally, like above, or installing per-project) is perfectly acceptable._ - -## Setting up Behat for your project - -Using the default Drupal site as an example (it's installed in `/var/www/drupal` by default, and is shared to `~/Sites/drupalvm/drupal` on your host machine), the following steps will help you get your first Behat tests up and running! - - 1. Create a `behat.yml` file inside the docroot of your site (e.g. create this file alongside the rest of the Drupal codebase at `/var/www/drupal/behat.yml`), with the following contents: - - ``` - default: - suites: - web_features: - paths: [ %paths.base%/features/web ] - contexts: [ WebContext ] - extensions: - Behat\MinkExtension: - goutte: ~ - javascript_session: selenium2 - selenium2: - wd_host: http://drupalvm.dev:4444/wd/hub - base_url: http://drupalvm.dev - Drupal\DrupalExtension: - blackbox: ~ - api_driver: 'drupal' - drupal: - drupal_root: '/var/www/drupal' - ``` - - 2. Log into Drupal VM with `vagrant ssh`, change directory to the Drupal site root (`cd /var/www/drupal`), then run `behat --init` to initialize the `features` folder where you will place test cases. - 3. From either inside the VM or on the host machine, open up the new `features` folder Behat just created, and create a new `drupal` folder inside. Inside _that_ folder, create `HomeContent.feature` with the following contents: - - ``` - Feature: Test DrupalContext - In order to prove the Behat is working correctly in Drupal VM - As a developer - I need to run a simple interface test - - Scenario: Viewing content in a region - Given I am on the homepage - Then I should see "No front page content has been created yet" in the "content" - - ``` - - 4. Now, inside Drupal VM, change directory to `/var/www/drupal` again, and run the command `behat` (which runs all the tests you've created—which should just be one so far). - -If everything was done correctly, you should see: - -``` -$ behat -Feature: Test DrupalContext - In order to prove the Behat is working correctly in Drupal VM - As a developer - I need to run a simple interface test - - Scenario: Viewing content in a region # features/drupal/HomeContent.feature:6 - Given I am on the homepage # Drupal\DrupalExtension\Context\MinkContext::iAmOnHomepage() - Then I should see "No front page content has been created yet" in the "content" # Drupal\DrupalExtension\Context\MinkContext::assertRegionText() - -1 scenario (1 passed) -2 steps (2 passed) -0m0.56s (26.48Mb) -``` - -Hooray! Now you're ready to get started testing ALL THE THINGS! Check out the following resources for more information about Behat and Drupal: - - - [Behat 3.0 Documentation](http://behat.readthedocs.org/en/v3.0/) - - [Drupal Extension Documentation](https://behat-drupal-extension.readthedocs.org/en/3.0/) \ No newline at end of file diff --git a/docs/extras/blackfire.md b/docs/extras/blackfire.md new file mode 100644 index 000000000..0b794aa73 --- /dev/null +++ b/docs/extras/blackfire.md @@ -0,0 +1,23 @@ +[Blackfire.io](https://blackfire.io/) is a service that allows code profiling to be stored and analyzed via an online profile on the Blackfire.io website. + +It doesn't require any additional Drupal modules to use, but once you've made sure `blackfire` is in the list of `installed_extras` in `config.yml` (and Drupal VM has been provisioned), you need to log into Drupal VM and [run the setup steps outlined on the Blackfire Ansible role's README](https://github.com/geerlingguy/ansible-role-blackfire#requirements). + +**Note**: You should only enable one code profiler at a time—e.g. when using [Blackfire](blackfire.md), disable [XHProf](xhprof.md), [Tideways](tideways.md) and [XDebug](xdebug.md). + +Once you've configured your environment for your own Blackfire account, you can profile a request with Blackfire by running something like the following example (within Drupal VM, after logging in with `vagrant ssh`): + +``` +$ blackfire curl http://drupalvm.test/ +Profiling: [########################################] 10/10 +Blackfire cURL completed +Graph URL https://blackfire.io/profiles/[UUID]/graph + +Wall Time 151ms +CPU Time 130ms +I/O Time 20.9ms +Memory 1.5MB +Network n/a n/a - +SQL n/a - +``` + +For a list of available role variables, see the [`geerlingguy.blackfire` Ansible role's README](https://github.com/geerlingguy/ansible-role-blackfire#readme). diff --git a/docs/extras/drupal-console.md b/docs/extras/drupal-console.md index 1b050744e..a671c829f 100644 --- a/docs/extras/drupal-console.md +++ b/docs/extras/drupal-console.md @@ -1,20 +1,65 @@ -[Drupal Console](http://drupalconsole.com/) is a modern CLI for interacting with Drupal and scaffolding a site. It works only with Drupal 8+, and is built on top of the Symfony Console component. +[Drupal Console](https://drupalconsole.com/) is a modern CLI for interacting with Drupal and scaffolding a site. It works only with Drupal 8+, and is built on top of the Symfony Console component. -Drupal VM will automatically install Drupal Console if you install Drupal 8 or later in your VM (this is based on the value of the `drupal_major_version` variable inside `config.yml`. +To have Drupal Console installed globally inside Drupal VM, make sure `drupalconsole` is in the list of `installed_extras` in your `config.yml` file. If you're adding it to an existing Drupal VM, run `vagrant provision` so it gets installed. You also (or instead) might want to add Drupal Console as a dependency of your Drupal project—if you do this, you may not need to add `drupalconsole` to Drupal VM globally. To use Drupal Console with a Drupal 8 site (in this case, using the default configuration that ships with Drupal VM): 1. Log into the VM with `vagrant ssh`. - 2. Change directory to the Drupal site's document root: `cd /var/www/drupal`. - 3. Use Drupal console (e.g. `drupal cache:rebuild --cache=all`). + 2. Change directory to the Drupal site's document root: `cd /var/www/drupalvm/drupal/web`. + 3. Use Drupal console (e.g. `drupal cache:rebuild all`). You should see an output like: ``` -vagrant@drupaltest:/var/www/drupal$ drupal cache:rebuild --cache=all +vagrant@drupalvm:/var/www/drupalvm/drupal/web$ drupal cache:rebuild all [+] Rebuilding cache(s), wait a moment please. [+] Done clearing cache(s). The command was executed successfully! -``` \ No newline at end of file +``` + +## Remote command execution using `--target` + +To run commands on your host computer but execute them on the VM, add a new sites file `~/.console/sites/drupalvm.yml` on your host computer: + +```yaml +dev: + root: /var/www/drupalvm/drupal + host: 192.168.88.88 + password: vagrant + type: ssh + extra-options: '-o PasswordAuthentication=no -i ~/.vagrant.d/insecure_private_key' +``` + +Execute from host machine using the `--target` option. + + drupal --target=drupalvm.test site:status + +or + + drupal @drupalvm.test site:status + +For more details, see [Drupal Console's documentation](https://docs.drupalconsole.com/en/alias/how-to-use-drupal-console-in-a-remote-installation.html) + +For a list of available role variables, see the [`geerlingguy.drupal-console` Ansible role's README](https://github.com/geerlingguy/ansible-role-drupal-console#readme). + +## Remote command execution using `vagrant-exec` + +You can use [`vagrant-exec`](https://github.com/p0deje/vagrant-exec) to execute commands remotely through Vagrant, and if you can't get Console to work with `--target`, you might want to try doing this (it's more convenient than logging into the VM just to run a Drupal VM command!). + +First, install the plugin: + + vagrant plugin install vagrant-exec + +Add the following to a `Vagrantfile.local` in your project (set `directory` to your drupal docroot): + +```ruby +if Vagrant.has_plugin?('vagrant-exec') + config.exec.commands '*', directory: '/var/www/drupal' +end +``` + +Now you can execute any Drupal Console command—even interactive ones!—from the host: + + vagrant exec bin/drupal generate:module diff --git a/docs/extras/drush.md b/docs/extras/drush.md index 11879ce89..5994f2d51 100644 --- a/docs/extras/drush.md +++ b/docs/extras/drush.md @@ -1,38 +1,83 @@ -If you have Drush installed on your host workstation, and would like to interact with a Drupal site running inside Drupal VM, there are drush aliases automatically created by Drupal VM for each of the virtual hosts you have configured. +If you have [Drush](http://www.drush.org) and Ansible installed on your host workstation, and would like to interact with a Drupal site running inside Drupal VM, there are drush aliases automatically created by Drupal VM for each of the virtual hosts you have configured. -With the example configuration, you can manage the example Drupal site using the Drush alias `@drupaltest.dev`. For example, to check if Drush can connect to the site in Drupal VM, run: +> Note: Drush 9.0.0 and later require some architectural changes to the way Drush is installed and used both within Drupal VM and on your host computer. Please check the [Drush](https://github.com/drush-ops/drush/issues) and [Drupal VM](https://github.com/geerlingguy/drupal-vm/issues) issue queues if you encounter any strange behavior when using Drush. + +With the example configuration, you can manage the example Drupal site using the Drush alias `@drupalvm.test`. For example, to check if Drush can connect to the site in Drupal VM, run: ``` -$ drush @drupaltest.dev status - Drupal version : 8.0.0-dev - Site URI : drupaltest.dev - Database driver : mysql - Database hostname : localhost - Database port : - Database username : drupal - Database name : drupal - Database : Connected - Drupal bootstrap : Successful - Drupal user : Anonymous - Default theme : bartik - Administration theme : seven - PHP executable : /usr/bin/php - PHP configuration : /etc/php5/cli/php.ini - PHP OS : Linux - Drush script : /usr/local/share/drush/drush.php - Drush version : 7.0-dev - Drush temp directory : /tmp - Drush configuration : - Drush alias files : - Drupal root : /var/www/drupal - Site path : sites/default - File directory path : sites/default/files - Temporary file : /tmp - directory path +$ drush @drupalvm.test status + Drupal version : 8.0.0-dev + Site URI : drupalvm.test + Database driver : mysql + Database hostname : localhost + Database port : + Database username : drupal + Database name : drupal + Database : Connected + Drupal bootstrap : Successful + Drupal user : Anonymous + Default theme : bartik + Administration theme : seven + PHP executable : /usr/bin/php + PHP configuration : /etc/php5/cli/php.ini + PHP OS : Linux + Drush script : /usr/local/share/drush/drush.php + Drush version : 7.0-dev + Drush temp directory : /tmp + Drush configuration : + Drush alias files : + Drupal root : /var/www/drupalvm/drupal + Site path : sites/default + File directory path : sites/default/files + Temporary file : /tmp + directory path Active config path : [...] Staging config path : [...] ``` -Drupal VM automatically generates a drush alias file in `~/.drush/drupalvm.aliases.drushrc.php` with an alias for every site you have defined in the `apache_vhosts` variable. +Drupal VM automatically generates a drush alias file in `~/.drush/drupalvm.aliases.drushrc.php` (for Drush < 9.0.0) and `~/.drush/sites/drupalvm.site.yml` (for Drush 9.0.0+) with an alias for every site you have defined in the `apache_vhosts` or `nginx_vhosts` variable. + +If you want to customize the generated alias file you can override the `drush_aliases_host_template` and `drush_aliases_guest_template` variables (or `_yml` variables for Drush 9.0.0+) in your `config.yml`. + +```yaml +drush_aliases_host_template: "{{ config_dir }}/templates/drupalvm.aliases.drushrc.php.j2" +``` + +Eg. to only print the alias for your main domain, and not the subdomain you can override the file using a [Jinja2 child template](http://jinja.pocoo.org/docs/2.9/templates/#child-template). + +```php +{% extends 'templates/drupalvm.aliases.drushrc.php.j2' %} + +{% block aliases %} +{{ alias('drupalvm.test', drupal_core_path) }} +{% endblock %} +``` + +You can disable Drupal VM's automatic Drush alias file management if you want to manage drush aliases on your own. Just set the `configure_drush_aliases` variable in `config.yml` to `false`. + +## Using sql-sync + +_For sql-sync to work between two remotes make sure you are running Drush 8.0.3 or later on your host and your guest machine, as well as 7.1.0 or later on the remote._ + +If you're locked to an older version of Drush, it is likely that Drush will try to run the command from the `@destination` instead of from your host computer, which means you need to move your `@remote` alias to Drupal VM as well. You can place the file in any of the [directories Drush searches](https://github.com/drush-ops/drush/blob/5a1328d6e9cb919a286e70360df159d1b4b15d3e/examples/example.aliases.drushrc.php#L43:L51), for example `/home/vagrant/.drush/.aliases.drushrc.php`. + +If you're still having issues, you can avoid `sql-sync` entirely and pipe the mysqldump output yourself with: + +``` +drush @remote sql-dump | drush @drupalvm.drupalvm sql-cli +``` + +## Running `drush core-cron` as a cron job. + +Using the `drupalvm_cron_jobs` list in `config.yml` you can configure your VM to automatically run cron tasks eg. every 30 minutes. + +```yaml +drupalvm_cron_jobs: + - name: "Drupal Cron" + minute: "*/30" + job: "{{ drush_path }} -r {{ drupal_core_path }} core-cron" +``` + +_Cron jobs are added to the vagrant user's crontab. Keys include name (required), minute, hour, day, weekday, month, job (required), and state._ -You can disable Drupal VM's automatic Drush alias file management if you want to manage drush aliases on your own. Just set the `configure_local_drush_aliases` variable in `config.yml` to `false`. \ No newline at end of file +For a list of available role variables, see the [`geerlingguy.drush` Ansible role's README](https://github.com/geerlingguy/ansible-role-drush#readme). diff --git a/docs/extras/elasticsearch.md b/docs/extras/elasticsearch.md new file mode 100644 index 000000000..798b21641 --- /dev/null +++ b/docs/extras/elasticsearch.md @@ -0,0 +1,24 @@ +[Elasticsearch](https://www.elastic.co/products/elasticsearch) is a search engine based on Lucene. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents. + +To enable Elasticsearch in Drupal VM just make sure `elasticsearch` is in the list of `installed_extras` in your `config.yml`, and when you build Drupal VM, the latest version of Elasticsearch will be installed. + +The URL to connect to the local elasticsearch server (assuming you're using the default `elasticsearch_http_port` of 9200) from Drupal is: + + http://localhost:9200 + +To access Elasticsearch from the host computer requires changing the IP address to listen on a specific interface, or 0.0.0.0 to listen on all interfaces. + + elasticsearch_network_host: 0.0.0.0 + +The Elasticsearch server can then be accessed at the configured domain: + + http://drupalvm.test:9200 + +## Elasticsearch configuration + +You can add configuration for Elasticsearch by setting the appropriate variables inside `config.yml` before you build Drupal VM. + + elasticsearch_network_host: localhost + elasticsearch_http_port: 9200 + +For a list of available role variables, see the [`geerlingguy.elasticsearch` Ansible role's README](https://github.com/geerlingguy/ansible-role-elasticsearch#readme). diff --git a/docs/extras/java.md b/docs/extras/java.md new file mode 100644 index 000000000..31b2fb26f --- /dev/null +++ b/docs/extras/java.md @@ -0,0 +1,4 @@ +Java will automatically be installed if you enabled any of the `installed_extras` that depend on it. +If you have any other use case for installing it, just make sure `java` is in the list of `installed_extras` in your `config.yml`. + +For a list of available role variables, see the [`geerlingguy.java` Ansible role's README](https://github.com/geerlingguy/ansible-role-java#readme). diff --git a/docs/extras/mailhog.md b/docs/extras/mailhog.md index aea4a85dd..700099b58 100644 --- a/docs/extras/mailhog.md +++ b/docs/extras/mailhog.md @@ -1,3 +1,13 @@ -By default, Drupal VM redirects all PHP emails to [MailHog](https://github.com/mailhog/MailHog) (instead of sending them to the outside world). You can access the MailHog UI at `http://drupaltest.dev:8025/` (or whatever domain you have configured in `config.yml`). +By default, Drupal VM redirects all PHP emails to [MailHog](https://github.com/mailhog/MailHog) (instead of sending them to the outside world). You can access the MailHog UI at [http://drupalvm.test:8025/](http://drupalvm.test:8025) (or whatever domain you have configured in `config.yml`). -You can override the default behavior of redirecting email to MailHog by editing or removing the `php_sendmail_path` inside `config.yml`, and you can choose to not install MailHog at all by removing it from `installed_extras` in `config.yml`. \ No newline at end of file +## Disable MailHog + +If you don't want to use MailHog, you can set the following override (back to PHP's default, as defined in the [`geerlingguy.php`](https://github.com/geerlingguy/ansible-role-php#role-variables) role) in your `config.yml` file: + +```yaml +php_sendmail_path: "/usr/sbin/sendmail -t -i" +``` + +After doing this, you can also prevent MailHog's installation by removing `mailhog` from the `installed_extras` list. + +For a list of available role variables, see the [`geerlingguy.mailhog` Ansible role's README](https://github.com/geerlingguy/ansible-role-mailhog#readme). diff --git a/docs/extras/memcached.md b/docs/extras/memcached.md new file mode 100644 index 000000000..409c94170 --- /dev/null +++ b/docs/extras/memcached.md @@ -0,0 +1,17 @@ +[Memcached](https://memcached.org/) is an in-memory caching system, much like [Redis](redis.md). While [Varnish](varnish.md) is generally used to improve performance for anonymous users, `memcached` is used to improve the performance for logged in users. + +To enable Memcached in Drupal VM: + +1. Make sure `memcached` is in the list of `installed_extras` in your `config.yml`. +2. Install the [Memcache API](https://www.drupal.org/project/memcache) module. +3. Enable the module before you configure it in the next step. +4. Add the following to your `settings.php` + +```php +// Make memcache the default cache class. +$settings['cache']['default'] = 'cache.backend.memcache'; +``` + +There's a lot more configuration available and the best resource is generally the [Memcache API module's README](http://cgit.drupalcode.org/memcache/tree/README.txt?h=8.x-2.x). + +For a list of available role variables, see the [`geerlingguy.memcached` Ansible role's README](https://github.com/geerlingguy/ansible-role-memcached#readme). diff --git a/docs/extras/mysql.md b/docs/extras/mysql.md deleted file mode 100644 index 7deffafc0..000000000 --- a/docs/extras/mysql.md +++ /dev/null @@ -1,22 +0,0 @@ -By default, this VM is set up so you can manage MySQL databases on your own. The default root MySQL user credentials are `root` for username and password, but you can change the password via `config.yml` (changing the `mysql_root_password` variable). I use the [Sequel Pro](http://www.sequelpro.com/) (Mac-only) to connect and manage databases, and Drush to sync databases (sometimes I'll just do a dump and import, but Drush is usually quicker, and is easier to do over and over again when you need it). - -## Connect using phpMyAdmin - -If you have `phpmyadmin` listed as one of the `installed_extras` inside `config.yml`, you can use phpMyAdmin's web-based interface to interact with databases. With Drupal VM running, visit `http://drupaltest.dev/phpmyadmin/`, and log in with `root` as the username and the password you set in `config.yml` (`mysql_root_password`). - -More about how to use phpMyAdmin: [phpMyAdmin documentation](http://docs.phpmyadmin.net/). - -_Note_: If you get the error `#1146 - Table 'phpmyadmin.pma_table_uiprefs' doesn't exist` when browsing tables in phpMyAdmin, please log into the VM using `vagrant ssh`, then run the command `sudo dpkg-reconfigure phpmyadmin`, and follow the onscreen prompts. This error is caused by [a bug in phpMyAdmin's Ubuntu package installation](https://github.com/geerlingguy/ansible-role-phpmyadmin/issues/1#issuecomment-92461536). - -## Connect using Sequel Pro (or a similar client): - - 1. Use the SSH connection type. - 2. Set the following options: - - MySQL Host: `127.0.0.1` - - Username: `root` - - Password: `root` (or the password configured in `config.yml`) - - SSH Host: `192.168.88.88` (or the IP configured in `config.yml`) - - SSH User: `vagrant` - - SSH Key: (browse to your `~/.vagrant.d/` folder and choose `insecure_private_key`) - -You should be able to connect as the root user and add, manage, and remove databases and users. \ No newline at end of file diff --git a/docs/extras/newrelic.md b/docs/extras/newrelic.md new file mode 100644 index 000000000..522e4c264 --- /dev/null +++ b/docs/extras/newrelic.md @@ -0,0 +1,23 @@ +The [New Relic PHP agent](https://docs.newrelic.com/docs/agents/php-agent/getting-started/new-relic-php) monitors your application to help you identify and solve performance issues. + +## Getting Started - Installing Prerequisites + +To make New Relic available globally for all your projects within Drupal VM, make the following changes inside `config.yml`, then run `vagrant up` (or `vagrant provision` if the VM is already built): + +```yaml +# Make sure newrelic is not commented out in the list of installed_extras: +installed_extras: + [...] + - newrelic + [...] + +# Set vars for your New Relic account: +# `newrelic` must be in installed_extras for this to work. +newrelic_license_key: yourkey +# Customize any additional vars relevant to your project needs. +# See all vars: https://github.com/weareinteractive/ansible-newrelic#variables +``` + +See [New Relic for PHP](https://docs.newrelic.com/docs/agents/php-agent/getting-started/new-relic-php) for help getting started. + +For a list of available role variables, see the [`weareinteractive.newrelic` Ansible role's README](https://github.com/weareinteractive/ansible-newrelic#readme). diff --git a/docs/extras/nodejs.md b/docs/extras/nodejs.md new file mode 100644 index 000000000..ccef453e5 --- /dev/null +++ b/docs/extras/nodejs.md @@ -0,0 +1,30 @@ +Node.js is used for many different purposes, but with Drupal, it is most often used as part of a toolset for Front End development or certain CI tasks. + +Drupal VM includes built-in support for Node.js—all you need to do is make sure `nodejs` is listed in the list of `installed_extras` inside `config.yml` before your provision Drupal VM. + +## Choosing a version of Node.js + +You can choose a version of Node.js to install using the `nodejs_version` variable in `config.yml`. See the [`geerlingguy.nodejs` Ansible role's README](https://github.com/geerlingguy/ansible-role-nodejs#readme) for all the currently-available versions for your OS. + +```yaml +nodejs_version: "0.12" +``` + +## Installing global packages via NPM + +To install packages globally, you can add them to the list of `nodejs_npm_global_packages` in `config.yml`. As an example, many developers use `phantomjs` as a ghost web driver for Behat tests inside Drupal VM. To install it globally, add it to the list: + +```yaml +nodejs_npm_global_packages: + - phantomjs +``` + +You can even specify a specific version to install: + +```yaml +nodejs_npm_global_packages: + - name: phantomjs + version: 2.1.7 +``` + +For a list of available role variables, see the [`geerlingguy.nodejs` Ansible role's README](https://github.com/geerlingguy/ansible-role-nodejs#readme). diff --git a/docs/extras/pimpmylog.md b/docs/extras/pimpmylog.md deleted file mode 100644 index 1abed918a..000000000 --- a/docs/extras/pimpmylog.md +++ /dev/null @@ -1,16 +0,0 @@ -[Pimp my Log](http://pimpmylog.com/) is a PHP-based web GUI for viewing log files on a given server. By default, it is installed on Drupal VM, and you can access it at the URL `http://local.pimpmylog.com/` (as long as you have a hosts entry for that URL pointing at Drupal VM's IP address!). - -By default, it will find the default Apache 2 `access.log` and `error.log` files, but it will not find other logs, like MySQL or extra Apache virtualhost logs. - -When configuring Pimp my Log (on the first visit to the `local.pimpmylog.com` URL), you can add extra paths in the UI, or you can add them after the fact by manually editing the configuration file, which by default is stored at `/usr/share/php/pimpmylog/config.user.php`. You can also delete that file and re-configure Pimp my Log via the web UI. - -Some log files you may be interested in monitoring: - - - `/var/log/apache2/access.log` - - `/var/log/apache2/error.log` (this log will show Apache and PHP notices/warnings/errors) - - `/var/log/apache2/other_vhosts_access.log` - - `/var/log/mysql.err` (MySQL error log) - - `/var/log/mysql-slow.log (MySQL slow query log) - - `/var/log/syslog` (enable the Drupal syslog module to route watchdog log entries to this file) - -For MySQL logs, you might want to read through the PML docs on [MySQL](http://support.pimpmylog.com/kb/softwares/mysql). \ No newline at end of file diff --git a/docs/extras/redis.md b/docs/extras/redis.md new file mode 100644 index 000000000..2550860fa --- /dev/null +++ b/docs/extras/redis.md @@ -0,0 +1,17 @@ +[Redis](https://redis.io/) is an in-memory caching system, much like [Memcached](memcached.md). While [Varnish](varnish.md) is generally used to improve performance for anonymous users, `redis` is used to improve the performance for logged in users. + +To enable Redis in Drupal VM: + +1. Make sure `redis` is in the list of `installed_extras` in your `config.yml`. +2. Install the [Redis](https://www.drupal.org/project/redis) module. +3. Enable the module before you configure it in the next step. +4. Add the following to your `settings.php` + +```php +// Make redis the default cache class. +$settings['cache']['default'] = 'cache.backend.redis' +``` + +There's a lot more configuration available and the best resource is generally the [Redis module's README](http://cgit.drupalcode.org/redis/tree/README.md). + +For a list of available role variables, see the [`geerlingguy.redis` Ansible role's README](https://github.com/geerlingguy/ansible-role-redis#readme). diff --git a/docs/extras/ruby.md b/docs/extras/ruby.md new file mode 100644 index 000000000..c4522b185 --- /dev/null +++ b/docs/extras/ruby.md @@ -0,0 +1,15 @@ +Ruby is used for many different purposes, but with Drupal, it is most often used as part of a toolset for Front End development or certain CI tasks. + +Drupal VM includes built-in support for Ruby—all you need to do is make sure `ruby` is listed in the list of `installed_extras` inside `config.yml` before your provision Drupal VM. + +## Installing gems + +To install ruby gems, you can add them to the list of `ruby_install_gems` in `config.yml`. + +```yaml +ruby_install_gems: + - sass + - compass +``` + +For a list of available role variables, see the [`geerlingguy.ruby` Ansible role's README](https://github.com/geerlingguy/ansible-role-ruby#readme). diff --git a/docs/extras/selenium.md b/docs/extras/selenium.md new file mode 100644 index 000000000..80f725b14 --- /dev/null +++ b/docs/extras/selenium.md @@ -0,0 +1,105 @@ +Behat is an open source behavior-driven development tool for PHP. You can use Behat to build and run automated tests for site functionality on your Drupal sites, and Drupal VM has excellent built-in support for Behat, using Selenium to run tests in a headless instance of either Google Chrome (default) or Firefox. + +## Getting Started - Installing Prerequisites + +To make Behat available globally for all your projects within Drupal VM, make the following changes inside `config.yml`, then run `vagrant up` (or `vagrant provision` if the VM is already built): + +```yaml +# Make sure selenium is not commented out in the list of installed_extras: +installed_extras: + [...] + - selenium + [...] + +# Add the following package to composer_global_packages or your Drupal project: +composer_global_packages: + - { name: drupal/drupal-extension, release: '*' } +``` + +After Drupal VM is finished provisioning, you should be able to log in and run the following command to make sure Behat is installed correctly: + +``` +$ behat --version +behat version 3.0.15 +``` + +_You can also include `drupal/drupal-extension` directly in your project's `composer.json` file, and install the dependencies per-project._ + +## Setting up Behat for your project + +Using the default Drupal site as an example (it's installed in `/var/www/drupalvm/drupal` by default, and is shared to the `./drupal` folder inside the drupal-vm directory on your host machine), the following steps will help you get your first Behat tests up and running! + + 1. Create a `behat.yml` file inside the docroot of your site (e.g. create this file alongside the rest of the Drupal codebase at `/var/www/drupalvm/drupal/behat.yml`), with the following contents: + + default: + suites: + web_features: + paths: [ "%paths.base%/features/web" ] + contexts: + - WebContext + - Drupal\DrupalExtension\Context\DrupalContext + - Drupal\DrupalExtension\Context\MinkContext + - Drupal\DrupalExtension\Context\MessageContext + - Drupal\DrupalExtension\Context\DrushContext + extensions: + Behat\MinkExtension: + goutte: ~ + javascript_session: selenium2 + selenium2: + wd_host: http://drupalvm.test:4444/wd/hub + base_url: http://drupalvm.test + Drupal\DrupalExtension: + blackbox: ~ + api_driver: 'drupal' + drupal: + drupal_root: '/var/www/drupalvm/drupal/web' + region_map: + content: "#content" + + 2. Log into Drupal VM with `vagrant ssh`, change directory to the Drupal site root (`cd /var/www/drupalvm/drupal`), then run `behat --init` to initialize the `features` folder where you will place test cases. + 3. From either inside the VM or on the host machine, open up the new `features/web` folder Behat just created. Inside _that_ folder, create `HomeContent.feature` with the following contents: + + Feature: Test DrupalContext + In order to prove Behat is working correctly in Drupal VM + As a developer + I need to run a simple interface test + + Scenario: Viewing content in a region + Given I am on the homepage + Then I should see "No front page content has been created yet" in the "content" + + 4. Now, inside Drupal VM, change directory to `/var/www/drupalvm/drupal` again, and run the command `behat` (which runs all the tests you've created—which should just be one so far). + +If everything was done correctly, you should see: + +```console +$ behat +Feature: Test DrupalContext + In order to prove Behat is working correctly in Drupal VM + As a developer + I need to run a simple interface test + + Scenario: Viewing content in a region # features/drupal/HomeContent.feature:6 + Given I am on the homepage # Drupal\DrupalExtension\Context\MinkContext::iAmOnHomepage() + Then I should see "No front page content has been created yet" in the "content" # Drupal\DrupalExtension\Context\MinkContext::assertRegionText() + +1 scenario (1 passed) +2 steps (2 passed) +0m0.56s (26.48Mb) +``` + +Hooray! Now you're ready to get started testing ALL THE THINGS! Check out the following resources for more information about Behat and Drupal: + + - [Behat 3.0 Documentation](http://behat.readthedocs.org/en/v3.0/) + - [Drupal Extension Documentation](https://behat-drupal-extension.readthedocs.org/en/3.0/) + +## Debugging issues + +There are many different ways you can run Behat tests via PhantomJS and other drivers, and some people have encountered issues and workarounds with different approaches. Here are some relevant issues you can read through for more background: + + - [Selenium Questions](https://github.com/geerlingguy/drupal-vm/issues/367) + - [Trying to achieve a Visual Regression Testing Strategy](https://github.com/geerlingguy/drupal-vm/issues/421) + +Also, see Acquia's [BLT](https://github.com/acquia/blt) project for a good example of Behat test integration with Drupal VM. + +For a list of available role variables, see the [`arknoll.selenium` Ansible role's README](https://github.com/arknoll/ansible-role-selenium#readme). diff --git a/docs/extras/solr.md b/docs/extras/solr.md index 73119dfe7..a1f8b6d56 100644 --- a/docs/extras/solr.md +++ b/docs/extras/solr.md @@ -6,12 +6,27 @@ The URL to connect to the local solr server (assuming you're using the default ` http://localhost:8983/solr/collection1 -This will connect to the default search core (`collection1`) set up by Solr. If you are using a multisite installation and want to have a search core per Drupal site, you can add more cores through Apache Solr's admin interface (visit `http://drupaltest.dev:8983/solr/`), then connect to each core by adding the core name to the end of the above URL (e.g. `core2` would be `http://localhost:8983/solr/core2`). +This will connect to the default search core (`collection1`) set up by Solr. If you are using a multisite installation and want to have a search core per Drupal site, you can add more cores through Apache Solr's admin interface (visit `http://drupalvm.test:8983/solr/`), then connect to each core by adding the core name to the end of the above URL (e.g. `core2` would be `http://localhost:8983/solr/core2`). + +## Using Different Solr versions + +Drupal VM installs Apache Solr 5.x by default, but you can use 6.x, 4.x, or other versions instead. To do this, [see the version-specific playbook examples](https://github.com/geerlingguy/ansible-role-solr/tree/master/molecule/default) in the `geerlingguy.solr` role. + +One important note: If you use Solr 6.x or later, you need to make sure your VM has Java 8+. Some older base OSes only install Java 7. To install Java 8, see the `geerlingguy.java` role examples for [installing Java 8 on RHEL/CentOS or Ubuntu < 16.04](https://github.com/geerlingguy/ansible-role-java#example-playbook-install-openjdk-8). ## Configuring the Solr search core for Drupal -Before Drupal content can be indexed correctly into Apache Solr, you will need to copy the Drupal Apache Solr Search or Search API Apache Solr configuration into place, and restart Apache Solr. This process will soon be automated, but for now, please perform the steps outlined in step 5 in this blog post (which should work with Drupal VM): [Solr for Drupal Developers, Part 3: Testing Solr locally](http://www.midwesternmac.com/blogs/jeff-geerling/solr-drupal-developers-part-3). +Before Drupal content can be indexed correctly into Apache Solr, you will need to copy the Drupal Apache Solr Search or Search API Apache Solr configuration into place, and restart Apache Solr. Drupal VM comes with an example post provision script for automating this. Simply add it to `post_provision_scripts`: + +```yaml +post_provision_scripts: + - "../examples/scripts/configure-solr.sh" +``` + +Note that for Drupal 8, this script will create a new search core named `d8` (rather than modifying the default core `collection1`). ## Extra Solr configuration -You can add extra configuration for Solr, like the minimum and maximum memory allocation for the JVM (`solr_xms` and `solr_xmx`), and even the `solr_version`, by setting the appropriate variables inside `config.yml` before you build Drupal VM. \ No newline at end of file +You can add extra configuration for Solr, like the minimum and maximum memory allocation for the JVM (`solr_xms` and `solr_xmx`), and even the `solr_version`, by setting the appropriate variables inside `config.yml` before you build Drupal VM. + +For a list of available role variables, see the [`geerlingguy.solr` Ansible role's README](https://github.com/geerlingguy/ansible-role-solr#readme). diff --git a/docs/extras/syncing-folders.md b/docs/extras/syncing-folders.md deleted file mode 100644 index 65288e9a7..000000000 --- a/docs/extras/syncing-folders.md +++ /dev/null @@ -1,74 +0,0 @@ -You can share folders between your host computer and the VM in a variety of ways; the most commonly-used method is an NFS share. If you use Windows and encounter any problems with NFS, try switching to `smb`. The `example.config.yml` file contains an example `nfs` share that would sync the folder `~/Sites/drupalvm` on your host into the `/var/www` folder on Drupal VM. - -If you want to use a different synced folder method (e.g. `smb`), you can change `type` to: - -```yaml -vagrant_synced_folders: - - local_path: ~/Sites/drupalvm - destination: /var/www - id: drupal - type: smb -``` - -You can add as many synced folders as you'd like, and you can configure [any type of share](https://docs.vagrantup.com/v2/synced-folders/index.html) supported by Vagrant; just add another item to the list of `vagrant_synced_folders`. - -## Synced Folder Performance - -Using different synced folder mechanisms can have a dramatic impact on your Drupal site's performance. Please read through the following blog posts for a thorough overview of synced folder performance: - - - [Comparing filesystem performance in Virtual Machines](http://mitchellh.com/comparing-filesystem-performance-in-virtual-machines) - - [NFS, rsync, and shared folder performance in Vagrant VMs](http://www.midwesternmac.com/blogs/jeff-geerling/nfs-rsync-and-shared-folder) - -Generally speaking: - - - NFS offers a decent tradeoff between performance and ease of use - - SMB offers a similar tradeoff, but is a bit slower than NFS - - Rsync offers the best performance inside the VM, but sync is currently one-way-only (from host to VM), which can make certain development workflows burdensome - - Native shared folders offer abysmal performance; only use this mechanism as a last resort! - -## Synced Folder Troubleshooting - -There are a number of issues people encounter with synced folders from time to time. The most frequent issues are listed below with possible solutions: - -### Using Native Synced Folders - -You can use a native synced folder, which should work pretty flawlessly on any platform, but with a potential serious performance downside (compared to other synced folder methods). Just set `type` to `""`, and you can even put the synced folder inside the drupal-vm folder using a relative path, like: - -```yaml -vagrant_synced_folders: - - local_path: docroot - destination: /var/www/docroot - id: drupal - type: "" - create: true -``` - -See [this issue](https://github.com/geerlingguy/drupal-vm/issues/67) for more information. - -### VirtualBox Guest Additions out of date - -If you get errors when running `vagrant up` stating that your guest additions are out of date, you can fix this easily by installing the `vagrant-vbguest` plugin. Run the following command in the drupal-vm folder: `vagrant plugin install vagrant-vbguest`. - -Otherwise, you will need to make sure you're using the officially supported `geerlingguy/ubuntu1404` box, which should _generally_ have the latest (or near-latest) guest additions installed. If not, please open an issue in the upstream project for building the base box: [`packer-ubuntu-1404`](https://github.com/geerlingguy/packer-ubuntu-1404). - -### Permissions-related errors - -If you're encountering errors where Drupal or some other software inside the VM is having permissions issues creating or deleting files inside a synced folder, you might need to either make sure the file permissions are correct on your host machine (if a folder is not readable by you, it probably also won't be readable when mounted via NFS!), or add extra configuration to the synced folders item inside the Vagrantfile (if using a sync method like `rsync`): - -``` -owner: "vagrant", -group: "www-data", -mount_options: ["dmode=775,fmode=664"] -``` - -See [this issue](https://github.com/geerlingguy/drupal-vm/issues/66) for more details. - -### VirtualBox Symbolic Links - -When using native VirtualBox shares, VirtualBox does not allow guest VMs to create symbolic links on synced folders for security reasons. On CentOS this prevents apache from installing since it will try to make a symlink inside `/var/www/` You can change the Drupal synced_folder to `/var/www/drupal` and the `drupal_core_path` to `/var/www/drupal/docroot` to work around this. - -There are many other potential [solutions](https://www.google.com/search?q=SharedFoldersEnableSymlinksCreate) available on the Internet. - -### Other NFS-related errors - -If you're having other weird issues, and none of the above fixes helps, you might want to try a different synced folder method (see top of this page), or something like File Conveyor or a special rsync setup (see [here](http://wolfgangziegler.net/auto-rsync-local-changes-to-remote-server#comments) for some examples). \ No newline at end of file diff --git a/docs/extras/tideways.md b/docs/extras/tideways.md new file mode 100644 index 000000000..2b4216ff2 --- /dev/null +++ b/docs/extras/tideways.md @@ -0,0 +1,23 @@ +The [Tideways XHProf Extension](https://github.com/tideways/php-xhprof-extension) is a well-maintained fork of the XHProf code and works with either the [XHProf](https://www.drupal.org/project/xhprof) or [Tideways](https://www.drupal.org/project/tideways) Drupal modules to profile page views. Results can be viewed with these modules or the native XHProf UI. + +Note that the Tideways project [recently split](https://tideways.com/profiler/blog/releasing-new-tideways-xhprof-extension) into a proprietary extension and a stand-alone fork of XHProf. DrupalVM (and this document) specifically uses the latter (the "Tideways XHProf Extension"). + +To use Tideways XHProf make sure `tideways` is in the list of `installed_extras`. + +**Note**: You should only enable one code profiler at a time—e.g. when using [Blackfire](blackfire.md), disable [XHProf](xhprof.md), [Tideways](tideways.md) and [XDebug](xdebug.md). + +### Profiling with the XHProf Drupal Module + +To enable profiling of Drupal pages using the Tideways PHP Extension, follow the directions for [configuring the XHProf and the XHProf module](xhprof.md#xhprof-module), but choose the _Tideways_ extension under the _Profiling settings_ section. + +### Profiling with the Tideways module + +Instructions for profiling with the Tideways module through the [tideways.io](https://tideways.io) service will be added after the following issue is resolved: [Can't install latest dev release on 8.x](https://www.drupal.org/node/2843481). + +For a list of available role variables, see the [`geerlingguy.php-tideways` Ansible role's README](https://github.com/geerlingguy/ansible-role-php-tideways#readme). + +### Viewing results + +As with the XHProf extension, you can view callgraphs (and a listing of all stored runs) using Drupal VM's own XHProf UI installation by visiting [http://xhprof.drupalvm.test/](http://xhprof.drupalvm.test) and clicking on the relevant run, then clicking the _[View Full Callgraph]_ link. + +Note that if you have overridden DrupalVM's [default set of Apache vHosts](https://github.com/geerlingguy/drupal-vm/blob/master/default.config.yml), you will need to specifically add a vHost for the XHProf dashboard. diff --git a/docs/extras/upload-progress.md b/docs/extras/upload-progress.md new file mode 100644 index 000000000..da364b98d --- /dev/null +++ b/docs/extras/upload-progress.md @@ -0,0 +1,3 @@ +To enable the Upload progress PHP extension make sure `upload-progress` is listed in the list of `installed_extras` inside `config.yml` before your provision Drupal VM. + +For a list of available role variables, see the [`thom8.php-upload-progress` Ansible role's README](https://github.com/thom8/ansible-role-php-upload-progress#readme). diff --git a/docs/extras/varnish.md b/docs/extras/varnish.md index 95e1be858..2176186c0 100644 --- a/docs/extras/varnish.md +++ b/docs/extras/varnish.md @@ -2,7 +2,7 @@ To enable Varnish, make sure `varnish` is in the list of your `installed_extras` in `config.yml`, and run `vagrant provision`. -There are a few varnish configuration variables further down in `example.config.yml` that you may wish to configure. You can use your own `.vcl` file template (instead of the generic Drupal 7-focused generic one) by editing the `varnish_default_vcl_template_path`, and you can use a different port for Varnish by changing `varnish_listen_port`. +There are a few varnish configuration variables further down in `default.config.yml` that you may wish to configure. You can use your own `.vcl` file template (instead of the default generic Drupal-focused one) by editing the `varnish_default_vcl_template_path`, and you can use a different port for Varnish by changing `varnish_listen_port`. If you'd like to use Varnish on port 80, and switch Apache to a different backend port, you can do so pretty easily; just make sure you have the following values set in your `config.yml` file, and run `vagrant provision` to have Ansible make the necessary changes: @@ -25,8 +25,40 @@ In order for Varnish to actually do anything helpful (instead of just pass throu You will also need to make a few small changes to your site's `settings.php` configuration to make Drupal work correctly behind a reverse proxy like Varnish: ```php -$conf['reverse_proxy'] = TRUE; -$conf['reverse_proxy_addresses'] = array('127.0.0.1'); +$settings['reverse_proxy'] = TRUE; +$settings['reverse_proxy_addresses'] = array('127.0.0.1'); ``` -If you don't set these values, Drupal will think all requests are coming from `127.0.0.1`. There are other settings you can change to make Drupal not store copies of cached pages in the Database (since Varnish is caching everything, this is redundant), but those other settings are not covered here. \ No newline at end of file +If you don't set these values, Drupal will think all requests are coming from `127.0.0.1`. There are other settings you can change to make Drupal not store copies of cached pages in the Database (since Varnish is caching everything, this is redundant), but those other settings are not covered here. + +## Extending the base `drupalvm.vcl.j2` template + +If you can't customize via variables because an option isn't exposed, you can extend the base `drupalvm.vcl.j2` through [Jinja2 template inheritance](http://jinja.pocoo.org/docs/2.9/templates/#template-inheritance). + +```yaml +varnish_default_vcl_template_path: "{{ config_dir }}/templates/drupalvm.vcl.j2" +``` + +Either copy the `drupalvm.vcl.j2` and modify it to your liking, or extend it and override the blocks you need to adjust. + +_If you extend Drupal VM's provided base template, the path referenced should to be relative to playbook.yml._ + +``` +{% extends 'templates/drupalvm.vcl.j2' %} + +{% block backend -%} +{{ super() }} +.connect_timeout = 1s; +{% endblock %} + +{% block vcl_deliver -%} +unset resp.http.X-Url; +unset resp.http.X-Host; +unset resp.http.Purge-Cache-Tags; +# Do not set X-Varnish-Cache headers. +{% endblock %} +``` + +The [`{{ super() }}` Jinja2 function](http://jinja.pocoo.org/docs/2.9/templates/#super-blocks) returns the original block content from the base template. + +For a list of available role variables, see the [`geerlingguy.varnish` Ansible role's README](https://github.com/geerlingguy/ansible-role-varnish#readme). diff --git a/docs/extras/xdebug.md b/docs/extras/xdebug.md index 0a6adb3f5..4a9bfa5d9 100644 --- a/docs/extras/xdebug.md +++ b/docs/extras/xdebug.md @@ -1,4 +1,4 @@ -XDebug is a useful tool for debugging PHP applications, but it uses extra memory and CPU for every request, so is disabled by default. +[XDebug](https://xdebug.org/) is a useful tool for debugging PHP applications, but it uses extra memory and CPU for every request, so is disabled by default. To enable XDebug, do the following in `config.yml`: @@ -7,7 +7,7 @@ To enable XDebug, do the following in `config.yml`: If you don't need to use XDebug, you can comment it out or remove it from `installed_extras` before you `vagrant up` Drupal VM. -## PHPStorm and XDebug with Drupal VM +### PHPStorm and XDebug with Drupal VM To use XDebug with PHPStorm, change the `php_xdebug_idekey` variable as shown below in `config.yml`, and then run `vagrant provision` to reconfigure the VM: @@ -15,10 +15,91 @@ To use XDebug with PHPStorm, change the `php_xdebug_idekey` variable as shown be php_xdebug_idekey: PHPSTORM ``` -## Sublime Text and XDebug with Drupal VM +### Sublime Text and XDebug with Drupal VM To use XDebug with Sublime Text, change the `php_xdebug_idekey` variable as shown below in `config.yml`, and then run `vagrant provision` to reconfigure the VM: ```yaml php_xdebug_idekey: sublime.xdebug ``` + +To configure a Sublime Text project to use XDebug when debugging, add the following `settings` key to your project's `.sublime-project` file: + +```json + "settings": { + "xdebug": { + "path_mapping": { + "/var/www/projectname/docroot" : "/Users/geerlingguy/Sites/projectname/docroot", + }, + "url": "http://local.projectname.com/", + "super_globals": true, + "close_on_stop": true + } + } +``` + +This assumes you have already installed [SublimeTextXdebug](https://github.com/martomo/SublimeTextXdebug) via Package Control. + +### NetBeans and XDebug with Drupal VM + +To use XDebug with NetBeans, change the `php_xdebug_idekey` variable as shown below in `config.yml`, and then run `vagrant provision` to reconfigure the VM. + +```yaml +php_xdebug_idekey: netbeans-xdebug +``` + +### Atom and XDebug with Drupal VM + +To use XDebug with Atom, change the `php_xdebug_idekey` variable as shown below in `config.yml`, and then run `vagrant provision` to reconfigure the VM. + +```yaml +php_xdebug_idekey: xdebug-atom +``` + +### Eclipse and XDebug with Drupal VM + +To use XDebug with Eclipse, change the `php_xdebug_idekey` variable as shown below in `config.yml`, and then run `vagrant provision` to reconfigure the VM. + +```yaml +php_xdebug_idekey: ECLIPSE_DBGP +``` + +### Visual Studio Code and XDebug with Drupal VM + +To use XDebug with Visual Studio Code, change the `php_xdebug_idekey` variable as shown below in `config.yml`, and then run `vagrant provision` to reconfigure the VM. + +```yaml +php_xdebug_idekey: VSCODE +``` + +### XDebug over SSH/Drush + +As long as `xdebug` is listed in `installed_extras` Drupal VM is configured to accept the `PHP_IDE_CONFIG`, `XDEBUG_CONFIG` and `PHP_OPTIONS` environment variables over SSH and this can be used to set up some IDE's as well as enable XDebug on a per request basis: + +``` +PHP_OPTIONS="-d xdebug.default_enable=1" drush @drupalvm.drupalvm migrate-import +``` + +To send the environment variables when using `vagrant ssh`, [create a `Vagrantfile.local`](../extending/vagrantfile.md) with: + +``` +config.ssh.forward_env = ['PHP_IDE_CONFIG', 'XDEBUG_CONFIG', 'PHP_OPTIONS'] +``` + +And you can run: + +``` +XDEBUG_CONFIG="-d default_enable=1" vagrant ssh -c 'php /var/www/drupalvm/drupal/web/core/scripts/run-tests.sh --url http://drupalvm.test --all' +XDEBUG_CONFIG="-d default_enable=1" vagrant ssh -c 'cd /var/www/drupalvm/drupal/web/core; php ../../vendor/bin/phpunit tests/Drupal/Tests/Core/Password/PasswordHashingTest.php' +``` + +## Profiling code with XDebug + +While most people use XDebug only for debugging purposes, you can also use it for profiling. It's not as commonly used for profiling as either Blackfire or XHProf, but it works! + +**Note**: You should only enable one code profiler at a time—e.g. when using [Blackfire](blackfire.md), disable [XHProf](xhprof.md), [Tideways](tideways.md) and [XDebug](xdebug.md). + +For a list of available role variables, see the [`geerlingguy.php-xdebug` Ansible role's README](https://github.com/geerlingguy/ansible-role-php-xdebug#readme). + + + diff --git a/docs/extras/xhprof.md b/docs/extras/xhprof.md index 1609e1047..2598bad7d 100644 --- a/docs/extras/xhprof.md +++ b/docs/extras/xhprof.md @@ -1,14 +1,20 @@ -As a prerequisite, make sure you have `xhprof` in the `installed_extras` list inside `config.yml` (So the PHP XHProf extension is installed on Drupal VM). +[XHProf](http://xhprof.io/) allows easy code profiling and can be used in many different ways. Ensure `xhprof` is in the list of `installed_extras` inside `config.yml`. -## XHProf module +_Note: XHProf does currently not work with PHP 7.1+. The PHP extension has barely been maintained since Facebook abandoned the project around 2015, so it's difficult to get it running under newer versions of PHP. If you require support for PHP 7.1 or newer, you should use [Tideways](tideways.md) instead._ + +### XHProf module The easiest way to use XHProf to profile your PHP code on a Drupal site is to install the [XHProf](https://www.drupal.org/project/xhprof) module, then in XHProf's configuration (at `/admin/config/development/xhprof`), check the 'Enable profiling of page views and drush requests' checkbox. -The XHProf module doesn't yet include support for callgraphs, but there's an issue to [add callgraph support](https://www.drupal.org/node/1470740). +The XHProf module doesn't include built-in support for callgraphs, but there's an issue to [add callgraph support](https://www.drupal.org/node/1470740). + +You can view callgraphs (and a listing of all stored runs) using Drupal VM's own XHProf installation by visiting [http://xhprof.drupalvm.test/](http://xhprof.drupalvm.test) and clicking on the relevant run, then clicking the _[View Full Callgraph]_ link. -## Devel module (deprecated) +### Devel module (deprecated) The Devel module also *used* to provide XHProf configuration, and setting the options below would allow Devel's XHProf integration to work correctly with Drupal VM's XHProf installation: - **xhprof directory**: `/usr/share/php` - - **XHProf URL**: `http://local.xhprof.com/` (assuming this domain is configured in `apache_vhosts` inside `config.yml`) \ No newline at end of file + - **XHProf URL**: `http://xhprof.drupalvm.test` + +**Note**: You should only enable one code profiler at a time—e.g. when using [Blackfire](blackfire.md), disable [XHProf](xhprof.md), [Tideways](tideways.md) and [XDebug](xdebug.md). diff --git a/docs/getting-started/configure-drupalvm.md b/docs/getting-started/configure-drupalvm.md new file mode 100644 index 000000000..2e068bf3b --- /dev/null +++ b/docs/getting-started/configure-drupalvm.md @@ -0,0 +1,48 @@ +If you only need a simple Drupal VM environment up and running there are no required configurations. The [configurations used by default are listed in `default.config.yml`](https://github.com/geerlingguy/drupal-vm/blob/master/default.config.yml) and you can override them with a number of optional configuration files. + +_Note: The merge of variables in these files is shallow, if you want to override a single item in a list, you will need to re-define all items in that list._ + +Configurations files are read in the following order: + +#### 1. default.config.yml + +Drupal VM's default configurations which you should not edit directly. + +#### 2. config.yml + +The main configuration file of a project. Commonly this is a copy of `default.config.yml` with the values tweaked to your own project. For an easier upgrade path you would only set the values you are actually overriding. + +```yaml +vagrant_box: geerlingguy/centos8 +vagrant_hostname: my-custom-site.test +vagrant_machine_name: my_custom_site + +php_version: "7.3" +``` + +#### 3. vagrant.config.yml + +Environment specific overrides. When you run Drupal VM through _Vagrant_, the environment will be set to `vagrant` and this file is loaded when available. If you're doing something more advanced, such as running Drupal VM on a [production environment](../other/production.md), you can use a different environment configuration file, eg `prod.config.yml`. + +_Note: In addition to the variables listed in `default.config.yml`, you can also override the variables set by any of the ansible roles. In the "Installed extras" section of this documentation, each role has a link to the available variables._ + +#### 4. local.config.yml + +Local development overrides. Commonly this file is ignored from VCS so that each team member can make local customizations. + +```yaml +# Increase the memory available to your Drupal site. +vagrant_memory: 1536 +php_memory_limit: "512M" + +# Override the synced folders to use rsync instead of NFS. +vagrant_synced_folders: + - local_path: . + destination: /var/www/drupalvm + type: rsync + create: true +``` + +## Additional resources + +- Jeff Geerling's DrupalDC talk "[Drupal VM Tips and Tricks for Drupal 8 development](https://www.youtube.com/watch?v=_wV6MDsT42Y)" diff --git a/docs/getting-started/installation-linux.md b/docs/getting-started/installation-linux.md new file mode 100644 index 000000000..12e4c9fb9 --- /dev/null +++ b/docs/getting-started/installation-linux.md @@ -0,0 +1,70 @@ +Please read through the [Quick Start Guide in the README](https://github.com/geerlingguy/drupal-vm#quick-start-guide) to get started. + +For a quick introduction to setting up Drupal VM, the [macOS video tutorial](installation-macos.md) applies somewhat to Linux as well. + +There are a few caveats when using Drupal VM on Linux, and this page will try to identify the main gotchas or optimization tips for those wishing to use Drupal VM on a Linux host. + +## Platform-specific Install Instructions + +Always make sure your workstation is up to date (e.g. `apt-get update && apt-get upgrade` on Debian-like systems, or `dnf upgrade` or `yum upgrade` on Fedora/RedHat-like systems). There are sometimes bugs in the base OS packages (e.g. [this NFS-related bug](https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1508510)) that can be resolved by a simple upgrade. + +### Ubuntu + +Some older Ubuntu Desktop installations don't include NFS support by default, so if you get a message like `It appears your machine doesn't support NFS`, then you should do the following to install NFS server: `sudo apt-get install -y nfs-server`. + +### Fedora + +Under Fedora, you might encounter a message like the following upon the first time you use VirtualBox or Vagrant: + +``` +$ vagrant status +VirtualBox is complaining that the kernel module is not loaded. Please +run `VBoxManage --version` or open the VirtualBox GUI to see the error +message which should contain instructions on how to fix this error. +``` + +In this case, you need to install your system's appropriate kernel module, and you'll also need to install `gcc` and run a specific VirtualBox installation script (or reinstall VirtualBox entirely) so the kernel module is loaded correctly. Do the following: + + 1. `sudo dnf install "kernel-devel-uname-r == $(uname -r)"` + 2. `sudo dnf install gcc` + 3. `sudo /var/lib/vboxdrv.sh setup` + +Periodically, when you upgrade your system's Linux kernel, you might need to run steps 2 and 3 above again, or you can uninstall and reinstall VirtualBox (e.g. `sudo dnf remove VirtualBox && sudo dnf install VirtualBox`). + +## Troubleshooting Vagrant Synced Folders + +Most issues have to do synced folders. These are the most common ones: + +### 'Mounting NFS shared folders...' hangs + +There are a few different reasons this particular problem can occur. You may run into the error below during `vagrant up`: + +``` +The following SSH command responded with a non-zero exit status. +Vagrant assumes that this means the command failed! + +mount -o '' 192.168.88.1:'/Users/myusername/Sites/drupalvm' /var/www/drupalvm + +Stdout from the command: + + + +Stderr from the command: + +stdin: is not a tty +mount.nfs: Connection timed out +``` + +If the directory you are trying to mount is within an encrypted folder or volume, NFS will very often fail with the above message as well as `exportfs: /home/myusername/Sites/drupalvm does not support NFS export`. There is no workaround other than sharing a directory that is not encrypted. + +If encryption is not the issue then it's likely that either NFS isn't running correctly on your host, certain ports or protocols are being blocked by the system firewall, or you need to add additional mount options to your `vagrant_synced_folders` configuration. Try the following fixes: + + 1. On Ubuntu, if you get a message like `It appears your machine doesn't support NFS`, run `sudo apt-get install -y nfs-server`. + 1. Make sure the `vboxnet` interfaces are not being blocked by your system firewall. For Fedora (and many flavors of Linux), check out this guide for more: [Get Vagrant's NFS working under Fedora 20](https://web.archive.org/web/20150706105420/http://blog.bak1an.so/blog/2014/03/23/fedora-vagrant-nfs/). + 1. Add `mount_options: ['vers=3']` to your synced folder definition in config.yml after the other options like `local_path`, `destination`, and `type`. + +After attempting any of the above fixes, run `vagrant reload --provision` to restart the VM and attempt mounting the synced folder again, or `vagrant destroy -f && vagrant up` to rebuild the VM from scratch. + +## Intel VT-x virtualization support + +On some laptops, Intel VT-x virtualization (which is built into most modern Intel processors) is enabled by default. This allows VirtualBox to run virtual machines efficiently using the CPU itself instead of software CPU emulation. If you get a message like "VT-x is disabled in the bios for both all cpu modes" or something similar, you may need to enter your computer's BIOS or UEFI settings and enable this virtualization support. diff --git a/docs/getting-started/installation-macos.md b/docs/getting-started/installation-macos.md new file mode 100644 index 000000000..85d3787d2 --- /dev/null +++ b/docs/getting-started/installation-macos.md @@ -0,0 +1,9 @@ +Please read through the [Quick Start Guide](https://github.com/geerlingguy/drupal-vm#quick-start-guide) to get started. + + + +_In this quick overview, Jeff Geerling will show you where you can learn more about Drupal VM, then show you a simple Drupal VM setup._ + +## NFS Timeout on Big Sur + +If you are using NFS shares on macOS Big Sur, and you have problems with the NFS mount going away, please set `vagrant_nfs_fix_enabled: true` in your `config.yml`. diff --git a/docs/getting-started/installation-windows.md b/docs/getting-started/installation-windows.md new file mode 100644 index 000000000..712af9fbd --- /dev/null +++ b/docs/getting-started/installation-windows.md @@ -0,0 +1,77 @@ +Please read through the [Quick Start Guide in the README](https://github.com/geerlingguy/drupal-vm#quick-start-guide) to get started. + + + +_In this video, Jeff Geerling walks through setting up a Drupal 8 website on Windows 10 using Drupal VM 3. Note that Drupal VM has changed a bit in versions 4+, and one major change is the default URL for Drupal VM is now **drupalvm.test** (not **drupalvm.dev** as mentioned in the video)._ + +There are a few caveats when using Drupal VM on Windows, and this page will try to identify the main gotchas or optimization tips for those wishing to use Drupal VM on a Windows host. + +## Windows Subsystem for Linux / Ubuntu bash + +If you are running Windows 10 (Anniversary edition) or later, you can install the Windows Subsytem for Linux, which allows you to install an Ubuntu-based CLI inside of Windows. With this installed, you can then manage and run Drupal VM inside the Linux-like environment. Follow these steps to use Drupal VM in the WSL: + + 1. Install Vagrant and VirtualBox in Windows (links in the [Drupal VM Quick Start Guide](https://github.com/geerlingguy/drupal-vm#quick-start-guide)). + 2. [Install/Enable the Windows Subsystem for Linux](https://msdn.microsoft.com/en-us/commandline/wsl/install_guide). + 1. Create an admin account for the Ubuntu Bash environment when prompted. + 3. In a local copy of Drupal VM (downloaded or Git cloned into a path that's in the Windows filesystem, e.g. `/mnt/c/Users/yourusername/Sites/drupal-vm`), run `wrun vagrant up`. + +If you need to run any other `vagrant` commands (with the exception of `vagrant ssh`—for now, that must be run in a different environment; see [Vagrant: Use Linux Subsystem on Windows](https://github.com/mitchellh/vagrant/issues/7731)), you can do so by prefixing them with `wrun`. + +> Note: using `wrun`, interactive prompts don't seem to work (e.g. if you run `vagrant destroy` without `-f`, you have to Ctrl-C out of it because it just hangs). +> +> Note 2: that the WSL is still in beta, and tools like `cbwin` are still undergoing rapid development, so some of these instructions are subject to change! + +## Command line environment + +If you're not on Windows 10, or if you don't want to install the WSL, you can use PowerShell, Git Bash, Git Shell, or other PowerShell-based environments with Drupal VM and Vagrant; however you might want to consider using a more POSIX-like environment so you can more easily work with Drupal VM: + + - [Cmder](http://cmder.net/) includes built-in git and SSH support, so you can do most things that you need without any additional plugins. + - [Cygwin](https://www.cygwin.com/) allows you to install a large variety of linux packages inside its bash environment, though it can be a little more tricky to manage and is less integrated into the Windows environment. + +## Troubleshooting Vagrant Synced Folders + +Most issues have to do synced folders. These are the most common ones: + +_Read the following to [improve the performance of synced folders by using NFS, samba or rsync](../other/performance.md#improving-performance-on-windows)._ + +### Symbolic Links + +Creating symbolic links in a shared folder will fail with a permission or protocol error. + +There are two parts to this: + + 1. VirtualBox does not allow guest VMs to create symlinks in synced folders by default. + 2. Windows does not allow the creation of symlinks unless your local policy allows it; see [TechNet article](https://technet.microsoft.com/en-us/library/dn221947%28v=ws.10%29.aspx). Even if local policy allows it, many users experience problems in the creation of symlinks. + +Using Ubuntu bash under Windows 10 _can_ make this easier, but there are still issues when creating and managing symlinks between the bash environment and the guest Vagrant operating system. + +### Git and File permissions + +If you're using a synced folder for your project, you should choose to either work _only_ inside the VM, or _only_ on the host machine. Don't commit changes both inside the VM and on the host unless you know what you're doing and have Git configured properly for Unix vs. Windows line endings. File permissions and line endings can be changed in ways that can break your project if you're not careful! + +You should probably disable Git's `fileMode` option inside the VM and on your host machine if you're running Windows and making changes to a Git repository: + + git config core.fileMode false + +### "Authentication failure" on vagrant up + +Some Windows users have reported running into an issue where an authentication failure is reported once the VM is booted (e.g. `drupalvm: Warning: Authentication failure. Retrying...` — see [#170](https://github.com/geerlingguy/drupal-vm/issues/170)). To fix this, do the following: + + 1. Delete `~/.vagrant.d/insecure_private_key` + 2. Run `vagrant ssh-config` + 3. Restart the VM with `vagrant reload` + +### Windows 7 requires PowerShell upgrade + +If you are running Windows 7 and `vagrant up` hangs, you may need to upgrade PowerShell. Windows 7 ships with PowerShell 2.0, but PowerShell 3.0 or higher is required. For Windows 7, you can upgrade to PowerShell 4.0 which is part of the [Windows Management Framework](http://www.microsoft.com/en-us/download/details.aspx?id=40855). + +## Hosts file updates + +If you install either the `vagrant-hostsupdater` (installed by default unless removed from `vagrant_plugins` in your `config.yml`) or `vagrant-hostmanager` plugin, you might get a permissions error when Vagrant tries changing the hosts file. On a macOS or Linux workstation, you're prompted for a sudo password so the change can be made, but on Windows, you have to do one of the following to make sure hostsupdater works correctly: + + 1. Run PowerShell or whatever CLI you use with Vagrant as an administrator. Right click on the application and select 'Run as administrator', then proceed with `vagrant` commands as normal. + 2. Change the permissions on the hosts file so your account has permission to edit the file (this has security implications, so it's best to use option 1 unless you know what you're doing). To do this, open `%SystemRoot%\system32\drivers\etc` in Windows Explorer, right-click the `hosts` file, and under Security, add your account and give yourself full access to the file. + +## Intel VT-x virtualization support + +On some laptops, Intel VT-x virtualization (which is built into most modern Intel processors) is enabled by default. This allows VirtualBox to run virtual machines efficiently using the CPU itself instead of software CPU emulation. If you get a message like "VT-x is disabled in the bios for both all cpu modes" or something similar, you may need to enter your computer's BIOS settings and enable this virtualization support. diff --git a/docs/getting-started/syncing-folders.md b/docs/getting-started/syncing-folders.md new file mode 100644 index 000000000..ed50f48c1 --- /dev/null +++ b/docs/getting-started/syncing-folders.md @@ -0,0 +1,108 @@ +You can share folders between your host computer and the VM in a variety of ways; the most commonly-used method is an NFS share. If you use Windows and encounter any problems with NFS, try switching to `smb`. The `default.config.yml` file contains an example `nfs` share that would sync the entire drupal-vm directory (configured as the relative path `.`) on your host into the `/var/www/drupalvm` folder on Virtual Machine. + +If you want to use a different synced folder method (e.g. `smb`), you can change `type`: + +```yaml +vagrant_synced_folders: + - local_path: . + destination: /var/www/drupalvm + type: smb + create: true +``` + +You can add as many synced folders as you'd like, and you can configure [any type of share](https://www.vagrantup.com/docs/synced-folders/index.html) supported by Vagrant; just add another item to the list of `vagrant_synced_folders`. + +## Options + +The synced folder options exposed are `type`, `excluded_paths` (when using rsync), `id`, `create`, `mount_options` and `nfs_udp`. Besides these there are some sane defaults set when using rsync. For example all files synced with rsync will be writable by everyone, thus allowing the web server to create files. + +### Overriding defaults + +If you feel the need to fine-tune some of the options not exposed, the entire options hash passed to Vagrant can be overriden using `options_override`. + +The merge of the default options and `options_override` is shallow, so you can use it to remove flags from eg. `rsync__args`. + +One scenario where this might be useful is when you are moving generated code from the virtual machine back to your local machine and you want the files to have appropriate permissions instead of the default 666/777. + +```yaml +options_override: + owner: vagrant + group: www-data + rsync__args: [ + "--verbose", "--archive", "--delete", + "--chmod=gu=rwX,o=rX", # 664 for files, 775 for directories + ] +``` + +> Note If you're using CentOS, the group should be set to `httpd` or `apache` instead. + +## Synced Folder Troubleshooting + +_Read the following [overview on the performance of the different synced folder mechanisms](../other/performance.md#synced-folder-performance)._ + + +There are a number of issues people encounter with synced folders from time to time. The most frequent issues are listed below with possible solutions: + +### Using Native Synced Folders + +You can use a native synced folder, which should work pretty flawlessly on any platform, but with a potential serious performance downside (compared to other synced folder methods). Just set `type` to `virtualbox`. + +```yaml +vagrant_synced_folders: + - local_path: . + destination: /var/www/docroot + type: virtualbox + create: true +``` + +See [this issue](https://github.com/geerlingguy/drupal-vm/issues/67) for more information. + +### Permissions-related errors + +If you're encountering errors where Drupal or some other software inside the VM is having permissions issues creating or deleting files inside a synced folder, you might need to either make sure the file permissions are correct on your host machine (if a folder is not readable by you, it probably also won't be readable when mounted via NFS!), or add extra configuration to the synced folders item (if using a sync method like `rsync`): + +```yaml +vagrant_synced_folders: + - local_path: . + destination: /var/www/drupalvm + type: virtualbox + create: true + mount_options: ["dmode=775", "fmode=664"] + options_override: + owner: "vagrant" + group: "www-data" +``` + +> Note If you're using CentOS, the group should be set to `httpd` or `apache` instead. + +See [this issue](https://github.com/geerlingguy/drupal-vm/issues/66) for more details. + +### Using [`vagrant-bindfs`](https://github.com/gael-ian/vagrant-bindfs) to work around permissions-related errors + +If you're using NFS synced folders the mounted directories will use the same numeric permissions on the guest VM as on the host OS. If you're on OSX for instance, your files within the VM would be owned by 501:20. To correct these permissions you can use the [`vagrant-bindfs` plugin](https://github.com/gael-ian/vagrant-bindfs) to mount your NFS folders to a temporary location and then re-mount them to the actual destination with the correct ownership. + +First install the plugin with `vagrant plugin install vagrant-bindfs` and then add a `Vagrantfile.local` with the following: + +```rb +vconfig['vagrant_synced_folders'].each do |synced_folder| + case synced_folder['type'] + when "nfs" + guest_path = synced_folder['destination'] + host_path = File.expand_path(synced_folder['local_path']) + config.vm.synced_folders[guest_path][:guestpath] = "/var/nfs#{host_path}" + config.bindfs.bind_folder "/var/nfs#{host_path}", guest_path, + u: 'vagrant', + g: 'www-data', + perms: 'u=rwX:g=rwD', + o: 'nonempty' + config.nfs.map_uid = Process.uid + config.nfs.map_gid = Process.gid + end +end +``` + +> Note If you're using CentOS, the group should be set to `httpd` or `apache` instead. + +### Other NFS-related errors + +If you're having other weird issues, and none of the above fixes helps, you might want to try a different synced folder method (see top of this page), or something like File Conveyor or a special rsync setup (see [here](http://wolfgangziegler.net/auto-rsync-local-changes-to-remote-server#comments) for some examples). diff --git a/docs/index.md b/docs/index.md index 14c156114..0206d5da2 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,8 +1,12 @@

Drupal VM Logo

-[Drupal VM](http://www.drupalvm.com/) is A VM for local Drupal development, built with Vagrant + Ansible. +[Drupal VM](https://www.drupalvm.com/) is A VM for local Drupal development, built with Vagrant + Ansible. -Welcome to Drupal VM's documentation site! Please read through the [Quick Start Guide](https://github.com/geerlingguy/drupal-vm#quick-start-guide) to get started, and then browse the rest of this project's documentation in the sidebar. +Welcome to Drupal VM's documentation site! Get started by reading the installation instructions for you platform: + +- [macOS](getting-started/installation-macos.md) +- [Windows](getting-started/installation-windows.md) +- [Linux](getting-started/installation-linux.md) ## Contributing to Drupal VM diff --git a/docs/js/fix_search.js b/docs/js/fix_search.js new file mode 100644 index 000000000..6dd9fb202 --- /dev/null +++ b/docs/js/fix_search.js @@ -0,0 +1,44 @@ +(function (){ + var MutationObserver = (function () { + var prefixes = ['WebKit', 'Moz', 'O', 'Ms', ''] + for (var i=0; i < prefixes.length; i++) { + if (prefixes[i] + 'MutationObserver' in window) { + return window[prefixes[i] + 'MutationObserver']; + } + } + return false; + }()); + + /* + * RTD messes up MkDocs' search feature by tinkering with the search box defined in the theme, see + * https://github.com/rtfd/readthedocs.org/issues/1088. This function sets up a DOM4 MutationObserver + * to react to changes to the search form (triggered by RTD on doc ready). It then reverts everything + * the RTD JS code modified. + * + * @see https://github.com/rtfd/readthedocs.org/issues/1088#issuecomment-224715045 + */ + $(document).ready(function () { + if (!MutationObserver) { + return; + } + var target = document.getElementById('rtd-search-form'); + var config = {attributes: true, childList: true}; + + var observer = new MutationObserver(function(mutations) { + // if it isn't disconnected it'll loop infinitely because the observed element is modified + observer.disconnect(); + var form = $('#rtd-search-form'); + var path = window.location.pathname; + var branch = path.split('/')[2]; + form.empty(); + form.attr('action', window.location.origin + '/en/' + branch + '/search.html'); + $('').attr({ + type: "text", + name: "q", + placeholder: "Search docs" + }).appendTo(form); + }); + + observer.observe(target, config); + }); +}()); diff --git a/docs/other/acquia.md b/docs/other/acquia.md new file mode 100644 index 000000000..920d14041 --- /dev/null +++ b/docs/other/acquia.md @@ -0,0 +1 @@ +To emulate the default Acquia Cloud environment with Drupal VM you should create a `config.yml` and override a few defaults from `default.config.yml`. For an up-to-date example, use [BLT's `config.yml`](https://github.com/acquia/blt/blob/9.x/scripts/drupal-vm/config.yml). Some of the variables in the BLT example are customized for BLT and you should be looking specifically at `vagrant_box`, `php_version`, and `php_packages_extra`. diff --git a/docs/other/base-os.md b/docs/other/base-os.md deleted file mode 100644 index 3aaf61cbb..000000000 --- a/docs/other/base-os.md +++ /dev/null @@ -1,40 +0,0 @@ -Drupal VM's configuration is designed to work with RedHat and Debian-compatible operating systems. Therefore, if you switch the `vagrant_box` in `config.yml` to any compatible OS, Drupal VM and all it's configuration should _Just Work™_... but that's not always the case. - -Currently-supported OSes are: - - - Ubuntu 14.04 (default) - - Ubuntu 12.04 - - RedHat Enterprise Linux / CentOS 7 - - RedHat Enterprise Linux / CentOS 6 - -For certain OSes, there are a couple other caveats and tweaks you may need to perform to get things running smoothly—the main features and latest development is only guaranteed to work with the default OS as configured in `example.config.yml`. - -## RedHat Enterprise Linux / CentOS 7 - -**MySQL/MariaDB**: RHEL/CentOS 7 switched from using MySQL as the default database system to using MariaDB, so to make sure everything is configured properly, you need to add the following to `config.yml` so MariaDB installs correctly: - -```yaml -mysql_packages: - - mariadb - - mariadb-server - - mariadb-libs - - MySQL-python - - perl-DBD-MySQL -mysql_daemon: mariadb -mysql_socket: /var/lib/mysql/mysql.sock -mysql_log_error: /var/log/mariadb/mariadb.log -mysql_syslog_tag: mariadb -mysql_pid_file: /var/run/mariadb/mariadb.pid -``` - -**XHProf**: XHProf is installed in a different directory for RedHat/CentOS (as opposed to Debian/Ubuntu), you will need to update the `"xhprof.drupalvm.dev"` vhost to point to the `documentroot` `"/usr/share/pear/xhprof_html"`. - -## RedHat Enterprise Linux / CentOS 6 - -**PHP OpCache**: PHP's OpCache (if you're using PHP > 5.5) requires the following setting to be configured in `config.yml` (see upstream bug: [CentOS (6) needs additional php-opcache package](https://github.com/geerlingguy/ansible-role-php/issues/39)): - -```yaml -php_opcache_enabled_in_ini: false -``` - -**XHProf**: XHProf is installed in a different directory for RedHat/CentOS (as opposed to Debian/Ubuntu), you will need to update the `"xhprof.drupalvm.dev"` vhost to point to the `documentroot` `"/usr/share/pear/xhprof_html"`. \ No newline at end of file diff --git a/docs/other/bigpipe.md b/docs/other/bigpipe.md new file mode 100644 index 000000000..3a2f4cc80 --- /dev/null +++ b/docs/other/bigpipe.md @@ -0,0 +1,43 @@ +[BigPipe](https://www.drupal.org/documentation/modules/big_pipe) is a Drupal module that was added as an 'experimental' module in Drupal 8.1. BigPipe allows PHP responses to be streamed in-progress so authenticated end users can recieve a cached response very quickly, with placeholders for more dynamic (harder to cache) content that are filled in during the same request. + +To do this, BigPipe requires an environment configured to allow the authenticated request response to be streamed from PHP all the way through to the client. All parts of the web stack that intermediate the connection have to have output buffering disabled so the response stream can flow through. + +Drupal VM's default configuration uses Apache with the `mod_proxy_fastcgi` module to connect to PHP-FPM, which isn't the most optimal configuration for BigPipe, so you should either switch to Nginx or consider further customizing the Apache configuration. + +Drupal VM's Varnish configuration works with BigPipe out of the box, as it allows the backend response to be streamed whenever BigPipe is enabled (it outputs a `Surrogate-Control: BigPipe/1.0` header to tell Varnish when to stream the response). + +## PHP configuration + +BigPipe doesn't require any particular modifications to PHP in Drupal VM's default configuration. However, for some scenarios, you might want to disable php's `output_buffering` entirely by setting `php_output_buffering: "Off"` in `config.yml`, or change the `output_buffering` level from it's default of `4096` bytes. + +## Nginx configuration + +There is no extra configuration required to get BigPipe working with Nginx. + +Nginx is the recommended way to use BigPipe, for the following reasons: + + - It's easier to configure Nginx to handle hundreds (or more) concurrent connections through to PHP-FPM than `mod_php`, and more widely used than the other compatible Apache CGI modules `mod_fcgid` and `mod_fastcgi` + - Nginx intelligently disables output buffering and gzip if the `X-Accel-Buffering: no` header is present (BigPipe sets this header automatically). This means gzip and buffering can be enabled for most requests, and disabled on-the-fly by BigPipe. + +## Apache configuration + +Apache has three primary means of interacting with PHP applications like Drupal: `mod_php`, `mod_fastcgi`, and `mod_proxy_fcgi`. Drupal VM uses `mod_proxy_fcgi`, which is the most widely used and supported method of using Apache with PHP-FPM for the best scalability and memory management with Apache + PHP. + +For all of these methods, you have to make sure `mod_deflate` gzip compression is disabled; you can do this by modifying the VirtualHost's `extra_parameters` parameter in the `apache_vhosts` list inside `config.yml`: + + apache_vhosts: + - servername: "{{ drupal_domain }}" + serveralias: "www.{{ drupal_domain }}" + documentroot: "{{ drupal_core_path }}" + extra_parameters: | + {{ apache_vhost_php_fpm_parameters }} + SetEnv no-gzip 1 + +This will disable the `mod_deflate` module for any requests inside that directory. + +If you want to switch Apache to use `mod_php` instead of proxying requests through PHP-FPM, you can make the following changes in `config.yml`: + + 1. Add `libapache2-mod-php7.4` to `extra_packages` in `config.yml`. + 2. Delete the `extra_parameters` under any Drupal site in the list of `apache_vhosts` (so there is no `SetHandler` rule). + +You can also disable PHP-FPM and remove the two `proxy` entries from `apache_mods_enabled` if you don't want to use PHP-FPM with Apache at all, but that's optional; it won't break anything to run Apache with `mod_php` and `mod_proxy_fastcgi` at the same time. diff --git a/docs/other/cloning-with-newd.md b/docs/other/cloning-with-newd.md deleted file mode 100644 index 298a65c7d..000000000 --- a/docs/other/cloning-with-newd.md +++ /dev/null @@ -1,15 +0,0 @@ -@rgoodie created a function called `newd` that clones this repo, uses `sed` to change configuration to Drupal 7 if desired, renames the VM to something other than drupaltest.dev, and kicks off `vagrant up`. - -Example: - -``` -# Create a new Drupal VM named 'test-fieldformatter' with Drupal 7. -$ newd 7 test-fieldformatter - -# Create a new Drupal VM named 'drupal8test' with Drupal 8. -$ newd 8 drupal8test -``` - -The source code for this new bash function (you could add it to your own `.bash_profile` or `.profile`) is located here: https://gist.github.com/rgoodie/9966f30b404a4daa59e1 - -Do you have your own wrapper script or other helpers to help you manage instances of Drupal VM? Please share it on this page! \ No newline at end of file diff --git a/docs/other/custom-base-box.md b/docs/other/custom-base-box.md new file mode 100644 index 000000000..40efbaf48 --- /dev/null +++ b/docs/other/custom-base-box.md @@ -0,0 +1,11 @@ +You can build a custom Vagrant base box to help speed up the provisioning time for Drupal VM for your project, or if you have other specilized requirements, like: + + - You need larger virtual disk image size for your VM + - You need a base box for a provider not supported by the default Drupal VM boxes (e.g. Parallels, VMware Fusion, AWS, etc.) + - You need to inject certain software or configuration which is difficult to do using Drupal VM alone. + +By default, Drupal VM uses the [`geerlingguy/drupal-vm`](https://app.vagrantup.com/geerlingguy/boxes/drupal-vm) Vagrant base box, but you can use any base box which has at least a minimal OS installation supported by Drupal VM (e.g. CentOS, Ubuntu, Debian). + +This base box is built using the Packer configuration here: [Packer Build - Drupal VM](https://github.com/geerlingguy/packer-drupal-vm). + +In order to build your own custom base box, fork the Packer project linked above, then follow the instructions included in its README to install Packer and build the base box. Then update your `config.yml` to point to your own custom box by overriding the `vagrant_box` variable. diff --git a/docs/other/docker.md b/docs/other/docker.md new file mode 100644 index 000000000..b2a9fb651 --- /dev/null +++ b/docs/other/docker.md @@ -0,0 +1,167 @@ +Drupal VM can be used with [Docker](https://www.docker.com) instead of or in addition to Vagrant: + + - You can quickly install a Drupal site (any version) using the official [`geerlingguy/drupal-vm`](https://hub.docker.com/r/geerlingguy/drupal-vm/) image. + - You can build a customized local instance using Docker, pulling the official [`geerlingguy/drupal-vm`](https://hub.docker.com/r/geerlingguy/drupal-vm/) image. + - You can 'bake your own' customized Drupal VM Docker image and reuse it or share it with your team. + +> **Docker support is currently experimental**, so unless you're already familiar with Docker, it might be best to wait until later versions of Drupal VM are released with more stable support. + +## Managing your hosts file + +Before using Docker to run Drupal VM, you should [edit your hosts file](https://support.rackspace.com/how-to/modify-your-hosts-file/) and add the following line: + + 192.168.89.89 drupalvm.test + +(Substitute the IP address and domain name you'd like to use to access your Drupal VM container.) + +You can also add other subdomains if you're using other built-in services, e.g. `adminer.drupalvm.test`, `xhprof.drupalvm.com`, etc. + +> If you're using Docker for Mac, you need to perform one additional step to ensure you can access Drupal VM using a unique IP address: +> +> 1. Add an alias IP address on the loopback interface: `sudo ifconfig lo0 alias 192.168.89.89/24` +> 2. When you're finished using the container, delete the alias: `sudo ifconfig lo0 -alias 192.168.89.89` (or restart your Mac). +> +> You'll have to create the alias again after restarting your Mac. See [this Docker (moby) issue](https://github.com/moby/moby/issues/22753#issuecomment-246054946) for more details. + +## Method 1: Get a quick Drupal site installed with Drupal VM's Docker image + +If you just want a quick, easy Drupal site for testing, you can run an instance of Drupal VM and install Drupal inside using the provided script. + + 1. Run an instance of Drupal VM: `docker run -d -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 80:80 -p 443:443 --name=drupalvm --privileged geerlingguy/drupal-vm` + 2. Install Drupal on this instance: `docker exec drupalvm install-drupal` (you can choose a version using `install-drupal [version]`, using versions like `9.x-dev` or `8.x-dev`). + +You should be able to access the Drupal site at `http://localhost`. If you need to share a host directory into the VM, you can do so by adding another `-v` parameter, like `-v /path/on/host:/path/in/container. + +If you only need a container to run your site, and you want to package up the container configuration with your project, you can add a Docker Compose file to your project's docroot like the following: + + ```yaml + version: "3" + + services: + + myproject: + image: geerlingguy/drupal-vm + container_name: myproject + ports: + - 80:80 + - 443:443 + privileged: true + volumes: + - ./:/var/www/drupalvm/drupal/web/:rw,delegated + - /var/lib/mysql + - /sys/fs/cgroup:/sys/fs/cgroup:ro + command: /lib/systemd/systemd + ``` + +Then, run `docker-compose up -d` to bring up the container. + +For an example use of the simple approach for a contributed module's local development environment, see the Honeypot module, where this approach was added in [Add local test environment configuration](https://www.drupal.org/node/2885488). + +If you need more flexibility, though, you use one of the other Docker container methods on this page. + +## Method 2: Build a default Drupal VM instance with Docker + +The [`geerlingguy/drupal-vm`](https://hub.docker.com/r/geerlingguy/drupal-vm/) image on Docker Hub contains a pre-built copy of Drupal VM, with all the latest Drupal VM defaults. If you need to quickly run your site in a container, or don't need to customize any of the components of Drupal VM, you can use this image. + +> For a reference installation that has configuration for running the local environment on _either_ Vagrant or Docker, see the [Drupal VM Live Site Repository](https://github.com/geerlingguy/drupalvm-live). + +### (Optional) Add a `Dockerfile` for customization + +If you need to make small changes to the official `drupal-vm` image (instead of baking your own fully-custom image), you can create a `Dockerfile` to make those changes. In one site's example, ImageMagick was required for some media handling functionality, and so the following `Dockerfile` was placed in the project's root directory (alongside the `docker-compose.yml` file): + + FROM geerlingguy/drupal-vm:latest + LABEL maintainer="Jeff Geerling" + + # Install imagemagick. + RUN apt-get install -y imagemagick + + EXPOSE 80 443 3306 8025 + +You can customize the official image in many other ways, but if you end up doing more than a step or two in a `Dockerfile`, it's probably a better idea to 'bake your own' Drupal VM Docker image. + +### Add a `docker-compose.yml` file + +Copy the `example.docker-compose.yml` file out of Drupal VM (or grab a copy from GitHub [here](https://github.com/geerlingguy/drupal-vm/blob/master/example.docker-compose.yml)), rename it `docker-compose.yml`, and place it in your project root. + + - _If you are using your own `Dockerfile` to further customize Drupal VM_, comment out the `image: drupal-vm` line, and uncomment the `build: .` line (this tells Docker Compose to build a new image based on your own `Dockerfile`). + +For the `volume:` definition in `docker-compose.yml`, Drupal VM's default docroot is `/var/www/drupalvm/drupal/web`, which follows the convention of a typical Drupal project built with Composer. If you don't get your site when you attempt to access Drupal VM, you will either need to modify the `volume:` definition to match your project's structure, or use a custom `Dockerfile` and copy in a customized Apache `vhosts.conf` file. + +You should also add a volume for MySQL data, otherwise MySQL may not start up correctly. By default, you should have a volume for `/var/lib/mysql` (no need to sync it locally). See Drupal VM's example docker-compose file for reference. + +### Run Drupal VM + +Run the command `docker-compose up -d` (the `-d` tells `docker-compose` to start the containers and run in the background). + +This command takes the instructions in the Docker Compose file and does two things: + + 1. Creates a custom Docker network that exposes Drupal VM on the IP address you have configured in `docker-compose.yml` (by default, `192.168.89.89`). + 2. Runs Drupal VM using the configuration in `docker-compose.yml`. + +After the Drupal VM container is running, you should be able to see the Dashboard page at the VM's IP address (e.g. `http://192.168.89.89`), and you should be able to access your site at the hostname you have configured in your hosts file (e.g. `http://drupalvm.test/`). + +> Note: If you see Drupal's installer appear when accessing the site, that means the codebase was found, but either the database connection details are not in your local site configuration, or they are, but you don't have the default database populated yet. You may need to load in the database either via `drush sql-sync` or by importing a dump into the container. The default credentials are `drupal` and `drupal` for username and password, and `drupal` for the database name. + +You can stop the container with `docker-compose stop` (and start it again with `docker-compose start`), or remove all the configuration with `docker-compose down` (warning: this will also wipe out the database and other local container modifications). + +### Using Drush inside Docker + +Currently, the easiest way to use Drupal VM's `drush` inside a Docker container is to use `docker exec` to run `drush` internally. There are a few other ways you can try to get Drush working with a codebase running on a container, but the easiest way is to run a command like: + + docker exec drupal-vm bash -c "drush --uri=drupalvm.test --root=/var/www/drupalvm/drupal/web status" + +## Method 3: 'Bake and Share' a custom Drupal VM Docker image + +If you need a more customized Drupal VM instance, it's best to build your own with Drupal VM's built-in Docker scripts. + +### Building ('baking') a Docker container with Drupal VM + +After you've configured your Drupal VM settings in `config.yml` and other configuration files, run the following command to create and provision a new Docker container: + + composer docker-bake + +This will bake a Docker images using Drupal VM's default settings for distro, IP address, hostname, etc. You can override these options (all are listed in the `provisioning/docker/bake.sh` file) by prepending them to the `composer` command: + + DRUPALVM_IP_ADDRESS='192.168.89.89' DISTRO='debian10' composer docker-bake + +This process can take some time (it should take a similar amount of time as it takes to build Drupal VM normally, using Vagrant and VirtualBox), and at the end, you should see a message like: + +``` +PLAY RECAP ********************************************************************* +localhost : ok=210 changed=94 unreachable=0 failed=0 + + +...done! + +Visit the Drupal VM dashboard: http://192.168.89.89:80 +``` + +Once the build is complete, you can view the dashboard by visiting the URL provided. + +### Saving the Docker container to an image + +If you are happy with the way the container was built, you can run the following command to convert the container into an image: + + composer docker-save-image + +You can override the default values for the image creation by overriding the following three variables inside `config.yml`: + + docker_container_name: drupal-vm + docker_image_name: drupal-vm + docker_image_path: ~/Downloads + +Using the default settings, this command will tag your current version of the container as `drupal-vm:latest` (on your local computer), then store an archive of the image in an archive file, in the path "`docker_image_path`/`docker_image_name`.tar.gz". + +### Loading the Docker container from an image + +On someone else's computer (or your own, if you have deleted the existing `drupal-vm` image), you can load an archived image by placing it in the path defined by "`docker_image_path`/`docker_image_name`.tar.gz" in your `config.yml` file. To do this, run the command: + + composer docker-load-image + +### Using a baked Drupal VM image with `docker-compose.yml` + +Drupal VM includes an `example.docker-compose.yml` file. To use the file, copy it to `docker-compose.yml` and customize as you see fit, making sure to change the `image` to the value of `docker_image_name` (the default is `drupal-vm`). Once you've configured the exposed ports and settings as you like, run the following command to bring up the network and container(s) according to the compose file: + + docker-compose up -d + +(The `-d` tells `docker-compose` to start the containers and run in the background.) You can stop the container with `docker-compose stop` (and start it again with `docker-compose start`), or remove all the configuration with `docker-compose down` (warning: this will also wipe out the database and other local container modifications). diff --git a/docs/other/drupal-6.md b/docs/other/drupal-6.md index b9869aeb0..ce6d5fe9f 100644 --- a/docs/other/drupal-6.md +++ b/docs/other/drupal-6.md @@ -1,4 +1,4 @@ If you'd like to use the included configuration and Drush make file to install a Drupal 6 site using an older version of Drush (< 7.x), you may need to make some changes, namely: 1. Drush < 7.x does not support .yml makefiles; if using Drush 5.x or 6.x, you will need to create the make file in the INI-style format. - 2. In your customized `config.yml` file, you will need to use the `default` installation profile instead of `standard` (for the `drupal_install_profile` variable). \ No newline at end of file + 2. In your customized `config.yml` file, you will need to use the `default` installation profile instead of `standard` (for the `drupal_install_profile` variable). diff --git a/docs/other/management-tools.md b/docs/other/management-tools.md new file mode 100644 index 000000000..e87195ef0 --- /dev/null +++ b/docs/other/management-tools.md @@ -0,0 +1,63 @@ +There are some upstream tools which aid in the creation and management of Drupal VM instances. Some of the more popular tools are listed here. + +If you know of any other tools to help manage Drupal VM, please add them to this page! + +## Lunchbox + +[Lunchbox](https://github.com/LunchboxDevTools/lunchbox) is a wrapper for the Drupal VM project to manage your Drupal development process. It is a Node.js-based GUI to assist in setting up Drupal VM and creating and managing instances. + +## Acquia BLT + +[BLT (Build and Launch Tool)](https://github.com/acquia/blt) is a project from Acquia that builds a Drupal project repository, and can optionally include Drupal VM as part of the project. There is an open PR that may [use Composer to add Drupal VM as a project dependency automatically](https://github.com/acquia/blt/pull/93). + +## Drupal VM Config Generator + +[Drupal VM Config Generator](https://github.com/opdavies/drupal-vm-config-generator) is a Symfony Console application that manages and customises configuration files for Drupal VM projects. + +You can either use the interactive console UI to build configurations, or pass options directly to the `drupalvm-generate` command. + +Examples: + +``` +drupalvm-generate \ + --hostname=example.com \ + --machine-name=example \ + --ip-address=192.168.88.88 \ + --cpus=1 \ + --memory=512 \ + --webserver=nginx \ + --domain=example.com \ + --path=../site \ + --destination=/var/www/site \ + --docroot=/var/www/site/drupal \ + --drupal-version=8 \ + --build-makefile=no \ + --install-site=true \ + --installed-extras=xdebug,xhprof \ + --force +``` + +## Drupal VM Generator + +[generator-drupalvm](https://github.com/kevinquillen/generator-drupalvm) is a Yeoman generator for quickly spawning configured VMs or new projects using Drupal VM. + +Examples: + +``` +# Generate a new Drupal VM instance in the current directory. +$ yo drupalvm +``` + +## Newd + +[`newd`](https://gist.github.com/rgoodie/9966f30b404a4daa59e1) is a bash function that quickly clones the Drupal VM repo wherever you need it, configures important bits, and then kicks off `vagrant up`. + +Examples: + +``` +# Create a new Drupal VM named 'test-fieldformatter' with Drupal 7. +$ newd 7 test-fieldformatter + +# Create a new Drupal VM named 'drupal8test' with Drupal 8. +$ newd 8 drupal8test +``` diff --git a/docs/other/networking.md b/docs/other/networking.md new file mode 100644 index 000000000..3604e3723 --- /dev/null +++ b/docs/other/networking.md @@ -0,0 +1,12 @@ +Since Vagrant manages internal network connections for Drupal VM, and since every person's network setup is unique, there are sometimes networking issues that require some adjustments to your Drupal VM configuration or a computer reboot. + +## Network Route Collision + +Drupal VM comes configured with the default IP address `192.168.88.88`. If you're connected to a LAN with the same private IP address range (e.g. `192.168.x.x`), then VirtualBox or VMware will not be able to set up the VM with the default IP address, because that would conflict with the `192.168.x.x` network your computer is using. + +In this case, you have two options: + + 1. Switch the `vagrant_ip` in `config.yml` to a different private IP address, e.g. `172.16.0.88` or `10.0.1.88`. + 2. Install the `vagrant-auto_network` plugin (`vagrant plugin install vagrant-auto_network`), and set the `vagrant_ip` to `0.0.0.0`. + +Another cause of route collisions is the use of multiple VM providers on your computer. If you have both VirtualBox and VMware Fusion, and you have VMs running in both, and you attempt to use the same IP range in both providers, you'll hit a networking conflict. In this case, the only easy way to restore connectivity is to restart your host machine. diff --git a/docs/other/performance.md b/docs/other/performance.md new file mode 100644 index 000000000..b0744a6e9 --- /dev/null +++ b/docs/other/performance.md @@ -0,0 +1,118 @@ +## Improving composer build performance + +Opting for composer based installs will most likely increase your VM's time to provision considerably. + +If you manage multiple VM's own your computer, you can use the [`vagrant-cachier` plugin](http://fgrehm.viewdocs.io/vagrant-cachier/) to share Composer's package cache across all VM's. The first build will be as slow as before but subsequent builds with the same `vagrant_box` (eg `geerlingguy/ubuntu1804`) will be much faster. + +Install the plugin on your host computer: `vagrant plugin install vagrant-cachier`. + +Drupal VM's `Vagrantfile` includes the appropriate `vagrant-cachier` configuration to cache Composer and apt dependencies. + +_You can also use this plugin to share other package manager caches. For more information read the [documentation](http://fgrehm.viewdocs.io/vagrant-cachier/usage/)._ + +## Synced Folder Performance + +Using different synced folder mechanisms can have a dramatic impact on your Drupal site's performance. Please read through the following blog posts for a thorough overview of synced folder performance: + + - [Comparing filesystem performance in Virtual Machines](http://mitchellh.com/comparing-filesystem-performance-in-virtual-machines) + - [NFS, rsync, and shared folder performance in Vagrant VMs](http://www.jeffgeerling.com/blogs/jeff-geerling/nfs-rsync-and-shared-folder) + +Generally speaking: + + - NFS offers a decent tradeoff between performance and ease of use + - SMB offers a similar tradeoff, but is a bit slower than NFS + - Rsync offers the best performance inside the VM, but sync is currently one-way-only (from host to VM), which can make certain development workflows burdensome + - Native shared folders offer abysmal performance; only use this mechanism as a last resort! + +If you are using rsync, it is advised to exclude certain directories so that they aren't synced. These include version control directories, database exports and Drupal's files directory. + +```yaml +vagrant_synced_folders: + - local_path: . + destination: /var/www/drupalvm + type: rsync + create: true + excluded_paths: + - private + - .git + - web/sites/default/files + - tmp +``` + +### Mixing synced folder types + +You can also mix the synced folder types and use a fast one-way rsync for your primary codebase and then a slower but two-way sync for Drupal's configuration sync directory. + +```yaml +vagrant_synced_folders: + - local_path: . + destination: /var/www/drupal + type: rsync + create: true + excluded_paths: + - private + - .git + - web/sites/default/files + - tmp + # Exclude the second synced folder. + - config/drupal + # Use a slower but two-way sync for configuration sync directory. + - local_path: config/drupal + destination: /var/www/drupal/config/drupal + type: virtualbox # Or smb/nfs if available + create: true +``` + +## Improving performance on Windows + +By default, if you use the _NFS_ synced folder type, Vagrant will ignore this directive and use the native (usually slow) VirtualBox shared folder system instead. You can get higher performance by doing one of the following (all of these steps require a full VM reload (`vagrant reload`) to take effect): + + 1. **Use PhpStorm or a reverse-mounted synced folder for working from inside the VM.** Read [Drupal VM on Windows - a fast container for BLT project development](https://www.jeffgeerling.com/blog/2017/drupal-vm-on-windows-fast-container-blt-project-development) for instructions and recommendations. + 1. **Install the `vagrant-winnfsd` plugin**. See the 'NFS' section later for more details and caveats. + 1. **Use `smb` for the synced folder's type.** + 1. **Use `rsync` for the synced folder's type.** This requires that you have `rsync` available on your Windows workstation, which you can get if you install a substitute CLI like [Cygwin](https://www.cygwin.com/) or [Cmder](http://cmder.net/). + +### NFS + +You can use the [vagrant-winnfsd](https://github.com/GM-Alex/vagrant-winnfsd) plugin to get NFS support on windows. Be aware that there are multiple issues logged against both the plugin and the winnfsd project, so no guarantees. + +#### Using WinNFSD without `vagrant-winnfsd` + +Another option for the more adventurous is to manually install and configure WinNFSD, and manually mount the shares within your VM. This requires a bit more work, but could be more stable on Windows; see this blog post for more details: [Windows + Vagrant + WinNFSD without file update problems](https://hollyit.net/blog/windowsvagrantwinnfsd-without-file-update-problems). + +GuyPaddock's [fork of `vagrant-winnfsd`](https://github.com/GuyPaddock/vagrant-winnfsd) adds logging and debug messages. You can replace the vagrant-winnfsd gem inside `.vagrant.d\gems\gems` to use it instead. For further caveats, please read through [vagrant-winnfsd issue #12](https://github.com/winnfsd/vagrant-winnfsd/issues/12#issuecomment-78195957), and make the following changes to `config.yml`: + + vagrant_synced_folder_default_type: virtualbox + +Add `mount_options` to your synced folder to avoid an error: + + type: nfs + mount_options: ["rw","vers=3","udp","nolock"] + +In a custom `Vagrantfile.local`, add user access to Vagrant: + + config.winnfsd.uid=900 + config.winnfsd.gid=900 + +### Better performance: Sharing from Drupal VM to your PC + +The fastest option for Drupal VM is to install the Drupal codebase entirely inside Drupal VM, without using a Vagrant shared folder. This method ensures the code runs as fast as it would if it were natively running on your PC, but it requires some other form of codebase synchronization, and means there is at least a tiny bit of lag between saving files in your editor and seeing the changes inside Drupal VM. + +If you use one of these techniques, it's recommended you use the [Git deployment technique](../deployment/git.md) to clone your Drupal codebase into Drupal VM from a Git repository. + +#### Syncing files via rsync or SSH + +If you use an IDE like PhpStorm, you can configure it to synchronize a local codebase with the code inside Drupal VM using SSH (SFTP). There are also tools that mount directories into Windows Explorer using plain SSH and SFTP, though configuring these tools can be difficult. + +If at all possible, make sure your IDE is configured to automatically synchronize changes. + +#### Share files using Samba inside Drupal VM + +Though it's not supported natively by Vagrant, you can mount a Samba share _from the VM guest_ to your host PC. To do this, you have to: + + 1. Install Samba inside the VM. + 2. Configure Samba (through `smb.conf`) to share a directory inside the VM. + 3. Open firewall ports `137`, `138`, `139`, and `445`. + 4. Mount the Samba shared folder within Windows Explorer (e.g. visit `\\drupalvm.test\share_name`) + +Read this blog post for further detail in creating a Samba share: [Configure a reverse-mounted Samba shared folder](https://www.jeffgeerling.com/blog/2017/drupal-vm-on-windows-fast-container-blt-project-development#reverse-share). diff --git a/docs/other/php-7.md b/docs/other/php-7.md deleted file mode 100644 index 620aff684..000000000 --- a/docs/other/php-7.md +++ /dev/null @@ -1,67 +0,0 @@ -Many users have requested the ability to easily install PHP 7.x in addition to the already easy-to-configure options of 5.3, 5.4, 5.5, and 5.6. This page will guide you through how to get PHP 7 running on Drupal VM by modifying a few configuration options and running a couple simple commands inside the VM. - -Note that, at this time (summer 2015), PHP 7 is still in pre-beta releases, and all support is experimental and prone to breaking things. Please don't try running PHP 7 on production machines yet! - -## Ubuntu 14.04 - -Currently the most reliable way to get PHP 7 (any version) running on Ubuntu is to build from source. This is supported by Drupal VM and is not too difficult, but it requires a few manual steps to make sure Apache and PHP play nice together, so this process is not currently documented here. - -Otherwise, Ondřej Surý also has a PPA for PHP 7.0 that is included with Drupal VM, and you can make the following additions/changes to your `config.yml` to use it: - -```yaml -php_version: "7.0" -php_packages: - - libapache2-mod-php7.0 - - php7.0-mcrypt - - php7.0-common - - php7.0-cli - - php7.0-curl - - php7.0-dev - - php7.0-fpm - - php7.0-gd - - libpcre3-dev -php_mysql_package: php7.0-mysqlnd -``` - -However, there's currently a bug with the beta1 version of the package, which causes installation to fail (see: https://github.com/oerdnj/deb.sury.org/issues/87). This section will be updated with more information once this packaging bug is fixed or a workaround is found. - -## RedHat/CentOS 7 - -After configuring Drupal VM to [use a different base OS](https://github.com/geerlingguy/drupal-vm/wiki/Using-Different-Base-OSes) (in this case, CentOS 7), you need to do the following to get PHP 7 running inside the VM: - - 1. Make the following changes to `config.yml`: - ```yaml - # Changes to make PHP 7 work in CentOS via Remi's repo. - php_executable: php70 - php_packages: - - ImageMagick - - php70 - - php70-php - - php70-fakepear - - php70-php-devel - - php70-php-gd - - php70-php-imap - - php70-php-ldap - - php70-php-mbstring - - php70-php-pdo - - php70-php-process - - php70-php-xml - - php70-php-xmlrpc - php_mysql_package: php70-php-mysqlnd - ``` - - 2. At this time, automatic install of `xhprof` and `xdebug` are unsupported. Make sure these options are commented or removed from the `installed_extras` setting in `config.yml`. - - 3. Run the normal `vagrant up` as you would with PHP 5.x, but when provisioning fails (usually on the Composer step), log into the VM with `vagrant ssh`, and run the following two commands: - ``` - sudo ln -s /usr/bin/php70 /usr/bin/php - sudo systemctl restart httpd.service - ``` - - 4. Log back out (type `exit` to exit the session in the VM) and run `vagrant provision`. This should pick back up where the provisioning left off earlier, and complete installation. - -Note: Make sure you're running the latest version of all Ansible role dependencies by running `ansible-galaxy install -r provisioning/requirements.txt --force` inside the root Drupal VM project folder. - -## Zend nightly PHP 7 builds - -Zend has a repository with [nightly PHP 7 builds](http://php7.zend.com/repo.php) for either RHEL/CentOS 7 or Debian 8/Ubuntu 14.04, but the repository requires some manual configuration and setup and is not going to be officially supported as a PHP 7 installation method within Drupal VM. \ No newline at end of file diff --git a/docs/other/production.md b/docs/other/production.md new file mode 100644 index 000000000..2964bc887 --- /dev/null +++ b/docs/other/production.md @@ -0,0 +1,167 @@ +Drupal VM can be made to manage a production environment. The security of your servers is _your_ responsibility, and **such usage should be considered experimental and unsupported**. + +(See companion blog post to this documentation: [Soup to Nuts: Using Drupal VM to build local and prod](https://www.jeffgeerling.com/blog/2017/soup-nuts-using-drupal-vm-build-local-and-prod).) + +If you want to try managing a production environment (or other non-local environments) with Drupal VM, please see the following suggestions for making these servers more secure and easier to manage. + +> Note: As of Drupal VM 5.0.0, the example production configuration files are no longer included with Drupal VM. You would need to download [Drupal VM 4.9.1](https://github.com/geerlingguy/drupal-vm/releases/tag/4.9.1) and copy the `examples/prod` directory into your Drupal VM codebase to make the example commands work with a newer version of Drupal VM. + +## Production specific overrides. + +Drupal VM supports loading configuration files depending on the environment variable `DRUPALVM_ENV` and using this feature you can have different configurations between development and production environments. + +```sh +# Loads vagrant.config.yml if available (default). +vagrant provision + +# Loads prod.config.yml if available. +DRUPALVM_ENV=prod vagrant provision --provisioner=aws +``` + +If you're issuing a provision directly through `ansible-playbook` as you would do for most production environments you can either set the `DRUPALVM_ENV` variable on your host, or on the remote production machine. + +```sh +# By default it doesn't try to load any other config file. +ansible-playbook -i examples/prod/inventory provisioning/playbook.yml --become --ask-become-pass + +# Loads prod.config.yml if available. +DRUPALVM_ENV=prod ansible-playbook -i examples/prod/inventory provisioning/playbook.yml --become --ask-become-pass +``` + +If you add `DRUPALVM_ENV=prod` to the `/etc/environment` file on your production environment: + +```sh +# Loads prod.config.yml if available. +ansible-playbook -i examples/prod/inventory provisioning/playbook.yml --become --ask-become-pass +``` + +_Note: Having the variable set locally takes precedence over having it on the remote machine._ + +As a precaution not to accidentally provision a production server with insecure configurations, you should set your security hardening configurations in `config.yml`, your local development overrides in `vagrant.config.yml` and finally any additional production specific overrides in `prod.config.yml`. This way, a production environment will never be provisioned with development tools, even if the `prod.config.yml` is not read. + +## Ansible Vault support + +Drupal VM will include a `secrets.yml` file included in your VM's configuration directory (alongside `config.yml`, `local.config.yml`, etc.) that you can use to store sensitive variables (e.g. MySQL's root password, Drupal's admin password). For extra security, you can encrypt this file, and require a password whenever the variable is used. + +First, you'd create an Ansible Vault encrypted file: + + $ ansible-vault create secrets.yml + +Create the file inside your VM's configuration directory, and save the following inside (replacing the actual passwords with your own secure ones!): + +``` +drupal_account_pass: add-your-secure-password-1-here +drupal_db_password: add-your-secure-password-2-here +mysql_root_password: add-your-secure-password-3-here +``` + +Ansible Vault will encrypt the file, and you can edit the file using `ansible-vault edit`. + +When running `vagrant` commands, make sure you tell the Ansible provisioner to use `--ask-vault-pass`, e.g.: + + DRUPALVM_ANSIBLE_ARGS='--ask-vault-pass' vagrant [command] + +And if you need to override one of the secrets stored in that file, you can do so through an environment-specific config file, for example: + + vagrant.config.yml + prod.config.yml + [etc.] + +## Example: Drupal VM on DigitalOcean + +The [`examples/prod` directory](https://github.com/geerlingguy/drupal-vm/tree/4.9.1/examples/prod) contains an example production configuration for Drupal VM which can be used to deploy Drupal VM to a production environment on a cloud provider like DigitalOcean, Linode, or AWS. + +This guide contains instructions for how you can build a Drupal environment with Drupal VM on DigitalOcean. + +### Create a DigitalOcean Droplet + +If you don't already have a DigitalOcean account, create one (you can use geerlingguy's [affiliate link](https://www.digitalocean.com/?refcode=b9c57af84643) to sign up, otherwise, visit the normal [DigitalOcean Sign Up form](https://cloud.digitalocean.com/registrations/new). + +Make sure you have an SSH key you can use to connect to your DigitalOcean droplets, and if you don't already have one set up, or if you need to add your existing key to your account, follow the instructions in this guide: [How to use SSH keys with DigitalOcean Droplets](https://www.digitalocean.com/community/tutorials/how-to-use-ssh-keys-with-digitalocean-droplets). + +Once you are logged into DigitalOcean and have added your SSH key, click the 'Create Droplet' button on your Droplets page. For the Droplet, choose the following options: + + - **Image**: Choose `Ubuntu 18.04.x x64` + - **Size**: 1 GB / 1 CPU (currently $5/month; you can choose a higher plan if needed) + - **Region**: Choose whatever region is geographically nearest to you and your site visitors + - **Settings**: (Nothing here affects how Drupal VM works, choose what you'd like) + - **Add SSH Keys**: Select the SSH key you added to your account earlier. + - **Hostname**: Choose a hostname for your site (e.g. `example.drupalvm.com`) + +Click 'Create Droplet', and wait a minute or so while the Droplet is booted. Once it's booted, make sure you can log into it from your local computer: + + ssh root@[droplet-hostname-or-ip] + +(Make sure you replace `[droplet-hostname-or-ip]`) with the hostname or IP address of your Droplet!) + +If you get a warning like "the authenticity of the host can't be established", answer yes to the prompt and hit enter. You should now be logged into the Droplet. Log back out by typing `exit` at the prompt and hitting return. + +Your DigitalOcean Droplet is booted and ready to have Drupal VM installed on it. + +### Customize `config.yml` for production + +Copy [`examples/prod/prod.config.yml`](https://github.com/geerlingguy/drupal-vm/blob/4.9.1/examples/prod/prod.config.yml) to `config.yml`, and by looking at `default.config.yml` add any other overrides you'd like. Whatever variables you have set in `config.yml` will override the defaults set by `default.config.yml`. + +The changes outlined in the [example `prod.config.yml`](https://github.com/geerlingguy/drupal-vm/blob/4.9.1/examples/prod/prod.config.yml) disable development-environment tools (like Adminer) and add extra security hardening configuration (via the `extra_security_enabled` variable). + +You now have Drupal VM configured for production by default. This is the recommended and safest way, so that you can't accidentally provision a production server with development tools. If desired you can also use the [environment variable `DRUPALVM_ENV`](#production-specific-overrides) to load an additional `.config.yml` with production specific overrides. In most cases this is not needed though. + +### Customize `vagrant.config.yml` for local development + +To re-use the same setup for local development, copy `default.config.yml` to `vagrant.config.yml` and configure it so that you override the security hardening configurations that were added in `config.yml`. Read about how configuration files are read under [Configuring Drupal VM](../getting-started/configure-drupalvm.md) + +### Customize `inventory` for production + +The only other thing you need to do is copy the inventory file `example.inventory` to `inventory` (so it is located at `prod/inventory`). By default, it reads: + + [drupalvm] + 1.2.3.4 ansible_ssh_user=my_admin_username + +Change the host `1.2.3.4` to either the IP address or the hostname of your DigitalOcean Droplet. Remember that if you would like to use a hostname, you need to make sure the hostname actually resolves to your Droplet's IP address, either in your domain's public DNS configuration, or via your local hosts file. + +### Initialize the server with an administrative account + +> Note: This guide assumes you have Ansible [installed](http://docs.ansible.com/ansible/intro_installation.html) on your host machine. + +The first step in setting up Drupal VM on the cloud server is to initialize the server with an administrative account (which is separate from the `root` user account for better security). + +Inside the `examples/prod/bootstrap` folder, copy the `example.vars.yml` file to `vars.yml` and update the variables in that file for your own administrative account (make sure especially to update the `admin_password` value!). + +Then, run the following command within Drupal VM's root directory (the folder containing the `Vagrantfile`): + + ansible-playbook -i examples/prod/inventory examples/prod/bootstrap/init.yml -e "ansible_ssh_user=root" + +Once the initialization is complete, you can test your new admin login with `ssh my_admin_username@droplet-hostname-or-ip`. You should be logged in via your existing SSH key. Log back out with `exit`. + +### Provision Drupal VM on the Droplet + +Run the following command within Drupal VM's root directory (the folder containing the `Vagrantfile`): + + DRUPALVM_ENV=prod ansible-playbook -i examples/prod/inventory provisioning/playbook.yml --become --ask-become-pass + +_Note: If you have installed [Drupal VM as a Composer dependency](../deployment/composer-dependency.md) you also need to specify the path of the config directory where you have your `config.yml` located._ + + DRUPALVM_ENV=prod ansible-playbook -i config/prod/inventory vendor/geerlingguy/drupal-vm/provisioning/playbook.yml -e "config_dir=$(pwd)/config" --become --ask-become-pass + +Ansible will prompt you for your admin account's `sudo` password (the same as the password you encrypted and saved as `admin_password`). Enter it and press return. + +After a few minutes, your Drupal-VM-in-the-cloud Droplet should be fully configured to match your local development environment! You can visit your Droplet and access the fresh Drupal site just like you would locally (e.g. `http://example.drupalvm.com/`). + +### Known issues + + - You may need to manually create the `drupal_core_path` directory on the server at this time; it's not always created automatically due to permissions errors. + - The `files` folder that is generated during the initial Drupal installation is set to be owned by the admin account; to make it work (and to allow Drupal to generate stylesheets and files correctly), you have to manually log into the server and run the following two commands after provisioning is complete: + + ``` + $ sudo chown -R www-data /var/www/drupalvm/drupal/sites/default/files + $ sudo chmod -R 0700 /var/www/drupalvm/drupal/sites/default/files + ``` + + - You can't synchronize folders between your host machine and DigitalOcean (at least not in any sane way); so you'll need to either have Drupal VM install a site from a given Drush make file or composer.json, or deploy the site via Git, using the `geerlingguy.drupal` role's git deployment options. + - Drupal VM doesn't include any kind of backup system. You should use one if you have any kind of important data on your server! + +### Go Further + +You can use Ubuntu Ubuntu 18.04, Debian 10, or CentOS 8 when you build the DigitalOcean Droplet. Just like with Drupal VM running locally, you can customize almost every aspect of the server! + +You may want to customize your configuration even further, to make sure Drupal VM is tuned for your specific Drupal site's needs, or you may want to change things and make the server configuration more flexible, etc. For all that, the book [Ansible for DevOps](http://ansiblefordevops.com/) will give you a great introduction to using Ansible to make Drupal VM and the included Ansible configuration do exactly what you need! diff --git a/docs/other/vagrant-lxc.md b/docs/other/vagrant-lxc.md new file mode 100644 index 000000000..1d9c056ac --- /dev/null +++ b/docs/other/vagrant-lxc.md @@ -0,0 +1,35 @@ +[`vagrant-lxc` is a Vagrant plugin](https://github.com/fgrehm/vagrant-lxc) that provisions Linux Containers (LXC) rather than VM's such as VirtualBox or VMWare. Although LXC has much better performance, it only works on Linux hosts, and it isn't as well supported or tested by Drupal VM. + +### Install dependencies + + sudo apt-get install lxc bridge-utils + vagrant plugin install vagrant-lxc + +### Load required kernel modules + +As containers can't load modules, but inherit them from the host, you need to load these on your host machine. + + sudo modprobe iptable_filter + sudo modprobe ip6table_filter + +To load these automatically when you boot up your system, you should check the guidelines of your specific distribution. Usually you add them to `/etc/modules` or `/etc/modules-load.d/*` + +### Create a [`Vagrantfile.local`](../extending/vagrantfile.md) + + config.vm.networks[0][1][:lxc__bridge_name] = 'vlxcbr1' + config.vm.provider :lxc do |lxc| + lxc.customize 'cgroup.memory.limit_in_bytes', "#{vconfig['vagrant_memory']}M" + end + +Read more about how to configure the container in [`vagrant-lxc`'s README.md](https://github.com/fgrehm/vagrant-lxc#readme). + +### Modify your `config.yml` + +The following boxes have been tested only minimally, choose which one you want. + + # Do not interact with the UFW service on Ubuntu. + drupalvm_disable_ufw_firewall: false + +### Provision the Container + + vagrant up --provider=lxc diff --git a/docs/other/vagrant-virtualbox.md b/docs/other/vagrant-virtualbox.md deleted file mode 100644 index 17b77a21d..000000000 --- a/docs/other/vagrant-virtualbox.md +++ /dev/null @@ -1,10 +0,0 @@ -From time to time, users have reported particular issues with Vagrant or VirtualBox in certain environments, and this page shows some common issues and possible fixes/solutions. - -## Guest additions fail to be detected - -From time to time, if you `vagrant halt`, then `vagrant up` again, you might get a message like `No guest additions were detected on the base box for this VM!`, as well as messages about shared folders not working correctly. - -There are two ways you can fix this problem: - - 1. Make sure you're running the latest box version for Drupal VM. Update by running `vagrant box update`. - 2. Install the `vagrant vbguest` plugin: `vagrant plugin install vagrant-vbguest`. diff --git a/docs/other/windows.md b/docs/other/windows.md deleted file mode 100644 index 5ed4a803d..000000000 --- a/docs/other/windows.md +++ /dev/null @@ -1,34 +0,0 @@ -There are a few caveats when using Drupal VM on Windows, and this page will try to identify the main gotchas or optimization tips for those wishing to use Drupal VM on a Windows host. - -## Synced Folders - -Most issues have to do synced folders. These are the most common ones: - -### Symbolic Links - -Creating symbolic links in a shared folder will fail with a permission or protocol error. - -There are two parts to this: - - 1. VirtualBox does not allow gets VMs to create symlinks in synced folders by default. - 2. Windows does not allow the creation of symlinks unless your local policy allows it; see [TechNet article](https://technet.microsoft.com/en-us/library/dn221947%28v=ws.10%29.aspx). Even if local policy allows it, many users experience problems in the creation of symlinks. - -### GIT & Permissions - -Do not work with git inside the synced folder inside the VM. Always use git on the Windows side. Otherwise the difference in permissions systems will make git think all your files have always been modified. It will also set the wrong permissions on any file you commit from inside the VM. - -### Long Paths - -Creating long paths inside a shared folder will fail if the length exceeds 260 characters. This usually happens when using npm. This should be solved in Vagrant 1.7.3, but if you're running an older version, you can manually make the changes here: https://github.com/mitchellh/vagrant/pull/5495/files - -### NFS - -You can use the [vagrant-winnfsd](https://github.com/GM-Alex/vagrant-winnfsd) plugin to get NFS support on windows. Be aware that there are multiple issues logged against both the plugin and the winnfsd project, so no guarantees. - -### "Authentication failure" on vagrant up - -Some Windows users have reported running into an issue where an authentication failure is reported once the VM is booted (e.g. `drupalvm: Warning: Authentication failure. Retrying...` — see [#170](https://github.com/geerlingguy/drupal-vm/issues/170)). To fix this, do the following: - - 1. Delete `~/.vagrant.d/insecure_private_key` - 2. Run `vagrant ssh-config` - 3. Restart the VM with `vagrant reload` diff --git a/docs/other/wordpress-other-applications.md b/docs/other/wordpress-other-applications.md new file mode 100644 index 000000000..39f843fa6 --- /dev/null +++ b/docs/other/wordpress-other-applications.md @@ -0,0 +1,105 @@ +While Drupal VM caters specifically to Drupal, and support for and compatibility with other PHP applications isn't guaranteed, Drupal VM is flexible enough to work with PHP applications besides Drupal. + +## Wordpress + +To integrate Drupal VM with an existing Wordpress project such as [bedrock](https://github.com/roots/bedrock), follow the documentation on using [Drupal VM as a Composer dependency](http://docs.drupalvm.com/en/latest/deployment/composer-dependency/). + +Begin by forking/cloning `bedrock` as a boilerplate for your application, and require Drupal VM as a development dependency. + +```yaml +composer require --dev geerlingguy/drupal-vm +``` + +Configure the VM by creating a `config/config.yml`: + +```yaml +vagrant_hostname: bedrock.dev +vagrant_machine_name: bedrock + +vagrant_synced_folders: + - local_path: . + destination: /var/www/wordpress + type: nfs + create: true + +# Needs to match with what we have in .env and vagrant_synced_folders. +drupal_core_path: "/var/www/wordpress/web" +drupal_domain: "{{ vagrant_hostname }}" +drupal_db_user: wordpress +drupal_db_password: wordpress +drupal_db_name: wordpress + +# Disable Drupal specific features. +drupal_build_composer_project: false +drupal_install_site: false +configure_drush_aliases: false + +# Remove some Drupal extras such as `drupalconsole` and `drush` +installed_extras: + - adminer + - mailhog + +# Add wp-cli +composer_global_packages: + - { name: wp-cli/wp-cli, release: '^1.0.0' } +``` + +Create the delegating `Vagrantfile` in the root of the project: + +```rb +# The absolute path to the root directory of the project. Both Drupal VM and +# the config file need to be contained within this path. +ENV['DRUPALVM_PROJECT_ROOT'] = "#{__dir__}" +# The relative path from the project root to the config directory where you +# placed your config.yml file. +ENV['DRUPALVM_CONFIG_DIR'] = "config" +# The relative path from the project root to the directory where Drupal VM is located. +ENV['DRUPALVM_DIR'] = "vendor/geerlingguy/drupal-vm" + +# Load the real Vagrantfile +load "#{__dir__}/#{ENV['DRUPALVM_DIR']}/Vagrantfile" +``` + +Edit your `.env` file to match the values you set in `config/config.yml`: + +``` +DB_NAME=wordpress +DB_USER=wordpress +DB_PASSWORD=wordpress +DB_HOST=localhost + +WP_ENV=development +WP_HOME=http://bedrock.dev +WP_SITEURL=${WP_HOME}/wp +``` + +Ignore local Drupal VM configuration files by adding the following to your `.gitignore`: + +``` +Vagrantfile.local +config/local.config.yml +``` + +Add a wp-cli `@dev` alias that points to the VM by editing the `wp-cli.yml` file: + +```yaml +path: web/wp + +@dev: + ssh: vagrant@bedrock.dev/var/www/wordpress/web/wp + url: bedrock.dev +``` + +For passwordless login with `wp-cli` add the following to your SSH config `~/.ssh/config`: + +``` +Host bedrock.dev + StrictHostKeyChecking no + IdentityFile ~/.vagrant.d/insecure_private_key +``` + +Provision the VM and import your database. + +```sh +vagrant up +``` diff --git a/example.config.yml b/example.config.yml deleted file mode 100644 index 50d0fc0c4..000000000 --- a/example.config.yml +++ /dev/null @@ -1,174 +0,0 @@ ---- -# `vagrant_box` can also be set to geerlingguy/centos6, geerlingguy/centos7, -# geerlingguy/ubuntu1204, parallels/ubuntu-14.04, etc. -vagrant_box: geerlingguy/ubuntu1404 -vagrant_user: vagrant - -# If you need to run multiple instances of Drupal VM, set a unique hostname, -# machine name, and IP address for each instance. -vagrant_hostname: drupalvm.dev -vagrant_machine_name: drupalvm -vagrant_ip: 192.168.88.88 - -# A list of synced folders, with the keys 'local_path', 'destination', 'id', and -# a 'type' of [nfs|rsync|smb] (leave empty for slow native shares). See -# https://github.com/geerlingguy/drupal-vm/wiki/Syncing-Folders for more info. -vagrant_synced_folders: - # The first synced folder will be used for the default Drupal installation, if - # build_from_makefile is 'true'. - - local_path: ~/Sites/drupalvm - destination: /var/www - id: drupal - type: nfs - create: true - -# Memory and CPU to use for this VM. -vagrant_memory: 1024 -vagrant_cpus: 2 - -# Set this to false if you are using a different site deployment strategy and -# would like to configure 'vagrant_synced_folders' and 'apache_vhosts' manually. -build_makefile: true -drush_makefile_path: /vagrant/drupal.make.yml - -# Set this to false if you don't need to install drupal (using the drupal_* -# settings below), but instead copy down a database (e.g. using drush sql-sync). -install_site: true - -# Settings for building a Drupal site from a makefile (if 'build_from_makefile' -# is 'true'). -drupal_major_version: 8 -drupal_core_path: "/var/www/drupal" -drupal_domain: "drupalvm.dev" -drupal_site_name: "Drupal" -drupal_install_profile: standard -drupal_enable_modules: [ 'devel' ] -drupal_account_name: admin -drupal_account_pass: admin -drupal_mysql_user: drupal -drupal_mysql_password: drupal -drupal_mysql_database: drupal - -# Cron jobs are added to the root user's crontab. Keys include name (required), -# minute, hour, day, weekday, month, job (required), and state. -drupalvm_cron_jobs: [] - # - { - # name: "Drupal Cron", - # minute: "*/30", - # job: "drush -r {{ drupal_core_path }} core-cron" - # } - -# Drupal VM automatically creates a drush alias file in your ~/.drush folder if -# this variable is 'true'. -configure_local_drush_aliases: true - -# Apache VirtualHosts. Add one for each site you are running inside the VM. For -# multisite deployments, you can point multiple servernames at one documentroot. -apache_vhosts: - - {servername: "{{ drupal_domain }}", documentroot: "{{ drupal_core_path }}"} - - {servername: "xhprof.drupalvm.dev", documentroot: "/usr/share/php/xhprof_html"} - - {servername: "pimpmylog.drupalvm.dev", documentroot: "/usr/share/php/pimpmylog"} -apache_remove_default_vhost: true -apache_mods_enabled: - - expires.load - - ssl.load - - rewrite.load - -# MySQL Databases and users. If build_from_makefile is true, first database will -# be used for the makefile-built site. -mysql_databases: - - name: "{{ drupal_mysql_database }}" - encoding: utf8 - collation: utf8_general_ci - -mysql_users: - - name: "{{ drupal_mysql_user }}" - host: "%" - password: "{{ drupal_mysql_password }}" - priv: "{{ drupal_mysql_database }}.*:ALL" - -# Comment out any extra utilities you don't want to install. If you don't want -# to install *any* extras, make set this value to an empty set, e.g. `[]`. -installed_extras: - - adminer - - mailhog - - memcached - - pimpmylog - # - selenium - # - solr - - varnish - - xdebug - - xhprof - -# Add any extra packages you'd like to install. -extra_packages: [] - -# You can configure almost anything else on the server in the rest of this file. -extra_security_enabled: false - -drush_version: master -drush_keep_updated: true - -firewall_allowed_tcp_ports: - - "22" - - "25" - - "80" - - "81" - - "443" - - "4444" - - "8025" - - "8080" - - "8443" - - "8983" -firewall_log_dropped_packets: false - -# PHP Configuration. Currently-supported versions: 5.5, 5.6, 7.0 (experimental). -php_version: "5.6" -php_memory_limit: "192M" -php_display_errors: "On" -php_display_startup_errors: "On" -php_realpath_cache_size: "1024K" -php_sendmail_path: "/usr/sbin/ssmtp -t" -php_opcache_enabled_in_ini: true -php_opcache_memory_consumption: "192" -php_opcache_max_accelerated_files: 4096 -php_max_input_vars: "4000" - -composer_path: /usr/bin/composer -composer_home_path: '/home/vagrant/.composer' -# composer_global_packages: -# - { name: phpunit/phpunit, release: '@stable' } - -# MySQL Configuration. -mysql_root_password: root -mysql_slow_query_log_enabled: true -mysql_slow_query_time: 2 -adminer_add_apache_config: true - -# Varnish Configuration. -varnish_listen_port: "81" -varnish_default_vcl_template_path: templates/drupalvm.vcl.j2 -varnish_default_backend_host: "127.0.0.1" -varnish_default_backend_port: "80" - -# Pimp my Log settings. -pimpmylog_install_dir: /usr/share/php/pimpmylog -pimpmylog_grant_all_privs: true - -# XDebug configuration. XDebug is disabled by default for better performance. -php_xdebug_default_enable: 0 -php_xdebug_coverage_enable: 0 -php_xdebug_cli_enable: 0 -php_xdebug_remote_enable: 1 -php_xdebug_remote_connect_back: 1 -# Use PHPSTORM for PHPStorm, sublime.xdebug for Sublime Text. -php_xdebug_idekey: PHPSTORM -php_xdebug_max_nesting_level: 255 - -# Solr Configuration (if enabled above). -solr_version: "4.10.4" -solr_xms: "64M" -solr_xmx: "128M" - -# Selenium configuration -selenium_version: 2.46.0 diff --git a/example.docker-compose.yml b/example.docker-compose.yml new file mode 100644 index 000000000..75b0c34d6 --- /dev/null +++ b/example.docker-compose.yml @@ -0,0 +1,52 @@ +--- +version: "3" + +services: + + drupal-vm: + + # If using a custom baked image, change the name below to your image's name. + image: geerlingguy/drupal-vm + # Comment out 'image' and uncomment the line below if customizing Drupal VM + # with a project-specific Dockerfile in the same directory as this file. + # build: . + + # Set this to your project's machine name (e.g. example-com) + container_name: drupal-vm + + ports: + - 80:80 + - 443:443 + - 3306:3306 + - 8025:8025 + + # Not strictly required, but custom DNS settings can help with stability. + dns: + - '8.8.8.8' + - '8.8.4.4' + + volumes: + - ./:/var/www/drupalvm/:rw,delegated + - /var/lib/mysql + - /sys/fs/cgroup:/sys/fs/cgroup:ro + + privileged: true + command: /lib/systemd/systemd + + networks: + drupalvm: + # Set this IP address to something different if you already have another + # service running on the default IP address. If you change the subnet, + # you need to also change the bridge network IP and subnet below. + ipv4_address: 192.168.89.89 + +networks: + + # This custom network allows Drupal VM to be accessed on an IP address. + drupalvm: + driver: bridge + driver_opts: + ip: 192.168.89.1 + ipam: + config: + - subnet: "192.168.89.0/16" diff --git a/example.drupal.composer.json b/example.drupal.composer.json new file mode 100644 index 000000000..2ff33bb63 --- /dev/null +++ b/example.drupal.composer.json @@ -0,0 +1,66 @@ +{ + "name": "custom-project/drupal-vm", + "description": "", + "type": "project", + "license": "MIT", + "authors": [ + { + "name": "", + "role": "" + } + ], + "repositories": [ + { + "type": "composer", + "url": "https://packages.drupal.org/8" + } + ], + "require": { + "composer/installers": "^1.9", + "drupal/core-composer-scaffold": "^9", + "drupal/core-project-message": "^9", + "drupal/core-recommended": "^9", + "drush/drush": "^10" + }, + "conflict": { + "drupal/drupal": "*" + }, + "minimum-stability": "dev", + "prefer-stable": true, + "extra": { + "drupal-scaffold": { + "locations": { + "web-root": "web/" + } + }, + "installer-paths": { + "web/core": [ + "type:drupal-core" + ], + "web/libraries/{$name}": [ + "type:drupal-library" + ], + "web/modules/contrib/{$name}": [ + "type:drupal-module" + ], + "web/profiles/contrib/{$name}": [ + "type:drupal-profile" + ], + "web/themes/contrib/{$name}": [ + "type:drupal-theme" + ], + "drush/Commands/contrib/{$name}": [ + "type:drupal-drush" + ], + "web/modules/custom/{$name}": [ + "type:drupal-custom-module" + ], + "web/themes/custom/{$name}": [ + "type:drupal-custom-theme" + ] + } + }, + "config": { + "process-timeout": 1200 + } +} diff --git a/example.drupal.make.yml b/example.drupal.make.yml index 8c564b851..1339d477e 100644 --- a/example.drupal.make.yml +++ b/example.drupal.make.yml @@ -11,11 +11,14 @@ projects: # Core. drupal: - type: "core" - download: - # Drupal core branch (e.g. "6.x", "7.x", "8.0.x"). - branch: "8.0.x" - working-copy: true + version: "8.4.0" + # Use this if you need a working git repository of Drupal core instead of + # the latest stable. + # type: "core" + # download: + # # Drupal core branch (e.g. "6.x", "7.x", "8.3.x", "8.5.x"). + # branch: "8.4.x" + # working-copy: true # Other modules. devel: "1.x-dev" diff --git a/examples/acquia/README.md b/examples/acquia/README.md deleted file mode 100644 index cbb1ebd41..000000000 --- a/examples/acquia/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Acquia Cloud Drupal VM Configuration Example - -This directory contains example configuration changes for the default Drupal VM `example.config.yml` file which emulate the default Acquia Cloud environment with Drupal VM: - - - Ubuntu 12.04.5 LTS - - Apache 2.2.22 - - PHP 5.5.23 - - MySQL/Percona 5.5.24 - - Apache Solr 4.5.1 - -To use these overrides, copy `example.config.yml` to `config.yml` as you would normally, but make sure the variables defined in `acquia.overrides.yml` are defined with the same values in your `config.yml` file. diff --git a/examples/acquia/acquia.overrides.yml b/examples/acquia/acquia.overrides.yml deleted file mode 100644 index 1cfb9a67b..000000000 --- a/examples/acquia/acquia.overrides.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -vagrant_box: geerlingguy/ubuntu1204 -php_version: "5.5" -solr_version: "4.5.1" diff --git a/examples/prod/README.md b/examples/prod/README.md deleted file mode 100644 index cb31e308e..000000000 --- a/examples/prod/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Drupal VM Production Configuration Example - -This directory contains an example production configuration for Drupal VM which can be used to deploy Drupal VM to a production environment on a cloud provider like DigitalOcean, Linode, or AWS. - -This README file contains instructions for how you can use this configuration file to build a Drupal environment on DigitalOcean. - -## Creating a DigitalOcean Droplet - -If you don't already have a DigitalOcean account, create one (you can use geerlingguy's [affiliate link](https://www.digitalocean.com/?refcode=b9c57af84643) to sign up, otherwise, visit the normal [DigitalOcean Sign Up form](https://cloud.digitalocean.com/registrations/new). - -Make sure you have an SSH key you can use to connect to your DigitalOcean droplets, and if you don't already have one set up, or if you need to add your existing key to your account, follow the instructions in this guide: [How to use SSH keys with DigitalOcean Droplets](https://www.digitalocean.com/community/tutorials/how-to-use-ssh-keys-with-digitalocean-droplets). - -Once you are logged into DigitalOcean and have added your SSH key, click the 'Create Droplet' button on your Droplets page. For the Droplet, choose the following options: - - - **Hostname**: Choose a hostname for your site (e.g. `example.drupalvm.com`) - - **Size**: 1 GB / 1 CPU (currently $10/month; you can choose a higher plan if needed) - - **Region**: Choose whatever region is geographically nearest to you and your site visitors - - **Settings**: (Nothing here affects how Drupal VM works, choose what you'd like) - - **Image**: Choose `Ubuntu 14.04 x64` - - **Add SSH Keys**: Select the SSH key you added to your account earlier. - -Click 'Create Droplet', and wait a minute or so while the Droplet is booted. Once it's booted, make sure you can log into it from your local computer: - - ssh root@[droplet-hostname] - -(Make sure you replace `[droplet-hostname]`) with the hostname or IP address of your Droplet!) - -If you get a warning like "the authenticity of the host can't be established", answer yes to the prompt and hit enter. You should now be logged into the Droplet. Log back out by typing `exit` at the prompt and hitting return. - -Your DigitalOcean Droplet is booted and ready to have Drupal VM installed on it. - -## Customizing `config.yml` and `inventory` for production - -Just like you would with the normal `example.config.yml`, you need to copy the file to `config.yml`, then go through `prod.overrides.yml` (in this directory), and make sure to update your `config.yml`, making sure all the variables are set to match `prod.overrides.yml`. - -The changes outlined in `prod.overrides.yml` disable development-environment tools (like Pimp My Log and Adminer) and add extra security hardening configuration (via the `extra_security_enabled` variable). - -The only other thing you need to do is copy the inventory file `example.inventory` to `inventory` (so it is located at `prod/inventory`). By default, it reads: - - [drupalvm] - 1.2.3.4 ansible_ssh_user=root - -Change the host `1.2.3.4` to either the IP address or the hostname of your DigitalOcean Droplet. Remember that if you would like to use a hostname, you need to make sure that hostname actually resolves to your Droplet's IP address, either in your domain's public DNS configuration, or via your local hosts file. - -## Provisioning Drupal VM on the Droplet - -Run the following command within this project's root directory (the folder containing the `Vagrantfile`): - - ansible-playbook -i examples/prod/inventory provisioning/playbook.yml --sudo - -After a few minutes, your Drupal-VM-in-the-cloud Droplet should be fully configured to match your local development environment! You can visit your Droplet and access the fresh Drupal site just like you would locally (e.g. `http://example.drupalvm.com/`). - -## Going Further - -You may want to customize your configuration further, to make sure Drupal VM is tuned for your specific Drupal site's needs, or you may want to change things and make the server configuration more flexible, etc. For all that, the book [Ansible for DevOps](http://ansiblefordevops.com/) will give you a great introduction to using Ansible to make Drupal VM and the included Ansible configuration do exactly what you need! diff --git a/examples/prod/example.inventory b/examples/prod/example.inventory deleted file mode 100644 index a5967b064..000000000 --- a/examples/prod/example.inventory +++ /dev/null @@ -1,2 +0,0 @@ -[drupalvm] -1.2.3.4 ansible_ssh_user=root diff --git a/examples/prod/prod.overrides.yml b/examples/prod/prod.overrides.yml deleted file mode 100644 index 40b3e9b4a..000000000 --- a/examples/prod/prod.overrides.yml +++ /dev/null @@ -1,32 +0,0 @@ ---- -# Normally, this would be set to the hostname of your DigitalOcean Droplet. -drupal_domain: "drupalvm.dev" - -# Since this will be a publicly-accessible instance of Drupal VM, make sure you -# configure secure passwords, especially for Drupal and MySQL! -drupal_account_pass: admin -drupal_mysql_password: drupal -mysql_root_password: root - -# Only install extras that you will need/use on your site, and don't install -# development-related software on production environments! -installed_extras: - - memcached - # - solr - - varnish - -# Enable a more hardened security configuration. -extra_security_enabled: true - -# Restrict the firewall to only ports that are required for external services. -firewall_allowed_tcp_ports: - - "22" - - "80" - - "443" - - "8983" -firewall_log_dropped_packets: true - -# Set Apache to listen on port 81 (internal only), and Varnish on 80. -apache_listen_port: "81" -varnish_listen_port: "80" -varnish_default_backend_port: "81" diff --git a/examples/scripts/README.md b/examples/scripts/README.md new file mode 100644 index 000000000..8d91b5182 --- /dev/null +++ b/examples/scripts/README.md @@ -0,0 +1,18 @@ +# Example Scripts for Drupal VM + +## Post-Provision Scripts + +Drupal VM allows you to run extra shell scripts at the end of the provisioning process, in case you need to do extra custom setup, configure your environment, or install extra software outside the purview of Drupal VM. + +To use an extra script, configure the path to the script (relative to `provisioning/playbook.yml`) in `config.yml`: + +```yaml +post_provision_scripts: + - "../examples/post-provision.sh" +``` + +The above example results in the example `post-provision.sh` script running after the main Drupal VM setup is complete. Note that this script would run _every_ time you provision the environment (e.g. once when you run `vagrant up`, then again every time you run `vagrant provision` again). + +You can define as many scripts as you would like, and any arguments after the path will be passed to the shell script itself (e.g. `"../examples/post-provision.sh --option"`). + +Generally, you should place your post-provision scripts inside a `scripts` directory in the root of your Drupal VM project directory; this directory is gitignored, so you can continue to update Drupal VM without accidentally overwriting your scripts. diff --git a/examples/scripts/configure-solr.sh b/examples/scripts/configure-solr.sh new file mode 100755 index 000000000..b66bb3a7c --- /dev/null +++ b/examples/scripts/configure-solr.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# +# Example shell script to run post-provisioning. +# +# This script configures the default Apache Solr search core to use one of the +# Drupal Solr module's configurations. This shell script presumes you have +# `solr` in the `installed_extras`, and is currently set up for the D8 versions +# of Apache Solr Search or Search API Solr. + +SOLR_CORE_NAME="d8" +SOLR_SETUP_COMPLETE_FILE="/etc/drupal_vm_solr_config_complete_$SOLR_CORE_NAME" + +# Search API Solr module. +SOLR_DOWNLOAD="http://ftp.drupal.org/files/projects/search_api_solr-8.x-1.x-dev.tar.gz" +SOLR_DOWNLOAD_DIR="/tmp" +SOLR_MODULE_NAME="search_api_solr" +SOLR_VERSION="5.x" +SOLR_CORE_PATH="/var/solr/data/$SOLR_CORE_NAME" + +# Check to see if we've already performed this setup. +if [ ! -e "$SOLR_SETUP_COMPLETE_FILE" ]; then + # Download and expand the Solr module. + wget -qO- $SOLR_DOWNLOAD | tar xvz -C $SOLR_DOWNLOAD_DIR + + # Copy new Solr collection core with the Solr configuration provided by module. + sudo su - solr -c "/opt/solr/bin/solr create -c $SOLR_CORE_NAME -d $SOLR_DOWNLOAD_DIR/$SOLR_MODULE_NAME/solr-conf/$SOLR_VERSION/" + + # Adjust the autoCommit time so index changes are committed in 1s. + sudo sed -i 's/\(\)\([^<]*\)\(<[^>]*\)/\11000\3/g' $SOLR_CORE_PATH/conf/solrconfig.xml + + # Restart Apache Solr. + sudo service solr restart + + # Create a file to indicate this script has already run. + sudo touch $SOLR_SETUP_COMPLETE_FILE +else + exit 0 +fi diff --git a/examples/scripts/pareview.sh b/examples/scripts/pareview.sh new file mode 100755 index 000000000..820477e0e --- /dev/null +++ b/examples/scripts/pareview.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# +# Example shell script to set up PAReview.sh. +# +# You also need to adjust your `config.yml` to add in some other dependencies. +# +# ``` +# post_provision_scripts: +# - "../examples/scripts/pareview.sh" +# +# composer_global_packages: +# - { name: drupal/coder, release: '^' } +# +# nodejs_version: "6.x" +# nodejs_npm_global_packages: +# - eslint +# ``` +# +# After running `vagrant provision`, `pareview.sh` should be available anywhere +# in your Vagrant user's $PATH, so you can run commands like: +# +# $ pareview.sh /path/to/my/module +# $ pareview.sh http://git.drupal.org/project/rules.git 8.x-1.x +# +# See: https://github.com/klausi/pareviewsh + +PAREVIEW_SETUP_COMPLETE_FILE="/etc/drupal_vm_pareview_config_complete" +HOME_PATH="/home/vagrant" + +# Check to see if we've already performed this setup. +if [ ! -e "$PAREVIEW_SETUP_COMPLETE_FILE" ]; then + # Register the `Drupal` and `DrupalPractice` Standard with PHPCS. + $HOME_PATH/.composer/vendor/bin/phpcs --config-set installed_paths $HOME_PATH/.composer/vendor/drupal/coder/coder_sniffer + + # Download DrupalSecure. + git clone --branch master https://git.drupalcode.org/sandbox/coltrane-1921926.git /opt/drupalsecure_code_sniffs + + # Move the DrupalSecure directory into the PHPCS Standards. + sudo ln -sv /opt/drupalsecure_code_sniffs/DrupalSecure $HOME_PATH/.composer/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards + + # Install Codespell. + sudo apt-get install -y python-pip + pip install codespell + + # Install PAReview script. + sudo wget -O /opt/pareview.sh https://raw.githubusercontent.com/klausi/pareviewsh/7.x-1.x/pareview.sh + sudo chmod +x /opt/pareview.sh + sudo ln -s /opt/pareview.sh /usr/local/bin + + # Create a file to indicate this script has already run. + sudo touch $PAREVIEW_SETUP_COMPLETE_FILE +else + exit 0 +fi diff --git a/lib/drupalvm/vagrant.rb b/lib/drupalvm/vagrant.rb new file mode 100644 index 000000000..003648755 --- /dev/null +++ b/lib/drupalvm/vagrant.rb @@ -0,0 +1,143 @@ +# frozen_string_literal: true + +require 'yaml' + +# Cross-platform way of finding an executable in the $PATH. +def which(cmd) + exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] + ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| + exts.each do |ext| + exe = File.join(path, "#{cmd}#{ext}") + return exe if File.executable?(exe) && !File.directory?(exe) + end + end + nil +end + +# Recursively walk an tree and run provided block on each value found. +def walk(obj, &function) + if obj.is_a?(Array) + obj.map { |value| walk(value, &function) } + elsif obj.is_a?(Hash) + obj.each_pair { |key, value| obj[key] = walk(value, &function) } + else + obj = yield(obj) + end +end + +# Resolve jinja variables in hash. +def resolve_jinja_variables(vconfig) + walk(vconfig) do |value| + while value.is_a?(String) && value.match(/{{ .* }}/) + value = value.gsub(/{{ (.*?) }}/) { vconfig[Regexp.last_match(1)] } + end + value + end +end + +# Return the combined configuration content all files provided. +def load_config(files) + vconfig = {} + files.each do |config_file| + if File.exist?(config_file) + optional_config = YAML.load_file(config_file) + vconfig.merge!(optional_config) if optional_config + end + end + resolve_jinja_variables(vconfig) +end + +# Return the path to the ansible-playbook executable. +def ansible_bin + @ansible_bin ||= which('ansible-playbook') +end + +# Return the ansible version parsed from running the executable path provided. +def ansible_version + /(#{Gem::Version::VERSION_PATTERN})/.match(`#{ansible_bin} --version`) { |match| return match[1] } +end + +# Require that if installed, the ansible version meets the requirements. +def require_ansible_version(requirement) + return unless ansible_bin + + req = Gem::Requirement.new(requirement) + return if req.satisfied_by?(Gem::Version.new(ansible_version)) + + raise_message "You must install an Ansible version #{requirement} to use this version of Drupal VM." +end + +def raise_message(msg) + raise Vagrant::Errors::VagrantError.new, msg +end + +# Return which Vagrant provisioner to use. +def vagrant_provisioner + ansible_bin ? :ansible : :ansible_local +end + +def ensure_plugins(plugins) + logger = Vagrant::UI::Colored.new + installed = false + + plugins.each do |plugin| + plugin_name = plugin['name'] + manager = Vagrant::Plugin::Manager.instance + + next if manager.installed_plugins.key?(plugin_name) + + logger.warn("Installing plugin #{plugin_name}") + + manager.install_plugin( + plugin_name, + sources: plugin.fetch('source', %w[https://rubygems.org/ https://gems.hashicorp.com/]), + version: plugin['version'] + ) + + installed = true + end + + return unless installed + + logger.warn('`vagrant up` must be re-run now that plugins are installed') + exit +end + +def get_apache_vhosts(vhosts) + aliases = [] + vhosts.each do |host| + aliases.push(host['servername']) + aliases.concat(host['serveralias'].split) if host['serveralias'] + end + aliases +end + +def get_nginx_vhosts(vhosts) + aliases = [] + vhosts.each do |host| + aliases.push(host['server_name']) + aliases.concat(host['server_name_redirect'].split) if host['server_name_redirect'] + end + aliases +end + +# Return a list of all virtualhost server names and aliases from a config hash. +def get_vhost_aliases(vconfig) + if vconfig['drupalvm_webserver'] == 'apache' + aliases = get_apache_vhosts(vconfig['apache_vhosts']) + else + # @todo shim for `nginx_hosts`. + aliases = get_nginx_vhosts(vconfig.fetch('nginx_hosts', vconfig['nginx_vhosts'])) + end + aliases = aliases.uniq - [vconfig['vagrant_ip']] + # Remove wildcard subdomains. + aliases.delete_if { |vhost| vhost.include?('*') } +end + +# Return a default post_up_message. +def get_default_post_up_message(vconfig) + 'Your Drupal VM Vagrant box is ready to use!'\ + "\n* Visit the dashboard for an overview of your site: http://dashboard.#{vconfig['vagrant_hostname']} (or http://#{vconfig['vagrant_ip']})"\ + "\n* You can SSH into your machine with `vagrant ssh`."\ + "\n* Find out more in the Drupal VM documentation at http://docs.drupalvm.com" +end diff --git a/mkdocs.yml b/mkdocs.yml index 028095faa..7b71f1cfe 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,36 +1,77 @@ +--- site_name: Drupal VM Documentation repo_url: https://github.com/geerlingguy/drupal-vm site_description: 'Drupal VM - A VM for local Drupal development, built with Vagrant + Ansible' theme: readthedocs +extra_javascript: + - js/fix_search.js + markdown_extensions: - toc: - permalink: True + permalink: true pages: - Home: 'index.md' - - Drupal Deployment Strategies: - - 'Drush Make file': 'deployment/drush-make.md' - - 'Local Drupal codebase': 'deployment/local-codebase.md' - - 'Drupal multisite': 'deployment/multisite.md' - - Extra Software and Setup: - - 'Syncing Folders': 'extras/syncing-folders.md' - - 'Connect to the MySQL Database': 'extras/mysql.md' - - 'Use Apache Solr for Search': 'extras/solr.md' - - 'Use Drush with Drupal VM': 'extras/drush.md' - - 'Use Drupal Console with Drupal VM': 'extras/drupal-console.md' - - 'Use Varnish with Drupal VM': 'extras/varnish.md' - - 'Use MariaDB instead of MySQL': 'extras/mariadb.md' - - 'View Logs with Pimp my Log': 'extras/pimpmylog.md' - - 'Profile Code with XHProf': 'extras/xhprof.md' - - 'Debug Code with XDebug': 'extras/xdebug.md' - - 'Catch Emails with MailHog': 'extras/mailhog.md' - - 'Test with Behat and Selenium': 'extras/behat.md' + - Getting Started: + - Installation: + - 'macOS': 'getting-started/installation-macos.md' + - 'Windows': 'getting-started/installation-windows.md' + - 'Linux': 'getting-started/installation-linux.md' + - 'Configuring Drupal VM': 'getting-started/configure-drupalvm.md' + - 'Syncing Folders': 'getting-started/syncing-folders.md' + - Building your codebase: + - 'Using a local Drupal codebase': 'deployment/local-codebase.md' + - 'Using a composer package': 'deployment/composer-package.md' + - 'Using composer.json': 'deployment/composer.md' + - 'Using a Drush Make file': 'deployment/drush-make.md' + - 'Drupal VM as a Composer Dependency': 'deployment/composer-dependency.md' + - 'Deploying Drupal via Git': 'deployment/git.md' + - Basic configurations: + - 'Using different base OSes': 'configurations/base-os.md' + - 'Using a different PHP version': 'configurations/php.md' + - Webservers: + - 'Apache': 'configurations/webservers-apache.md' + - 'Nginx': 'configurations/webservers-nginx.md' + - Databases: + - 'Connect to the MySQL Database': 'configurations/databases-mysql.md' + - 'Use MariaDB instead of MySQL': 'configurations/databases-mariadb.md' + - 'Use PostgreSQL instead of MySQL': 'configurations/databases-postgresql.md' + - Installed extras: + - 'adminer (Database UI)': 'extras/adminer.md' + - 'blackfire (Profiling tool)': 'extras/blackfire.md' + - 'drupalconsole (Drupal CLI)': 'extras/drupal-console.md' + - 'drush (Drupal CLI)': 'extras/drush.md' + - 'elasticsearch (Search engine)': 'extras/elasticsearch.md' + - 'java': 'extras/java.md' + - 'mailhog (Mail catcher)': 'extras/mailhog.md' + - 'memcached (In-memory cache)': 'extras/memcached.md' + - 'newrelic (Performance monitoring)': 'extras/newrelic.md' + - 'nodejs': 'extras/nodejs.md' + - 'redis (In-memory database)': 'extras/redis.md' + - 'ruby': 'extras/ruby.md' + - 'selenium (BDD with Behat)': 'extras/selenium.md' + - 'solr (Search engine)': 'extras/solr.md' + - 'tideways (Profiling tool)': 'extras/tideways.md' + - 'upload-progress': 'extras/upload-progress.md' + - 'varnish (Caching reverse proxy)': 'extras/varnish.md' + - 'xdebug (Debugging tool)': 'extras/xdebug.md' + - 'xhprof (Profiling tool)': 'extras/xhprof.md' + - Extending Drupal VM: + - 'Adding Vagrant plugins Vagrantfile.local': 'extending/vagrantfile.md' + - 'Passing on CLI arguments to ansible': 'extending/ansible-args.md' + - 'Pre- and Post-Provision Scripts': 'extending/scripts.md' - Other Information: - - 'Using Different Base OSes': 'other/base-os.md' - - 'PHP 7 on Drupal VM': 'other/php-7.md' - - 'Drupal 6 Notes': 'other/drupal-6.md' - - 'Windows Notes': 'other/windows.md' - - 'Cloning Drupal VM with newd': 'other/cloning-with-newd.md' - - 'Vagrant and VirtualBox Tips': 'other/vagrant-virtualbox.md' + - 'Networking Notes': 'other/networking.md' + - 'Vagrant LXC provider': 'other/vagrant-lxc.md' + - 'Improving Performance': 'other/performance.md' + - 'Docker': 'other/docker.md' + - 'Custom Vagrant Base Box': 'other/custom-base-box.md' + - 'BigPipe with Drupal VM': 'other/bigpipe.md' + - 'Drupal multisite': 'deployment/multisite.md' + - 'Drupal 6 Notes': 'other/drupal-6.md' + - 'Drupal VM Management Tools': 'other/management-tools.md' + - 'Emulating Acquia Cloud environment': 'other/acquia.md' + - 'Deploying to a production environment': 'other/production.md' + - 'Wordpress or other applications': 'other/wordpress-other-applications.md' diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml new file mode 100644 index 000000000..d4f2679e2 --- /dev/null +++ b/molecule/default/converge.yml @@ -0,0 +1,37 @@ +--- +- name: Converge + hosts: all + become: true + + tasks: + - name: Update apt cache. + apt: + update_cache: true + cache_valid_time: 1200 + when: ansible_os_family == 'Debian' + + - name: Install test dependencies (RedHat). + package: + name: logrotate + state: present + when: ansible_os_family == 'RedHat' + + - name: Configure override vars (all). + set_fact: + # Update the composer_home_path for global installs. + composer_home_path: "/root/.composer" + + # Don't run the 'disable firewall' tasks in tests. + firewall_disable_firewalld: false + firewall_disable_ufw: false + + # Added to prevent test failures in CI. + firewall_enable_ipv6: false + hostname_configure: false + + - name: Configure test vars (RedHat). + set_fact: + postfix_inet_protocols: ipv4 + when: ansible_os_family == 'RedHat' + +- import_playbook: ../../provisioning/playbook.yml diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml new file mode 100644 index 000000000..04169a846 --- /dev/null +++ b/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu1804}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/molecule/default/ubuntu1804-php74.config.yml b/molecule/default/ubuntu1804-php74.config.yml new file mode 100644 index 000000000..736d0e6a8 --- /dev/null +++ b/molecule/default/ubuntu1804-php74.config.yml @@ -0,0 +1,4 @@ +--- +php_version: "7.4" +php_sendmail_path: "/usr/sbin/sendmail -t -i" +installed_extras: [] diff --git a/molecule/default/ubuntu1804-postgresql.config.yml b/molecule/default/ubuntu1804-postgresql.config.yml new file mode 100644 index 000000000..573d78e13 --- /dev/null +++ b/molecule/default/ubuntu1804-postgresql.config.yml @@ -0,0 +1,4 @@ +--- +drupal_db_backend: pgsql +php_sendmail_path: "/usr/sbin/sendmail -t -i" +installed_extras: [] diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml new file mode 100644 index 000000000..58a5c8477 --- /dev/null +++ b/molecule/default/verify.yml @@ -0,0 +1,48 @@ +--- +- name: Verify + hosts: all + become: true + + vars: + drupal_vm_hostname: drupalvm.test + drupal_composer_install_dir: /var/www/drupalvm/drupal + + tasks: + - name: Validate web services are up and running. + uri: + url: http://localhost{{ item.port | default('') }} + headers: + Host: "{{ item.host_prefix }}{{ drupal_vm_hostname }}" + return_content: true + register: response + failed_when: item.expected_content not in response.content + with_items: + - name: Drupal + host_prefix: "" + expected_content: "Welcome to Drupal" + - name: Dashboard + host_prefix: "dashboard." + expected_content: "Vagrant + Ansible" + - name: Adminer + host_prefix: "adminer." + expected_content: "<title>Login - Adminer" + - name: MailHog + host_prefix: "" + port: ":8025" + expected_content: "<title>MailHog" + + - name: Validate Varnish is up and running. + uri: + url: http://localhost:81 + headers: + Host: "{{ drupal_vm_hostname }}" + register: varnish_response + failed_when: "'varnish' not in varnish_response.via" + + - name: Validate Drush is working with Drupal. + command: > + vendor/bin/drush status + chdir={{ drupal_composer_install_dir }} + register: drush_result + changed_when: false + failed_when: "'Drupal bootstrap : Successful' not in drush_result.stdout" diff --git a/provisioning/JJG-Ansible-Windows/README.md b/provisioning/JJG-Ansible-Windows/README.md deleted file mode 100644 index f3406ba45..000000000 --- a/provisioning/JJG-Ansible-Windows/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# JJG-Ansible-Windows - -Windows shell provisioning script to bootstrap Ansible from within a Vagrant VM running on Windows. - -This script is configured to use configure any Linux-based VM (Debian, Ubuntu, Fedora, RedHat, CentOS, etc.) so it can run Ansible playbooks from within the VM through Vagrant. - -Read more about this script, and other techniques for using Ansible within a Windows environment, on Server Check.in: [Running Ansible within Windows](https://servercheck.in/blog/running-ansible-within-windows). - -## Usage - -In your Vagrantfile, use a conditional provisioning statement if you want to use this script (which runs Ansible from within the VM instead of on your host—this example assumes your playbook is inside within a 'provisioning' folder, and this script is within provisioning/JJG-Ansible-Windows): - -```ruby -# Use rbconfig to determine if we're on a windows host or not. -require 'rbconfig' -is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/) -if is_windows - # Provisioning configuration for shell script. - config.vm.provision "shell" do |sh| - sh.path = "provisioning/JJG-Ansible-Windows/windows.sh" - sh.args = "provisioning/playbook.yml" - end -else - # Provisioning configuration for Ansible (for Mac/Linux hosts). - config.vm.provision "ansible" do |ansible| - ansible.playbook = "provisioning/playbook.yml" - ansible.sudo = true - end -end -``` - -Note that the `windows.sh` script will run within the VM and will run the given playbook against localhost with `--connection=local` inside the VM. You shouldn't/can't pass a custom inventory file to the script, as you can using Vagrant's Ansible provisioner. - -### Role Requirements File - -If your playbook requires roles to be installed which are not present in a `roles` directory within the playbook's directory, then you should add the roles to a [role requirements](http://docs.ansible.com/galaxy.html#advanced-control-over-role-requirements-files) file. Place the resulting `requirements.txt` or `requirements.yml` file in the same directory as your playbook, and the roles will be installed automatically. - -## Licensing and More Info - -Created by [Jeff Geerling](http://jeffgeerling.com/) in 2014. Licensed under the MIT license; see the LICENSE file for more info. diff --git a/provisioning/JJG-Ansible-Windows/windows.sh b/provisioning/JJG-Ansible-Windows/windows.sh deleted file mode 100644 index 9ef898bae..000000000 --- a/provisioning/JJG-Ansible-Windows/windows.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash -# -# Windows shell provisioner for Ansible playbooks, based on KSid's -# windows-vagrant-ansible: https://github.com/KSid/windows-vagrant-ansible -# -# @see README.md -# @author Jeff Geerling, 2014 - -# Uncomment if behind a proxy server. -# export {http,https,ftp}_proxy='http://username:password@proxy-host:80' - -ANSIBLE_PLAYBOOK=$1 -PLAYBOOK_DIR=${ANSIBLE_PLAYBOOK%/*} - -# Detect package management system. -YUM=$(which yum 2>/dev/null) -APT_GET=$(which apt-get 2>/dev/null) - -# Make sure Ansible playbook exists. -if [ ! -f "/vagrant/$ANSIBLE_PLAYBOOK" ]; then - echo "Cannot find Ansible playbook." - exit 1 -fi - -# Install Ansible and its dependencies if it's not installed already. -if ! command -v ansible >/dev/null; then - echo "Installing Ansible dependencies and Git." - if [[ ! -z ${YUM} ]]; then - yum install -y git python python-devel - elif [[ ! -z ${APT_GET} ]]; then - apt-get install -y git python python-dev - else - echo "Neither yum nor apt-get are available." - exit 1; - fi - - echo "Installing pip via easy_install." - wget https://raw.githubusercontent.com/ActiveState/ez_setup/v0.9/ez_setup.py - python ez_setup.py && rm -f ez_setup.py - easy_install pip - # Make sure setuptools are installed crrectly. - pip install setuptools --no-use-wheel --upgrade - - echo "Installing required python modules." - pip install paramiko pyyaml jinja2 markupsafe - - echo "Installing Ansible." - pip install ansible -fi - -# Install requirements. -echo "Installing Ansible roles from requirements file, if available." -find "/vagrant/$PLAYBOOK_DIR" \( -name "requirements.yml" -o -name "requirements.txt" \) -exec sudo ansible-galaxy install -r {} \; - -# Run the playbook. -echo "Running Ansible provisioner defined in Vagrantfile." -ansible-playbook -i 'localhost,' "/vagrant/${ANSIBLE_PLAYBOOK}" --extra-vars "is_windows=true" --connection=local diff --git a/provisioning/README.md b/provisioning/README.md new file mode 100644 index 000000000..6f3eedb02 --- /dev/null +++ b/provisioning/README.md @@ -0,0 +1,15 @@ +# Drupal VM - Ansible Provisioning + +Drupal VM uses the Ansible provisioner to build all the software that runs and supplements Drupal sites. + +The Ansible configuration uses a variety of open source community-maintained Ansible Roles that are hosted on Ansible Galaxy, but Drupal VM includes the roles in the codebase for efficiency's sake. + +**You should NOT make any manual changes to the roles in the `roles` directory**, but rather, contribute to the upstream roles corresponding to the role's folder name (e.g. for issues with the `geerlingguy.apache` role, see the [`geerlingguy.apache`](https://galaxy.ansible.com/geerlingguy/apache/) role page on Ansible Galaxy, and the role's [issue tracker on GitHub](https://github.com/geerlingguy/ansible-role-apache/issues)). + +## Adding and Updating Galaxy roles + +From time to time, third party roles need to be added or updated to enable new Drupal VM functionality or fix bugs. To update a role (e.g. `geerlingguy.apache`), find the role's `version` setting inside `requirements.yml`, bump the version to the required or latest version of the role, then run the following command _in the same directory as this README file_: + + $ ansible-galaxy install -r requirements.yml --force + +Then commit the updated `requirements.yml` file and the new and updated files within the `roles` directory in a new PR to the Drupal VM project. diff --git a/provisioning/ansible.cfg b/provisioning/ansible.cfg new file mode 100644 index 000000000..4b1740edf --- /dev/null +++ b/provisioning/ansible.cfg @@ -0,0 +1,6 @@ +[defaults] +roles_path = ./roles + +[ssh_connection] +pipelining = True +control_path = /tmp/ansible-ssh-%%h-%%p-%%r diff --git a/provisioning/docker/bake.sh b/provisioning/docker/bake.sh new file mode 100755 index 000000000..53c5bf4ca --- /dev/null +++ b/provisioning/docker/bake.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# +# Bake a Docker container with Drupal VM. + +# Exit on any individual command failure. +set -e + +# Set variables. +DRUPALVM_IP_ADDRESS="${DRUPALVM_IP_ADDRESS:-192.168.89.89}" +DRUPALVM_MACHINE_NAME="${DRUPALVM_MACHINE_NAME:-drupal-vm}" +DRUPALVM_HOSTNAME="${DRUPALVM_HOSTNAME:-localhost}" +DRUPALVM_PROJECT_ROOT="${DRUPALVM_PROJECT_ROOT:-/var/www/drupalvm}" + +DRUPALVM_HTTP_PORT="${DRUPALVM_HTTP_PORT:-80}" +DRUPALVM_HTTPS_PORT="${DRUPALVM_HTTPS_PORT:-443}" + +DISTRO="${DISTRO:-ubuntu1804}" +TAG="${TAG:-latest}" +OPTS="${OPTS:---privileged}" +INIT="${INIT:-/lib/systemd/systemd}" + +# Helper function to colorize statuses. +function status() { + status=$1 + printf "\n" + echo -e -n "\033[32m$status" + echo -e '\033[0m' +} + +# Set volume options. +if [[ "$OSTYPE" == "darwin"* ]]; then + volume_opts='rw,cached' +else + volume_opts='rw' +fi + +# Run the container. +status "Bringing up Docker container..." +docker run --name=$DRUPALVM_MACHINE_NAME -d \ + --add-host "$DRUPALVM_HOSTNAME drupalvm":127.0.0.1 \ + -v $PWD:$DRUPALVM_PROJECT_ROOT/:$volume_opts \ + -p $DRUPALVM_IP_ADDRESS:$DRUPALVM_HTTP_PORT:80 \ + -p $DRUPALVM_IP_ADDRESS:$DRUPALVM_HTTPS_PORT:443 \ + $OPTS \ + geerlingguy/docker-$DISTRO-ansible:$TAG \ + $INIT + +# Create Drupal directory. +docker exec $DRUPALVM_MACHINE_NAME mkdir -p $DRUPALVM_PROJECT_ROOT/drupal + +# Set things up and run the Ansible playbook. +status "Running setup playbook..." +docker exec --tty $DRUPALVM_MACHINE_NAME env TERM=xterm \ + ansible-playbook $DRUPALVM_PROJECT_ROOT/tests/test-setup.yml + +status "Provisioning Drupal VM inside Docker container..." +docker exec $DRUPALVM_MACHINE_NAME env TERM=xterm ANSIBLE_FORCE_COLOR=true \ + ansible-playbook $DRUPALVM_PROJECT_ROOT/provisioning/playbook.yml + +status "...done!" +status "Visit the Drupal VM dashboard: http://$DRUPALVM_IP_ADDRESS:$DRUPALVM_HTTP_PORT" diff --git a/provisioning/docker/bin/install-drupal b/provisioning/docker/bin/install-drupal new file mode 100755 index 000000000..ef2637f0f --- /dev/null +++ b/provisioning/docker/bin/install-drupal @@ -0,0 +1,33 @@ +#!/bin/bash +# +# Install a Drupal site with Drush. +# +# Usage: +# install-drupal [version] +# [version] is optional, defaults to 8.x-dev. Can switch to 7.x-dev if needed. + +# Exit on any individual command failure. +set -e + +# Setup. +DRUPAL_VERSION="${1:-8.x-dev}" +PROJECT_PATH='/var/www/drupalvm' + +# Create Drupal project directory. +mkdir -p $PROJECT_PATH + +# Create a Drupal project. +echo "Downloading Drupal $DRUPAL_VERSION" +cd $PROJECT_PATH +COMPOSER_ALLOW_SUPERUSER=1 composer create-project drupal-composer/drupal-project:$DRUPAL_VERSION drupal --stability dev --no-interaction + +# Install Drupal with Drush. +echo "Installing Drupal" +cd drupal/web +drush si standard --root=$PROJECT_PATH/drupal/web -y \ + --db-url='mysql://drupal:drupal@localhost/drupal' \ + --site-name='Drupal VM' \ + --account-name=admin --account-pass=admin + +# Set appropriate permissions. +chown -R www-data:www-data $PROJECT_PATH diff --git a/provisioning/docker/load-image.sh b/provisioning/docker/load-image.sh new file mode 100755 index 000000000..33dd58c20 --- /dev/null +++ b/provisioning/docker/load-image.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# +# Load a Docker image from an archive (tar). +# +# Required configuration (in config.yml): +# +# docker_image_name: drupal-vm +# docker_image_path: ~/Downloads +# + +# Exit on any individual command failure. +set -e + +# Include YAML parser. +source provisioning/docker/parse-yaml.sh + +# Pretty colors. +red='\033[0;31m' +green='\033[0;32m' +neutral='\033[0m' + +# Set variables, read from config.yml if available. +# TODO: This could definitely be more intelligent! +if [ -f 'config.yml' ]; then + image_name=$(parse_yaml config.yml docker_image_name) + image_path=$(parse_yaml config.yml docker_image_path) +else + image_name=$(parse_yaml default.config.yml docker_image_name) + image_path=$(parse_yaml default.config.yml docker_image_path) +fi + +image_full_path="$image_path/$image_name.tar.gz" +image_full_path=${image_full_path/#\~/$HOME} # Expand ~ to $HOME. + +# Load the image. +printf "\n"${green}"Loading Docker image..."${neutral}"\n" +gunzip -c $image_full_path | docker load +printf ${green}"...done!"${neutral}"\n" diff --git a/provisioning/docker/parse-yaml.sh b/provisioning/docker/parse-yaml.sh new file mode 100755 index 000000000..38f9be0f2 --- /dev/null +++ b/provisioning/docker/parse-yaml.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# +# Parse a YAML file. +# +# Usage: +# parse_yaml [file-path] [variable-to-retrieve] +# +# Requires ruby. +# @see https://coderwall.com/p/bm_tpa/reading-yaml-files-in-bash-with-ruby +# @todo Consider using PHP so user doesn't need to install Ruby. + +function parse_yaml { + ruby -ryaml -e 'puts ARGV[1..-1].inject(YAML.load(File.read(ARGV[0]))) {|acc, key| acc[key] }' "$@" +} diff --git a/provisioning/docker/save-image.sh b/provisioning/docker/save-image.sh new file mode 100755 index 000000000..eb3fc71a4 --- /dev/null +++ b/provisioning/docker/save-image.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# +# Commit a Docker image and save it to an archive (tar). +# +# Required configuration (in config.yml): +# +# docker_container_name: drupal-vm +# docker_image_name: drupal-vm +# docker_image_path: ~/Downloads +# + +# Exit on any individual command failure. +set -e + +# Include YAML parser. +source provisioning/docker/parse-yaml.sh + +# Pretty colors. +red='\033[0;31m' +green='\033[0;32m' +neutral='\033[0m' + +# Set variables, read from config.yml if available. +# TODO: This could definitely be more intelligent! +if [ -f 'config.yml' ]; then + container_name=$(parse_yaml config.yml docker_container_name) + image_name=$(parse_yaml config.yml docker_image_name) + image_path=$(parse_yaml config.yml docker_image_path) +else + container_name=$(parse_yaml default.config.yml docker_container_name) + image_name=$(parse_yaml default.config.yml docker_image_name) + image_path=$(parse_yaml default.config.yml docker_image_path) +fi + +image_full_path="$image_path/$image_name.tar.gz" +image_full_path="${image_full_path/#\~/$HOME}" # Expand ~ to $HOME. + +# Save the image. +printf "\n"${green}"Saving Docker container to $image_full_path..."${neutral}"\n" +docker commit $container_name $image_name +docker save $image_name | gzip -1 > $image_full_path +printf ${green}"...done!"${neutral}"\n" diff --git a/provisioning/docker/vars/docker-hub-overrides.yml b/provisioning/docker/vars/docker-hub-overrides.yml new file mode 100644 index 000000000..b345f0f6f --- /dev/null +++ b/provisioning/docker/vars/docker-hub-overrides.yml @@ -0,0 +1,14 @@ +--- +hostname_configure: false +firewall_enabled: false +installed_extras: + - adminer + - drush + - mailhog + # - varnish + +# Don't build or install Drupal inside the container. +drupal_build_makefile: false +drupal_build_composer: false +drupal_build_composer_project: false +drupal_install_site: false diff --git a/provisioning/playbook.yml b/provisioning/playbook.yml index 3b07db67b..e8427ecaa 100644 --- a/provisioning/playbook.yml +++ b/provisioning/playbook.yml @@ -1,63 +1,133 @@ --- - hosts: all + become: yes vars_files: - - ../config.yml + - vars/main.yml + - ../default.config.yml pre_tasks: - - include: tasks/init-debian.yml - when: ansible_os_family == 'Debian' - - include: tasks/init-redhat.yml - when: ansible_os_family == 'RedHat' + - import_tasks: tasks/config.yml + tags: ['always'] + + - import_tasks: tasks/app-toggles.yml + tags: ['always'] + + - import_tasks: tasks/backwards-compatibility.yml + tags: ['always'] + + - include_tasks: "tasks/init-{{ ansible_os_family }}.yml" + + - name: Run configured pre-provision shell scripts. + script: "{{ item }}" + with_items: "{{ pre_provision_scripts|default([]) }}" + + - name: Run configured pre-provision ansible task files. + include_tasks: "{{ outer_item }}" + loop_control: + loop_var: outer_item + with_fileglob: "{{ pre_provision_tasks_dir|default(omit) }}" + + - import_tasks: tasks/php.yml roles: # Essential roles. - - { role: geerlingguy.repo-remi, when: ansible_os_family == 'RedHat' } - - geerlingguy.firewall - - geerlingguy.git - - geerlingguy.apache - - geerlingguy.mysql - - geerlingguy.php - - geerlingguy.php-pecl - - geerlingguy.php-mysql - - geerlingguy.composer - - geerlingguy.drush - - { role: geerlingguy.drupal-console, when: drupal_major_version > 7 } + - { role: geerlingguy.repo-epel, when: ansible_os_family == 'RedHat' } + - { role: geerlingguy.repo-remi, when: ansible_os_family == 'RedHat', tags: ['webserver', 'php'] } + - { role: drupalvm.hostname, when: hostname_configure } + - { role: drupalvm.vagrant-nfs-fix, when: vagrant_nfs_fix_enabled } + - { role: geerlingguy.firewall, when: firewall_enabled } + - { role: geerlingguy.git } + - { role: geerlingguy.postfix } + - { role: geerlingguy.apache, when: drupalvm_webserver == 'apache', tags: ['webserver'] } + - { role: geerlingguy.apache-php-fpm, when: drupalvm_webserver == 'apache', tags: ['webserver'] } + - { role: geerlingguy.nginx, when: drupalvm_webserver == 'nginx', tags: ['webserver'] } + - { role: geerlingguy.php-versions, when: php_version != '', tags: ['php', 'xdebug', 'database'] } + - { role: geerlingguy.php, tags: ['php'] } + - { role: geerlingguy.php-pecl, tags: ['php'] } + - { role: geerlingguy.composer } + - { role: geerlingguy.mysql, when: drupal_db_backend == 'mysql', tags: ['database'] } + - { role: geerlingguy.php-mysql, when: drupal_db_backend == 'mysql', tags: ['php', 'database'] } + - { role: geerlingguy.postgresql, when: drupal_db_backend == 'pgsql', tags: ['database'] } + - { role: geerlingguy.php-pgsql, when: drupal_db_backend == 'pgsql', tags: ['php', 'database'] } # Conditionally-installed roles. + - { role: geerlingguy.drupal-console, when: 'drupal_major_version > 7 and "drupalconsole" in installed_extras' } + - { role: geerlingguy.drush, when: '"drush" in installed_extras' } - { role: geerlingguy.memcached, when: '"memcached" in installed_extras' } - - { role: geerlingguy.php-memcached, when: '"memcached" in installed_extras' } - - { role: geerlingguy.php-xdebug, when: '"xdebug" in installed_extras' } - - { role: geerlingguy.php-xhprof, when: '"xhprof" in installed_extras' } - - { role: geerlingguy.adminer, when: '"adminer" in installed_extras' } - - { role: geerlingguy.pimpmylog, when: '"pimpmylog" in installed_extras' } + - { role: geerlingguy.php-memcached, when: '"memcached" in installed_extras', tags: ['php'] } + + - role: geerlingguy.php-tideways + workspace: "/root/php{{ php_version }}" + when: '"tideways" in installed_extras' + tags: ['php'] + + - role: geerlingguy.php-xdebug + workspace: "/root/php{{ php_version }}" + when: '"xdebug" in installed_extras' + tags: ['php', 'xdebug'] + + - role: geerlingguy.php-xhprof + workspace: "/root/php{{ php_version }}" + when: '"xhprof" in installed_extras' + tags: ['php'] + + - role: thom8.php-upload-progress + workspace: "/root/php{{ php_version }}" + when: '"upload-progress" in installed_extras' + tags: ['php'] + + - { role: geerlingguy.blackfire, when: '"blackfire" in installed_extras' } + - { role: geerlingguy.adminer, when: '"adminer" in installed_extras', tags: ['database'] } - { role: geerlingguy.daemonize, when: '"mailhog" in installed_extras' } - { role: geerlingguy.mailhog, when: '"mailhog" in installed_extras' } - - { role: geerlingguy.java, when: '"solr" or "selenium" in installed_extras' } + - { role: weareinteractive.newrelic, when: '"newrelic" in installed_extras' } + - { role: geerlingguy.nodejs, when: '"nodejs" in installed_extras' } + - { role: geerlingguy.redis, when: '"redis" in installed_extras' } + - { role: geerlingguy.php-redis, when: '"redis" in installed_extras', tags: ['php'] } + - { role: geerlingguy.ruby, when: '"ruby" in installed_extras' } + + - role: geerlingguy.java + when: > + "java" in installed_extras or + "solr" in installed_extras or + "selenium" in installed_extras or + "elasticsearch" in installed_extras + - { role: arknoll.selenium, when: '"selenium" in installed_extras' } - { role: geerlingguy.solr, when: '"solr" in installed_extras' } + - { role: geerlingguy.elasticsearch, when: '"elasticsearch" in installed_extras' } - { role: geerlingguy.varnish, when: '"varnish" in installed_extras' } + - { role: drupalvm.www, tags: ['webserver'] } + - { role: geerlingguy.drupal, tags: ['drupal'] } # Roles for security and stability on production. - { role: geerlingguy.security, when: extra_security_enabled } tasks: - - name: Check if Drupal is already set up. - stat: "path={{ drupal_core_path }}/index.php" - register: drupal_site + - import_tasks: tasks/sshd.yml + - import_tasks: tasks/extras.yml + + - include_tasks: tasks/apparmor.yml + when: ansible_os_family == 'Debian' and drupal_db_backend == 'mysql' + tags: ['database'] + + - include_tasks: tasks/drush-aliases.yml + when: configure_drush_aliases - - include: tasks/extras.yml - - include: tasks/www.yml - - include: tasks/apparmor.yml - when: ansible_os_family == 'Debian' + - import_tasks: tasks/cron.yml + tags: ['cron'] - # Build makefile if configured. - - include: tasks/build-makefile.yml - when: build_makefile + - include_tasks: tasks/dashboard.yml + when: dashboard_install_dir is defined and dashboard_install_dir != '' + tags: ['webserver', 'database', 'php'] - # Install site if configured. - - include: tasks/install-site.yml - when: install_site + - name: Run configured post-provision shell scripts. + script: "{{ item }}" + with_items: "{{ post_provision_scripts|default([]) }}" - - include: tasks/drush-aliases.yml - - include: tasks/cron.yml + - name: Run configured post-provision ansible task files. + include_tasks: "{{ outer_item }}" + loop_control: + loop_var: outer_item + with_fileglob: "{{ post_provision_tasks_dir|default(omit) }}" diff --git a/provisioning/requirements.txt b/provisioning/requirements.txt deleted file mode 100644 index d7e067f24..000000000 --- a/provisioning/requirements.txt +++ /dev/null @@ -1,24 +0,0 @@ -arknoll.selenium -geerlingguy.adminer -geerlingguy.apache -geerlingguy.composer -geerlingguy.daemonize -geerlingguy.drupal-console -geerlingguy.drush -geerlingguy.firewall -geerlingguy.git -geerlingguy.java -geerlingguy.mailhog -geerlingguy.memcached -geerlingguy.mysql -geerlingguy.php -geerlingguy.php-memcached -geerlingguy.php-mysql -geerlingguy.php-pecl -geerlingguy.php-xdebug -geerlingguy.php-xhprof -geerlingguy.pimpmylog -geerlingguy.repo-remi -geerlingguy.security -geerlingguy.solr -geerlingguy.varnish diff --git a/provisioning/requirements.yml b/provisioning/requirements.yml new file mode 100644 index 000000000..c01added6 --- /dev/null +++ b/provisioning/requirements.yml @@ -0,0 +1,82 @@ +--- +roles: + - name: arknoll.selenium + version: 2.2.2 + - name: thom8.php-upload-progress + version: 1.0.1 + - name: weareinteractive.newrelic + version: 1.8.0 + - name: geerlingguy.adminer + version: 1.3.1 + - name: geerlingguy.apache + version: 3.2.0 + - name: geerlingguy.apache-php-fpm + version: 1.1.0 + - name: geerlingguy.blackfire + version: 1.1.3 + - name: geerlingguy.composer + version: 1.9.0 + - name: geerlingguy.daemonize + version: 1.2.2 + - name: geerlingguy.drupal + version: 4.3.0 + - name: geerlingguy.drupal-console + version: 1.1.1 + - name: geerlingguy.drush + version: 3.3.0 + - name: geerlingguy.elasticsearch + version: 5.1.0 + - name: geerlingguy.firewall + version: 2.5.0 + - name: geerlingguy.git + version: 3.0.0 + - name: geerlingguy.java + version: 1.10.0 + - name: geerlingguy.mailhog + version: 2.2.0 + - name: geerlingguy.memcached + version: 2.2.0 + - name: geerlingguy.mysql + version: 3.3.2 + - name: geerlingguy.nginx + version: 3.1.0 + - name: geerlingguy.nodejs + version: 6.0.0 + - name: geerlingguy.php + version: 4.7.0 + - name: geerlingguy.php-memcached + version: 2.0.2 + - name: geerlingguy.php-mysql + version: 2.1.0 + - name: geerlingguy.php-pecl + version: 2.0.0 + - name: geerlingguy.php-pgsql + version: 1.0.1 + - name: geerlingguy.php-redis + version: 3.2.1 + - name: geerlingguy.php-tideways + version: 2.2.0 + - name: geerlingguy.php-versions + version: 5.0.0 + - name: geerlingguy.php-xdebug + version: 3.0.0 + - name: geerlingguy.php-xhprof + version: 3.0.0 + - name: geerlingguy.postfix + version: 2.0.0 + - name: geerlingguy.postgresql + version: 3.1.1 + - name: geerlingguy.redis + version: 1.7.0 + - name: geerlingguy.repo-epel + version: 3.1.0 + - name: geerlingguy.repo-remi + version: 2.0.1 + - name: geerlingguy.ruby + version: 3.0.0 + - name: geerlingguy.security + version: 2.0.1 + - name: geerlingguy.solr + version: 5.3.1 + - name: geerlingguy.varnish + version: 3.3.0 diff --git a/provisioning/roles/arknoll.selenium/.gitignore b/provisioning/roles/arknoll.selenium/.gitignore new file mode 100644 index 000000000..7b8cfb120 --- /dev/null +++ b/provisioning/roles/arknoll.selenium/.gitignore @@ -0,0 +1,24 @@ +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +Icon? +ehthumbs.db +Thumbs.db + +# IDE files # +################# +/.settings +/.buildpath +/.project +/nbproject +*.komodoproject +*.kpf +/.idea + +# Other files # +############### +!empty diff --git a/provisioning/roles/arknoll.selenium/.travis.yml b/provisioning/roles/arknoll.selenium/.travis.yml new file mode 100644 index 000000000..6741ad76f --- /dev/null +++ b/provisioning/roles/arknoll.selenium/.travis.yml @@ -0,0 +1,22 @@ +--- +services: docker + +env: + - distro: centos7 + - distro: centos6 + - distro: ubuntu1604 + - distro: debian8 + - distro: ubuntu1404 + - distro: ubuntu1204 + +script: + # Download test shim. + - wget -O ${PWD}/tests/test.sh https://gist.githubusercontent.com/geerlingguy/73ef1e5ee45d8694570f334be385e181/raw/ + - chmod +x ${PWD}/tests/test.sh + + # Run tests. + - ${PWD}/tests/test.sh + +notifications: + email: false + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/arknoll.selenium/LICENSE.txt b/provisioning/roles/arknoll.selenium/LICENSE.txt new file mode 100644 index 000000000..978821a72 --- /dev/null +++ b/provisioning/roles/arknoll.selenium/LICENSE.txt @@ -0,0 +1,13 @@ +Copyright (c) Alex Knoll + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/provisioning/roles/arknoll.selenium/README.md b/provisioning/roles/arknoll.selenium/README.md new file mode 100644 index 000000000..901c8fc60 --- /dev/null +++ b/provisioning/roles/arknoll.selenium/README.md @@ -0,0 +1,79 @@ +## selenium [![Build Status](https://travis-ci.org/arknoll/ansible-role-selenium.svg?branch=master)](https://travis-ci.org/arknoll/ansible-role-selenium) + +Set up selenium and Firefox for running selenium tests. + +#### Requirements + +* `java` + +#### Variables + +* `selenium_install_dir`: [default: `/opt`] Install directory +* `selenium_version`: [default: `2.53.0`] Install version +* `selenium_install_firefox`: [default: `no`] Whether to install FireFox +* `selenium_install_chrome`: [default: `yes`] Whether to install Google Chrome + +## Dependencies + +None + +#### Example + +```yaml +--- +- hosts: all + roles: + - selenium +``` + +#### Start/Stop/Restart Selenium + +``` +$ service selenium start +$ service selenium stop +$ service selenium restart +``` + +#### Known issue with Firefox + +For some OS combinations the package manager version of Firefox +doesn't work appropriately with Selenium. In these circumstances +you may see an error like: + +``` +WebDriver\Exception\UnknownError: Unable to connect to host 127.0.0.1 on port 7055 after 45000 ms. Firefox console output: +``` + +Chrome and chromedriver don't appear to have this issue. If +possible, use Chrome. If you still want to use firefox, then +I suggest using https://galaxy.ansible.com/arknoll/firefox/ +to install an older version of firefox. (38.0 worked for me +on Ubuntu 16.04). + +#### License and Author + +Author:: Alex Knoll (arknoll@gmail.com) + +Copyright:: 2015, Alex Knoll + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +#### Contributing + +We welcome contributed improvements and bug fixes via the usual workflow: + +1. Fork this repository +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Add some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create a new pull request diff --git a/provisioning/roles/arknoll.selenium/defaults/main.yml b/provisioning/roles/arknoll.selenium/defaults/main.yml new file mode 100644 index 000000000..025722c37 --- /dev/null +++ b/provisioning/roles/arknoll.selenium/defaults/main.yml @@ -0,0 +1,9 @@ +--- +# defaults file for selenium +selenium_install_dir: /opt +selenium_version: "2.53.0" +selenium_install_firefox: no +selenium_install_chrome: yes +selenium_display_id: "1" +selenium_port: 4444 +selenium_xvfb_args: "--server-args='-screen 0, 1920x1080x24'" diff --git a/provisioning/roles/arknoll.selenium/handlers/main.yml b/provisioning/roles/arknoll.selenium/handlers/main.yml new file mode 100644 index 000000000..acf78d5ae --- /dev/null +++ b/provisioning/roles/arknoll.selenium/handlers/main.yml @@ -0,0 +1,4 @@ +--- +# handlers file for selenium +- name: restart selenium + service: name=selenium state=restarted diff --git a/provisioning/roles/arknoll.selenium/meta/main.yml b/provisioning/roles/arknoll.selenium/meta/main.yml new file mode 100644 index 000000000..81cc3dbb9 --- /dev/null +++ b/provisioning/roles/arknoll.selenium/meta/main.yml @@ -0,0 +1,21 @@ +--- +# meta file for selenium +galaxy_info: + author: Alex Knoll + description: Set up selenium and Firefox for running selenium tests. + license: Apache V2 + min_ansible_version: 2.0 + platforms: + - name: EL + versions: + - 6 + - 7 + - name: Ubuntu + versions: + - all + - name: Debian + versions: + - all + categories: + - web +dependencies: [] diff --git a/provisioning/roles/arknoll.selenium/tasks/main.yml b/provisioning/roles/arknoll.selenium/tasks/main.yml new file mode 100644 index 000000000..f5986213a --- /dev/null +++ b/provisioning/roles/arknoll.selenium/tasks/main.yml @@ -0,0 +1,106 @@ +--- +# Tasks file for selenium +- name: Include OS-Specific variables + include_vars: "{{ ansible_os_family }}.yml" + tags: [configuration, selenium] + +- name: Install dependencies + package: name=unzip + tags: [configuration, selenium] + +- name: create directory + file: "path={{ selenium_install_dir }}/selenium state=directory recurse=yes" + tags: [configuration, selenium, selenium-create-directory] + +- name: Download Selenium + get_url: + url: "http://selenium-release.storage.googleapis.com/{{ selenium_version | regex_replace('\\.[0-9]+$', '') }}/selenium-server-standalone-{{ selenium_version }}.jar" + dest: "{{ selenium_install_dir }}/selenium/selenium-server-standalone-{{ selenium_version }}.jar" + tags: [configuration, selenium, selenium-download] + +- name: Install FireFox (if configured) + package: name=firefox state=present + when: selenium_install_firefox + tags: [configuration, selenium, selenium-firefox] + +- name: Add Chrome key (if configured, Debian) + apt_key: + url: "https://dl-ssl.google.com/linux/linux_signing_key.pub" + state: present + when: ansible_os_family == 'Debian' and selenium_install_chrome + tags: [configuration, selenium, selenium-chrome] + +- name: Add Chrome repo (if configured, Debian) + apt_repository: + repo: "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" + state: present + update_cache: yes + when: ansible_os_family == 'Debian' and selenium_install_chrome + tags: [configuration, selenium, selenium-chrome] + +- name: Install Chrome (if configured, Debian) + apt: + name: google-chrome-stable + state: present + when: ansible_os_family == 'Debian' and selenium_install_chrome + tags: [configuration, selenium, selenium-chrome] + +- name: Install Chrome (if configured, RedHat) + yum: + name: https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm + state: present + when: ansible_os_family == 'RedHat' and selenium_install_chrome + tags: [configuration, selenium, selenium-chrome] + +- name: Get the latest release for chromedriver + uri: + url: https://chromedriver.storage.googleapis.com/LATEST_RELEASE + return_content: yes + register: chromedriver_latest + when: selenium_install_chrome + tags: [configuration, selenium, selenium-chrome] + +- name: Install chromedriver + unarchive: + src: "https://chromedriver.storage.googleapis.com/{{ chromedriver_latest.content | trim }}/chromedriver_linux64.zip" + dest: /usr/bin + mode: 0755 + copy: no + when: selenium_install_chrome + tags: [configuration, selenium, selenium-chrome] + +- name: Install xvfb + package: name={{ selenium_xvfb_package }} + tags: [configuration, selenium, selenium-xvfb] + +- name: Install init script + template: + src: "selenium-init-{{ ansible_os_family }}.j2" + dest: /etc/init.d/selenium + owner: root + group: root + mode: 0755 + when: "ansible_service_mgr != 'systemd'" + tags: [configuration, selenium, selenium-install] + +- name: Install systemd unit file (for systemd systems) + template: + src: "selenium-unit.j2" + dest: /etc/systemd/system/selenium.service + owner: root + group: root + mode: 0755 + when: "ansible_service_mgr == 'systemd'" + tags: [configuration, selenium, selenium-install] + +- name: Register systemd service status (for systemd systems) + shell: 'systemctl status selenium | grep "active (running)"' + when: "ansible_service_mgr == 'systemd'" + register: selenium_running + ignore_errors: yes + changed_when: false + +- name: Ensure selenium is running + service: name=selenium state=started enabled=yes + tags: [configuration, selenium, selenium-run] + when: selenium_running.failed is defined and selenium_running.failed == true diff --git a/provisioning/roles/arknoll.selenium/templates/selenium-init-Debian.j2 b/provisioning/roles/arknoll.selenium/templates/selenium-init-Debian.j2 new file mode 100644 index 000000000..33f2ab7ff --- /dev/null +++ b/provisioning/roles/arknoll.selenium/templates/selenium-init-Debian.j2 @@ -0,0 +1,74 @@ +#!/bin/bash +### BEGIN INIT INFO +# Provides: selenium +# Required-Start: $local_fs $network +# Required-Stop: $local_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: selenium +# Description: selenium test framework +### END INIT INFO + +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + +DISPLAY_ID="{{ selenium_display_id }}" +RUN_AS=root + +JAVA_BIN=/usr/bin/java + +XVFB_BIN=/usr/bin/xvfb-run + +SELENIUM_DIR={{ selenium_install_dir }}/selenium +SELENIUM_JAR_FILE="$SELENIUM_DIR/selenium-server-standalone-{{ selenium_version }}.jar" +DAEMON_PID_FILE="$SELENIUM_DIR/selenium.pid" +SELENIUM_LOG_FILE="$SELENIUM_DIR/selenium.log" +SELENIUM_DAEMON_OPTS=" -client -jar $SELENIUM_JAR_FILE -log $SELENIUM_LOG_FILE -port {{ selenium_port }}" + +export DISPLAY="$DISPLAY_ID" + +set -e + +. /lib/lsb/init-functions + +case "$1" in + start) + if status_of_proc -p $DAEMON_PID_FILE "$SELENIUM_JAR_FILE" $SELENIUM_JAR_FILE > /dev/null; then + log_progress_msg "Service already running" + else + log_daemon_msg "Starting Selenium server" + log_progress_msg "selenium" + start-stop-daemon -c $RUN_AS --start --quiet --background --pidfile $DAEMON_PID_FILE --make-pidfile --exec $XVFB_BIN {{ selenium_xvfb_args }} $JAVA_BIN -- $SELENIUM_DAEMON_OPTS + fi + ;; + + stop) + if status_of_proc -p $DAEMON_PID_FILE "$SELENIUM_JAR_FILE" $SELENIUM_JAR_FILE > /dev/null; then + log_daemon_msg "Stopping Selenium server" + log_progress_msg "selenium" + DAEMON_PID=$(cat $DAEMON_PID_FILE) + DAEMON_CHILDREN=$(pstree -l -p $DAEMON_PID |grep "([[:digit:]]*)" -o |tr -d '()') + # Stop daemon itself. + start-stop-daemon --stop --pidfile $DAEMON_PID_FILE + # Stop all child processes. + sudo kill $DAEMON_CHILDREN + else + log_progress_msg "Service not running" + fi + ;; + + restart|force-reload) + $0 stop + sleep 1 + $0 start + ;; + + status) + status_of_proc -p $DAEMON_PID_FILE "$SELENIUM_JAR_FILE" $SELENIUM_JAR_FILE && exit 0 || exit $? + ;; + + *) + N=/etc/init.d/selenium + echo "Usage: $N {start|stop|restart|force-reload|status}" >&2 + exit 1 + ;; +esac diff --git a/provisioning/roles/arknoll.selenium/templates/selenium-init-RedHat.j2 b/provisioning/roles/arknoll.selenium/templates/selenium-init-RedHat.j2 new file mode 100644 index 000000000..d186e6ac9 --- /dev/null +++ b/provisioning/roles/arknoll.selenium/templates/selenium-init-RedHat.j2 @@ -0,0 +1,80 @@ +#!/bin/bash +# +# Selenium +# +# chkconfig: 345 90 25 +# description: Selenium service + +# Source function library. +. /etc/init.d/functions + +java_bin=/usr/bin/java + +xvfb_bin=/usr/bin/xvfb-run + +selenium_dir={{ selenium_install_dir }}/selenium +selenium_jar_file="$selenium_dir/selenium-server-standalone-{{ selenium_version }}.jar" +user=root +display="{{ selenium_display_id }}" +exec="$xvfb_bin {{ selenium_xvfb_args }} --server-num=$display $java_bin" +args=" -client -jar $selenium_jar_file -p {{ selenium_port }}" +lockfile="/var/lock/subsys/selenium" +pidfile="$selenium_dir/selenium.pid" +logfile="$selenium_dir/selenium.log" +prog="selenium" + +RETVAL=0 + +start() { + echo -n $"Starting $prog: " + + touch $pidfile + chown $user $pidfile + + touch $logfile + chown $user $logfile + + /bin/su - $user -c "DISPLAY=\":$display\" $exec $args >> $logfile 2>&1 & echo \$! > $pidfile" + + sleep 2 + + pgrep -fl $prog + RETVAL=$? + [ $RETVAL -eq 0 ] && echo_success || echo_failure + + return $RETVAL +} + +stop() { + echo -n $"Stopping $prog: " + killproc -p $pidfile $prog + RETVAL=$? + echo + [ $RETVAL -eq 0 ] && rm -f $lockfile $pidfile + return $RETVAL +} + +restart() { + stop + sleep 2 + start +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + status -p ${pidfile} ${prog} + RETVAL=$? + ;; + restart) + restart + ;; + *) + echo $"Usage: $0 {start|stop|restart}" + exit 1 +esac diff --git a/provisioning/roles/arknoll.selenium/templates/selenium-unit.j2 b/provisioning/roles/arknoll.selenium/templates/selenium-unit.j2 new file mode 100644 index 000000000..f25dfcab0 --- /dev/null +++ b/provisioning/roles/arknoll.selenium/templates/selenium-unit.j2 @@ -0,0 +1,11 @@ +[Unit] +Description=selenium test framework +After=syslog.target network.target + +[Service] +ExecStart=/usr/bin/xvfb-run {{ selenium_xvfb_args }} /usr/bin/java -client -jar {{ selenium_install_dir }}/selenium/selenium-server-standalone-{{ selenium_version }}.jar +Restart=on-failure +RestartSec=20s + +[Install] +WantedBy=multi-user.target diff --git a/provisioning/roles/arknoll.selenium/tests/README.md b/provisioning/roles/arknoll.selenium/tests/README.md new file mode 100644 index 000000000..6fb211721 --- /dev/null +++ b/provisioning/roles/arknoll.selenium/tests/README.md @@ -0,0 +1,11 @@ +# Ansible Role tests + +To run the test playbook(s) in this directory: + + 1. Install and start Docker. + 1. Download the test shim (see .travis.yml file for the URL) into `tests/test.sh`: + - `wget -O tests/test.sh https://gist.githubusercontent.com/geerlingguy/73ef1e5ee45d8694570f334be385e181/raw/` + 1. Make the test shim executable: `chmod +x tests/test.sh`. + 1. Run (from the role root directory) `distro=[distro] playbook=[playbook] ./tests/test.sh` + +If you don't want the container to be automatically deleted after the test playbook is run, add the following environment variables: `cleanup=false container_id=$(date +%s)` diff --git a/provisioning/roles/arknoll.selenium/tests/requirements.yml b/provisioning/roles/arknoll.selenium/tests/requirements.yml new file mode 100644 index 000000000..8fbe7cb66 --- /dev/null +++ b/provisioning/roles/arknoll.selenium/tests/requirements.yml @@ -0,0 +1,2 @@ +--- +- src: geerlingguy.java diff --git a/provisioning/roles/arknoll.selenium/tests/test.yml b/provisioning/roles/arknoll.selenium/tests/test.yml new file mode 100644 index 000000000..4fb579e31 --- /dev/null +++ b/provisioning/roles/arknoll.selenium/tests/test.yml @@ -0,0 +1,20 @@ +--- +# Test file for selenium +- hosts: all + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=3600 + when: ansible_os_family == 'Debian' + + - name: Don't install Chrome on old OSes. + set_fact: + selenium_install_firefox: yes + selenium_install_chrome: no + when: > + (ansible_distribution == 'Ubuntu' and ansible_distribution_version == '12.04') + or (ansible_os_family == 'RedHat' and ansible_distribution_version.split('.')[0] == '6') + + roles: + - geerlingguy.java + - role_under_test diff --git a/provisioning/roles/arknoll.selenium/vars/Debian.yml b/provisioning/roles/arknoll.selenium/vars/Debian.yml new file mode 100644 index 000000000..03f8ea6d2 --- /dev/null +++ b/provisioning/roles/arknoll.selenium/vars/Debian.yml @@ -0,0 +1,2 @@ +--- +selenium_xvfb_package: xvfb diff --git a/provisioning/roles/arknoll.selenium/vars/RedHat.yml b/provisioning/roles/arknoll.selenium/vars/RedHat.yml new file mode 100644 index 000000000..1b0f59d07 --- /dev/null +++ b/provisioning/roles/arknoll.selenium/vars/RedHat.yml @@ -0,0 +1,2 @@ +--- +selenium_xvfb_package: xorg-x11-server-Xvfb diff --git a/provisioning/roles/drupalvm.hostname/README.md b/provisioning/roles/drupalvm.hostname/README.md new file mode 100644 index 000000000..66f9bc582 --- /dev/null +++ b/provisioning/roles/drupalvm.hostname/README.md @@ -0,0 +1,47 @@ +# Drupal VM hostname Role + +This role is a shim to set the hostname and FQDN of Drupal VM. + +## Requirements + +This role is meant to be run in Drupal VM. Use outside of Drupal VM will likely result in weird things happening. + +## Role Variables + +Available variables are listed below: + +```yaml +hostname_fqdn: "{{ inventory_hostname }}" +``` + +The fully qualified domain name. If left blank, the `hostname` command will not be run (this can be useful if running the role within a Docker container). + +```yaml +hostname_short: "{{ hostname_fqdn|regex_replace('^([^.]+).*$', '\\1') }}" +``` + +The shortname defaulting to the part up to the first period of the FQDN, without the rest of the domain. + +```yaml +hostname_unsafe_writes: "{{ (ansible_virtualization_type == 'docker')|ternary('yes', 'no')|bool }}" +``` + +Whether to use unsafe writes or atomic operations when updating system files. Defaults to atomic operations on all systems except for docker where mounted files cannot be updated atomically and can only be done in an unsafe manner. + +## Dependencies + +None. + +## Example Playbook + + - hosts: drupalvm + roles: + - drupalvm.hostname + +## License + +MIT / BSD + +## Author Information + +This role was created in 2017 by [Oskar Schöldström](http://oxy.fi) and [Jeff Geerling](https://www.jeffgeerling.com/) (author of [Ansible for DevOps](https://www.ansiblefordevops.com/)). diff --git a/provisioning/roles/drupalvm.hostname/defaults/main.yml b/provisioning/roles/drupalvm.hostname/defaults/main.yml new file mode 100644 index 000000000..62bc0a722 --- /dev/null +++ b/provisioning/roles/drupalvm.hostname/defaults/main.yml @@ -0,0 +1,5 @@ +--- +hostname_fqdn: "{{ inventory_hostname }}" +hostname_short: "{{ hostname_fqdn|regex_replace('^([^.]+).*$', '\\1') }}" + +hostname_unsafe_writes: "{{ (ansible_virtualization_type == 'docker')|ternary('yes', 'no')|bool }}" diff --git a/provisioning/roles/drupalvm.hostname/meta/main.yml b/provisioning/roles/drupalvm.hostname/meta/main.yml new file mode 100644 index 000000000..f4669b3c9 --- /dev/null +++ b/provisioning/roles/drupalvm.hostname/meta/main.yml @@ -0,0 +1,24 @@ +--- +galaxy_info: + author: Jeff Geerling + description: A role to set the hostname and FQDN on Drupal VM. + company: Midwestern Mac, LLC + issue_tracker_url: https://github.com/geerlingguy/drupal-vm/issues + license: MIT + min_ansible_version: 2.2 + + platforms: + - name: EL + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + + galaxy_tags: + - drupal + - vm + - hostname diff --git a/provisioning/roles/drupalvm.hostname/tasks/main.yml b/provisioning/roles/drupalvm.hostname/tasks/main.yml new file mode 100644 index 000000000..60a8da596 --- /dev/null +++ b/provisioning/roles/drupalvm.hostname/tasks/main.yml @@ -0,0 +1,32 @@ +--- +- name: Configure /etc/mailname (Debian). + copy: + content: "{{ hostname_fqdn }}\n" + dest: /etc/mailname + when: + - ansible_os_family == 'Debian' + - hostname_fqdn != '' + +- name: Add hostname to /etc/hosts. + lineinfile: + dest: /etc/hosts + regexp: '.*\t{{ hostname_short }}$' + line: "127.0.0.1\t{{ hostname_fqdn }}\t{{ hostname_short }}" + state: present + unsafe_writes: "{{ hostname_unsafe_writes }}" + when: hostname_fqdn != '' + +- name: Configure hostname. + copy: + content: "{{ (ansible_os_family == 'Debian') | ternary(hostname_short, hostname_fqdn) }}\n" + dest: /etc/hostname + unsafe_writes: "{{ hostname_unsafe_writes }}" + register: set_hostname + when: hostname_fqdn != '' + +- name: Set the hostname for current session. + command: hostname --file /etc/hostname + when: + - set_hostname is changed + - hostname_fqdn != '' + tags: ['skip_ansible_lint'] diff --git a/provisioning/roles/drupalvm.vagrant-nfs-fix/README.md b/provisioning/roles/drupalvm.vagrant-nfs-fix/README.md new file mode 100644 index 000000000..f815cd118 --- /dev/null +++ b/provisioning/roles/drupalvm.vagrant-nfs-fix/README.md @@ -0,0 +1,29 @@ +# Drupal VM Vagrant NFS Fix Role + +This role exists to fix [issue #2154](https://github.com/geerlingguy/drupal-vm/issues/2154). + +## Requirements + +This role is meant to be run in Drupal VM. + +## Role Variables + +Available variables are listed below: + +```yaml +vagrant_nfs_fix_keepalive_file: "/vagrant/.vagrant-nfs-fix-keepalive.tmp" +``` + +Path to the keepalive file that we'll be `touch`ed every 30 seconds to keep NFS from timing out. + +## Dependencies + +None. + +## License + +MIT / BSD + +## Author Information + +This role was created in 2021 by [Oskar Schöldström](http://oxy.fi) and [Jeff Geerling](https://www.jeffgeerling.com/) (author of [Ansible for DevOps](https://www.ansiblefordevops.com/)). diff --git a/provisioning/roles/drupalvm.vagrant-nfs-fix/defaults/main.yml b/provisioning/roles/drupalvm.vagrant-nfs-fix/defaults/main.yml new file mode 100644 index 000000000..ce6bb638e --- /dev/null +++ b/provisioning/roles/drupalvm.vagrant-nfs-fix/defaults/main.yml @@ -0,0 +1,2 @@ +--- +vagrant_nfs_fix_keepalive_file: "/vagrant/.vagrant-nfs-fix-keepalive.tmp" diff --git a/provisioning/roles/drupalvm.vagrant-nfs-fix/tasks/main.yml b/provisioning/roles/drupalvm.vagrant-nfs-fix/tasks/main.yml new file mode 100644 index 000000000..4b4072d56 --- /dev/null +++ b/provisioning/roles/drupalvm.vagrant-nfs-fix/tasks/main.yml @@ -0,0 +1,22 @@ +--- +- name: Copy Vagrant NFS fix script into place. + template: + src: vagrant-nfs-fix.j2 + dest: /usr/sbin/vagrant-nfs-fix + owner: root + group: root + mode: 0755 + +- name: Copy Vagrant NFS fix systemd unit file into place. + template: + src: vagrant-nfs-fix.unit.j2 + dest: /etc/systemd/system/vagrant-nfs-fix.service + owner: root + group: root + mode: 0644 + +- name: Configure the NFS fix service. + service: + name: vagrant-nfs-fix + state: started + enabled: true diff --git a/provisioning/roles/drupalvm.vagrant-nfs-fix/templates/vagrant-nfs-fix.j2 b/provisioning/roles/drupalvm.vagrant-nfs-fix/templates/vagrant-nfs-fix.j2 new file mode 100644 index 000000000..435b39de8 --- /dev/null +++ b/provisioning/roles/drupalvm.vagrant-nfs-fix/templates/vagrant-nfs-fix.j2 @@ -0,0 +1,8 @@ +#!/bin/sh + +while true; do + touch {{ vagrant_nfs_fix_keepalive_file }} + sleep 1 + rm {{ vagrant_nfs_fix_keepalive_file }} + sleep 30 +done diff --git a/provisioning/roles/drupalvm.vagrant-nfs-fix/templates/vagrant-nfs-fix.unit.j2 b/provisioning/roles/drupalvm.vagrant-nfs-fix/templates/vagrant-nfs-fix.unit.j2 new file mode 100644 index 000000000..c0ece3a68 --- /dev/null +++ b/provisioning/roles/drupalvm.vagrant-nfs-fix/templates/vagrant-nfs-fix.unit.j2 @@ -0,0 +1,12 @@ +[Unit] +Description=Workaround for vagrant NFS inactivity bug +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +RestartSec=1 +ExecStart=/usr/sbin/vagrant-nfs-fix + +[Install] +WantedBy=multi-user.target diff --git a/provisioning/roles/drupalvm.www/README.md b/provisioning/roles/drupalvm.www/README.md new file mode 100644 index 000000000..e1a08d49f --- /dev/null +++ b/provisioning/roles/drupalvm.www/README.md @@ -0,0 +1,31 @@ +# Drupal VM www Role + +This role is a shim to configure miscellaneous settings prior to installing a Drupal site inside Drupal VM. + +## Requirements + +This role is meant to be run in Drupal VM. Use outside of Drupal VM will likely result in weird things happening. + +## Role Variables + +There are a few defaults defined, but you shouldn't really need to worry about this role's variables. It's a really simple role. + +## Dependencies + + - geerlingguy.nginx if `drupalvm_webserver` is set to `nginx`. + +## Example Playbook + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: drupalvm + roles: + - drupalvm.www + +## License + +MIT / BSD + +## Author Information + +This role was created in 2017 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/drupalvm.www/defaults/main.yml b/provisioning/roles/drupalvm.www/defaults/main.yml new file mode 100644 index 000000000..a77ca68b0 --- /dev/null +++ b/provisioning/roles/drupalvm.www/defaults/main.yml @@ -0,0 +1,3 @@ +--- +drupalvm_webserver: apache +vagrant_user: vagrant diff --git a/provisioning/roles/drupalvm.www/meta/main.yml b/provisioning/roles/drupalvm.www/meta/main.yml new file mode 100644 index 000000000..cc51852a0 --- /dev/null +++ b/provisioning/roles/drupalvm.www/meta/main.yml @@ -0,0 +1,31 @@ +galaxy_info: + author: Jeff Geerling + description: A role to configure various odds and ends in Drupal VM prior to installing Drupal. + company: Midwestern Mac, LLC + issue_tracker_url: https://github.com/geerlingguy/drupal-vm/issues + license: MIT + min_ansible_version: 2.2 + + platforms: + - name: EL + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - precise + - raring + - saucy + - trusty + - xenial + + galaxy_tags: + - nginx + - drupal + - vm + - vagrant + +dependencies: + - { role: geerlingguy.nginx, when: drupalvm_webserver == 'nginx' } diff --git a/provisioning/roles/drupalvm.www/tasks/main.yml b/provisioning/roles/drupalvm.www/tasks/main.yml new file mode 100644 index 000000000..d000bb42d --- /dev/null +++ b/provisioning/roles/drupalvm.www/tasks/main.yml @@ -0,0 +1,53 @@ +--- +- name: Define drupalvm_webserver_user (Debian). + set_fact: + drupalvm_webserver_user: www-data + when: ansible_os_family == 'Debian' and drupalvm_webserver_user is undefined + +- name: Define drupalvm_webserver_user (RedHat). + set_fact: + drupalvm_webserver_user: "{{ (drupalvm_webserver == 'apache') | ternary('httpd', 'nginx') }}" + when: ansible_os_family == 'RedHat' and drupalvm_webserver_user is undefined + +- name: Register information about the /vagrant directory. + stat: + path: /vagrant + register: vagrant_directory + +# When using NFS the group id of a folder will be identical to that of the host +# machine, but the groupname will differ or not exist. For the latter case +# we create a group called `vagrant_group`. +# +# The gr_name will be set if the GID is mapped to an existing group. If the GID +# doesn't exist, gr_name will be undefined. +- name: Ensure a group with the same GID as used to sync directories exist. + group: + gid: "{{ vagrant_directory.stat.gid }}" + name: vagrant_group + state: present + when: + - vagrant_directory.stat.exists + - vagrant_directory.stat.gr_name is undefined + +- name: Ensure the webserver user is in the same group as the owner of synced directories. + user: + name: "{{ drupalvm_webserver_user }}" + append: yes + groups: "{{ vagrant_directory.stat.gr_name|default('vagrant_group') }}" + when: + - vagrant_directory.stat.exists + - not (vagrant_directory.stat.gr_name is defined and vagrant_directory.stat.gr_name == 'root') + +- name: Ensure admin group exist. + group: "name=admin state=present" + +- name: Ensure vagrant user is in admin group. + user: "name={{ vagrant_user }} append=yes groups=admin" + +- name: Set nicer permissions on Apache log directory. + file: + path: "/var/log/{{ apache_daemon }}" + state: directory + mode: 0755 + recurse: true + when: drupalvm_webserver == 'apache' diff --git a/provisioning/roles/geerlingguy.adminer/.ansible-lint b/provisioning/roles/geerlingguy.adminer/.ansible-lint new file mode 100644 index 000000000..acc82551f --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/.ansible-lint @@ -0,0 +1,3 @@ +skip_list: + - 'yaml' + - 'role-name' diff --git a/provisioning/roles/geerlingguy.adminer/.github/FUNDING.yml b/provisioning/roles/geerlingguy.adminer/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.adminer/.github/stale.yml b/provisioning/roles/geerlingguy.adminer/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.adminer/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.adminer/.github/workflows/ci.yml new file mode 100644 index 000000000..c499de068 --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/.github/workflows/ci.yml @@ -0,0 +1,73 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "0 5 * * 0" + +defaults: + run: + working-directory: 'geerlingguy.adminer' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.adminer' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + include: + - distro: centos7 + playbook: converge.yml + - distro: ubuntu2004 + playbook: converge.yml + - distro: debian10 + playbook: converge.yml + - distro: centos7 + playbook: standalone.yml + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.adminer' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} + MOLECULE_PLAYBOOK: ${{ matrix.playbook }} diff --git a/provisioning/roles/geerlingguy.adminer/.github/workflows/release.yml b/provisioning/roles/geerlingguy.adminer/.github/workflows/release.yml new file mode 100644 index 000000000..66901cb0f --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.adminer' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.adminer' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.adminer/.gitignore b/provisioning/roles/geerlingguy.adminer/.gitignore new file mode 100644 index 000000000..8840c8f02 --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/.gitignore @@ -0,0 +1,5 @@ +*.retry +*/__pycache__ +*.pyc +.cache + diff --git a/provisioning/roles/geerlingguy.adminer/.yamllint b/provisioning/roles/geerlingguy.adminer/.yamllint new file mode 100644 index 000000000..f2033dd21 --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/provisioning/JJG-Ansible-Windows/LICENSE b/provisioning/roles/geerlingguy.adminer/LICENSE similarity index 96% rename from provisioning/JJG-Ansible-Windows/LICENSE rename to provisioning/roles/geerlingguy.adminer/LICENSE index 378188abb..4275cf3c1 100644 --- a/provisioning/JJG-Ansible-Windows/LICENSE +++ b/provisioning/roles/geerlingguy.adminer/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 Jeff Geerling +Copyright (c) 2017 Jeff Geerling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/provisioning/roles/geerlingguy.adminer/README.md b/provisioning/roles/geerlingguy.adminer/README.md new file mode 100644 index 000000000..dfc1d5335 --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/README.md @@ -0,0 +1,55 @@ +# Ansible Role: Adminer + +[![CI](https://github.com/geerlingguy/ansible-role-adminer/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-adminer/actions?query=workflow%3ACI) + +An Ansible Role that installs [Adminer](http://www.adminer.org/) on almost any computer. + +## Requirements + +You need to have PHP and MySQL for Adminer to do anything useful. If you have Apache installed, Adminer will add in configuration to make Adminer accessible on any virtualhost at `/adminer`; set `adminer_add_apache_config` to `false` to disable this behavior. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + adminer_download_url: https://www.adminer.org/latest.php + +The URL from which Adminer should be downloaded. + + adminer_install_dir: /opt/adminer + +The directory in which Adminer will be downloaded/installed. + + adminer_install_filename: adminer.php + +The filename for the downloaded Adminer application. If you're managing virtualhosts or server directives manually, it might be simpler to set the document root to your configured `adminer_install_dir`, and the filename to `index.php`, so you don't have to enter `/adminer.php` in the URL to access Adminer. + + adminer_symlink_dirs: [] + +Directories inside which you would like `adminer.php` symlinked. Can be useful if you just want to toss the script into a docroot and access it at `sitename/adminer.php`. + + adminer_add_apache_config: false + +Set this to `true` to tell Adminer to add a config file to Apache so you can access it at `hostname/adminer` on any configured virtualhost, using an Apache `Alias` directive. The role will also restart Apache so this configuration takes effect immediately. + + adminer_theme: '' + +You can use any theme from adminer library (for example `pappu687`). You can find the full list [here](https://www.adminer.org/en/#extras). + +## Dependencies + +None. If `adminer_add_apache_config` is set to `true`, it will use some variables and handlers defined by the `geerlingguy.apache` role, so there's a soft dependency on that role. + +## Example Playbook + + - hosts: servers + roles: + - { role: geerlingguy.adminer } + +## License + +MIT / BSD + +## Author Information + +This role was created in 2015 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). It is originally a fork of [Oefenweb/ansible-adminer](https://github.com/Oefenweb/ansible-adminer). diff --git a/provisioning/roles/geerlingguy.adminer/defaults/main.yml b/provisioning/roles/geerlingguy.adminer/defaults/main.yml new file mode 100644 index 000000000..c93ec8231 --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/defaults/main.yml @@ -0,0 +1,6 @@ +--- +adminer_download_url: https://www.adminer.org/latest.php +adminer_install_dir: /opt/adminer +adminer_install_filename: adminer.php +adminer_symlink_dirs: [] +adminer_add_apache_config: false diff --git a/provisioning/roles/geerlingguy.adminer/meta/main.yml b/provisioning/roles/geerlingguy.adminer/meta/main.yml new file mode 100644 index 000000000..dc888e041 --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/meta/main.yml @@ -0,0 +1,48 @@ +--- +dependencies: [] + +galaxy_info: + author: geerlingguy + description: Installs Adminer for Database management. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.0 + platforms: + - name: EL + versions: + - all + - name: GenericUNIX + versions: + - all + - name: Fedora + versions: + - all + - name: opensuse + versions: + - all + - name: GenericBSD + versions: + - all + - name: FreeBSD + versions: + - all + - name: Ubuntu + versions: + - all + - name: SLES + versions: + - all + - name: GenericLinux + versions: + - all + - name: Debian + versions: + - all + galaxy_tags: + - system + - database + - development + - adminer + - mysql + - mariadb + - php diff --git a/provisioning/roles/geerlingguy.adminer/molecule/default/converge.yml b/provisioning/roles/geerlingguy.adminer/molecule/default/converge.yml new file mode 100644 index 000000000..32cfadaf8 --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/molecule/default/converge.yml @@ -0,0 +1,17 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + adminer_add_apache_config: true + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + roles: + - role: geerlingguy.apache + - role: geerlingguy.adminer diff --git a/provisioning/roles/geerlingguy.adminer/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.adminer/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.adminer/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.adminer/molecule/default/requirements.yml new file mode 100644 index 000000000..25c230cfb --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/molecule/default/requirements.yml @@ -0,0 +1,2 @@ +--- +- src: geerlingguy.apache diff --git a/provisioning/roles/geerlingguy.adminer/molecule/default/standalone.yml b/provisioning/roles/geerlingguy.adminer/molecule/default/standalone.yml new file mode 100644 index 000000000..aaaa0c65d --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/molecule/default/standalone.yml @@ -0,0 +1,17 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + adminer_install_dir: /opt/adminer + adminer_add_apache_config: false + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + roles: + - role: geerlingguy.adminer diff --git a/provisioning/roles/geerlingguy.adminer/tasks/main.yml b/provisioning/roles/geerlingguy.adminer/tasks/main.yml new file mode 100644 index 000000000..8ab43dbdf --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/tasks/main.yml @@ -0,0 +1,80 @@ +--- +# Install Adminer. +- name: Ensure Adminer directory exists. + file: # noqa 208 + path: "{{ adminer_install_dir }}" + state: directory + recurse: true + +- name: Testing if adminer is older than 1 day + find: + paths: "{{ adminer_install_dir }}" + patterns: "{{ adminer_install_filename }}" + age: "1d" + register: adminer_is_old + +- name: Download Adminer to configured directory. + get_url: + url: "{{ adminer_download_url }}" + dest: "{{ adminer_install_dir }}/{{ adminer_install_filename }}" + force: "{{ (adminer_is_old.matched == 1) | ternary('yes','no') }}" + mode: 0644 + timeout: 60 + +- name: Ensure paths to place symlinks exist + file: + state: directory + path: "{{ item }}" + mode: 0755 + with_items: + - "{{ adminer_symlink_dirs }}" + +- name: Symlink Adminer into configured directories. + file: + src: "{{ adminer_install_dir }}/adminer.php" + dest: "{{ item }}/adminer.php" + state: link + mode: 0644 + with_items: "{{ adminer_symlink_dirs }}" + +# Install Adminer theme. +- name: Download Adminer theme + get_url: + url: https://raw.githubusercontent.com/vrana/adminer/master/designs/{{ adminer_theme }}/adminer.css + dest: "{{ adminer_install_dir }}" + force: "{{ (adminer_is_old.matched == 1) | adminer_force_download }}" + mode: 0644 + timeout: 60 + when: adminer_theme is defined and adminer_theme != null + +- name: Symlink Adminer theme into configured directories. + file: + src: "{{ adminer_install_dir }}/adminer.css" + dest: "{{ item }}/adminer.css" + state: link + mode: 0644 + with_items: "{{ adminer_symlink_dirs }}" + when: adminer_theme is defined and adminer_theme != null + +# Add Apache configuration (if configured). +- name: Set the proper Apache configuration directory (Debian). + set_fact: + apache_extra_conf_dir: >- + {{ 'conf-enabled' if apache_vhosts_version == '2.4' else 'conf.d' }} + when: adminer_add_apache_config and ansible_os_family == 'Debian' + +- name: Add Apache configuration file for Adminer (Debian). + template: + src: adminer.conf.j2 + dest: "{{ apache_conf_path }}/{{ apache_extra_conf_dir }}/adminer.conf" + mode: 0644 + when: adminer_add_apache_config and ansible_os_family == 'Debian' + notify: restart apache + +- name: Add Apache configuration file for Adminer (RedHat). + template: + src: adminer.conf.j2 + dest: "{{ apache_conf_path }}/adminer.conf" + mode: 0644 + when: adminer_add_apache_config and ansible_os_family == 'RedHat' + notify: restart apache diff --git a/provisioning/roles/geerlingguy.adminer/templates/adminer.conf.j2 b/provisioning/roles/geerlingguy.adminer/templates/adminer.conf.j2 new file mode 100644 index 000000000..93f23f2e7 --- /dev/null +++ b/provisioning/roles/geerlingguy.adminer/templates/adminer.conf.j2 @@ -0,0 +1,9 @@ +Alias /adminer "{{ adminer_install_dir }}/adminer.php" +<Directory "{{ adminer_install_dir }}"> +{% if apache_vhosts_version == "2.2" %} + Order allow,deny + Allow from all +{% else %} + Require all granted +{% endif %} +</Directory> diff --git a/provisioning/roles/geerlingguy.apache-php-fpm/.travis.yml b/provisioning/roles/geerlingguy.apache-php-fpm/.travis.yml new file mode 100644 index 000000000..756cb37f3 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache-php-fpm/.travis.yml @@ -0,0 +1,44 @@ +--- +services: docker + +env: + - distro: centos7 + init: /usr/lib/systemd/systemd + run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" + - distro: ubuntu1604 + init: /lib/systemd/systemd + run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" + - distro: ubuntu1404 + init: /sbin/init + run_opts: "" + +before_install: + # Pull container. + - 'docker pull geerlingguy/docker-${distro}-ansible:latest' + +script: + - container_id=$(mktemp) + # Run container in detached state. + - 'docker run --detach --volume="${PWD}":/etc/ansible/roles/role_under_test:ro ${run_opts} geerlingguy/docker-${distro}-ansible:latest "${init}" > "${container_id}"' + + # Install required Galaxy roles. + - 'docker exec --tty "$(cat ${container_id})" env TERM=xterm ansible-galaxy install geerlingguy.repo-remi geerlingguy.apache geerlingguy.php' + + # Ansible syntax check. + - 'docker exec --tty "$(cat ${container_id})" env TERM=xterm ansible-playbook /etc/ansible/roles/role_under_test/tests/test.yml --syntax-check' + + # Test role. + - 'docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/role_under_test/tests/test.yml' + - 'docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/role_under_test/tests/test.yml' + + # Test role idempotence. + - idempotence=$(mktemp) + - docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/role_under_test/tests/test.yml | tee -a ${idempotence} + - > + tail ${idempotence} + | grep -q 'changed=0.*failed=0' + && (echo 'Idempotence test: pass' && exit 0) + || (echo 'Idempotence test: fail' && exit 1) + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.apache-php-fpm/LICENSE b/provisioning/roles/geerlingguy.apache-php-fpm/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache-php-fpm/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.apache-php-fpm/README.md b/provisioning/roles/geerlingguy.apache-php-fpm/README.md new file mode 100644 index 000000000..23e7e7e8e --- /dev/null +++ b/provisioning/roles/geerlingguy.apache-php-fpm/README.md @@ -0,0 +1,69 @@ +# Ansible Role: Apache PHP-FPM + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-apache-php-fpm.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-apache-php-fpm) + +An Ansible Role that configures Apache for PHP-FPM usage on RHEL/CentOS and Debian/Ubuntu. + +## Requirements + +This role is dependent upon `geerlingguy.apache`, and also requires you have PHP running with PHP-FPM somewhere on the server or elsewhere (I usually configure PHP with the `geerlingguy.php` role). + +When configuring your Apache virtual hosts, you can add the following line to any vhost definition to enable passthrough to PHP-FPM: + + # If using a TCP port: + ProxyPassMatch ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000/var/www/example" + + # If using a Unix socket: + ProxyPassMatch ^/(.*\.php(/.*)?)$ "unix:/var/run/php5-fpm.sock|fcgi://localhost/var/www/example" + +For a full usage example with the `geerlingguy.apache` role, see the Example Playbook later in this README. + +### RedHat 6 and 7 + +RedHat/CentOS 7 automatically installs and enables mod_proxy_fcgi by default. + +RedHat/CentOS 6 installs Apache 2.2, and is much harder to get configured with FastCGI, but here are two guides in case you need to support this use case: + + - [Apache 2.2 + mod_fastcgi](http://stackoverflow.com/a/21409702/100134) + - [Apache 2.4 + mod_proxy_fcgi](http://unix.stackexchange.com/a/138903/16194 + +### Ubuntu < 14.04 + +This role will only work correctly if you have Apache 2.4.9+ installed; on older versions of Debian/Ubuntu Linux (e.g. 12.04), you can add `ppa:ondrej/apache2` prior to Apache installation to install Apache 2.4, for example: + + - name: Add repository for Apache 2.4 on Ubuntu 12.04. + apt_repository: repo='ppa:ondrej/apache2' + when: ansible_distribution_version == "12.04" + +## Role Variables + +None. + +## Dependencies + +None. + +## Example Playbook + + - hosts: webservers + + vars: + php_enable_php_fpm: true + apache_vhosts: + - servername: "www.example.com" + documentroot: "/var/www/example" + extra_parameters: | + ProxyPassMatch ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000/var/www/example" + + roles: + - geerlingguy.apache + - geerlingguy.php + - geerlingguy.apache-php-fpm + +## License + +MIT / BSD + +## Author Information + +This role was created in 2016 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](http://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.apache-php-fpm/meta/main.yml b/provisioning/roles/geerlingguy.apache-php-fpm/meta/main.yml new file mode 100644 index 000000000..c22187d59 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache-php-fpm/meta/main.yml @@ -0,0 +1,31 @@ +--- +dependencies: + - geerlingguy.apache + +galaxy_info: + author: geerlingguy + description: Apache 2.4+ PHP-FPM support for Linux. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.0 + platforms: + - name: EL + versions: + - 6 + - 7 + - name: Debian + versions: + - wheezy + - jessie + - stretch + - name: Ubuntu + versions: + - precise + - trusty + - xenial + galaxy_tags: + - web + - apache + - php + - cgi + - php-fpm diff --git a/provisioning/roles/geerlingguy.apache-php-fpm/tasks/main.yml b/provisioning/roles/geerlingguy.apache-php-fpm/tasks/main.yml new file mode 100644 index 000000000..5fbaa835c --- /dev/null +++ b/provisioning/roles/geerlingguy.apache-php-fpm/tasks/main.yml @@ -0,0 +1,12 @@ +--- +# For RedHat/CentOS, see notes in README. +- name: Enable mod_proxy_fcgi. + file: + src: "{{ apache_server_root }}/mods-available/{{ item }}" + dest: "{{ apache_server_root }}/mods-enabled/{{ item }}" + state: link + with_items: + - proxy.load + - proxy_fcgi.load + notify: restart apache + when: ansible_os_family == 'Debian' diff --git a/provisioning/roles/geerlingguy.apache-php-fpm/tests/test.yml b/provisioning/roles/geerlingguy.apache-php-fpm/tests/test.yml new file mode 100644 index 000000000..b72410ccf --- /dev/null +++ b/provisioning/roles/geerlingguy.apache-php-fpm/tests/test.yml @@ -0,0 +1,23 @@ +--- +- hosts: all + + vars: + php_enablerepo: "remi,remi-php56" + apache_listen_port_ssl: 443 + apache_create_vhosts: true + apache_vhosts_filename: "vhosts.conf" + apache_vhosts: + - servername: "example.com" + documentroot: "/var/www/vhosts/example_com" + + pre_tasks: + - name: Add repository for PHP 7. + apt_repository: repo='ppa:ondrej/php' + when: ansible_distribution == 'Ubuntu' and ansible_distribution_version != '16.04' + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.apache + - role: geerlingguy.php + - role: role_under_test diff --git a/provisioning/roles/geerlingguy.apache/.ansible-lint b/provisioning/roles/geerlingguy.apache/.ansible-lint new file mode 100644 index 000000000..acc82551f --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/.ansible-lint @@ -0,0 +1,3 @@ +skip_list: + - 'yaml' + - 'role-name' diff --git a/provisioning/roles/geerlingguy.apache/.github/FUNDING.yml b/provisioning/roles/geerlingguy.apache/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.apache/.github/stale.yml b/provisioning/roles/geerlingguy.apache/.github/stale.yml new file mode 100644 index 000000000..3cc6ec313 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/.github/stale.yml @@ -0,0 +1,57 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - bug + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.apache/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.apache/.github/workflows/ci.yml new file mode 100644 index 000000000..91bbbc992 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/.github/workflows/ci.yml @@ -0,0 +1,68 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "0 5 * * 0" + +defaults: + run: + working-directory: 'geerlingguy.apache' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.apache' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + distro: + - centos8 + - centos7 + - ubuntu2004 + - debian10 + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.apache' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} diff --git a/provisioning/roles/geerlingguy.apache/.github/workflows/release.yml b/provisioning/roles/geerlingguy.apache/.github/workflows/release.yml new file mode 100644 index 000000000..06be70522 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.apache' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.apache' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.apache/.gitignore b/provisioning/roles/geerlingguy.apache/.gitignore new file mode 100644 index 000000000..8840c8f02 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/.gitignore @@ -0,0 +1,5 @@ +*.retry +*/__pycache__ +*.pyc +.cache + diff --git a/provisioning/roles/geerlingguy.apache/.yamllint b/provisioning/roles/geerlingguy.apache/.yamllint new file mode 100644 index 000000000..f2033dd21 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/provisioning/roles/geerlingguy.apache/LICENSE b/provisioning/roles/geerlingguy.apache/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.apache/README.md b/provisioning/roles/geerlingguy.apache/README.md new file mode 100644 index 000000000..24149d808 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/README.md @@ -0,0 +1,160 @@ +# Ansible Role: Apache 2.x + +[![CI](https://github.com/geerlingguy/ansible-role-apache/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-apache/actions?query=workflow%3ACI) + +An Ansible Role that installs Apache 2.x on RHEL/CentOS, Debian/Ubuntu, SLES and Solaris. + +## Requirements + +If you are using SSL/TLS, you will need to provide your own certificate and key files. You can generate a self-signed certificate with a command like `openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout example.key -out example.crt`. + +If you are using Apache with PHP, I recommend using the `geerlingguy.php` role to install PHP, and you can either use mod_php (by adding the proper package, e.g. `libapache2-mod-php5` for Ubuntu, to `php_packages`), or by also using `geerlingguy.apache-php-fpm` to connect Apache to PHP via FPM. See that role's README for more info. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + apache_enablerepo: "" + +The repository to use when installing Apache (only used on RHEL/CentOS systems). If you'd like later versions of Apache than are available in the OS's core repositories, use a repository like EPEL (which can be installed with the `geerlingguy.repo-epel` role). + + apache_listen_ip: "*" + apache_listen_port: 80 + apache_listen_port_ssl: 443 + +The IP address and ports on which apache should be listening. Useful if you have another service (like a reverse proxy) listening on port 80 or 443 and need to change the defaults. + + apache_create_vhosts: true + apache_vhosts_filename: "vhosts.conf" + apache_vhosts_template: "vhosts.conf.j2" + +If set to true, a vhosts file, managed by this role's variables (see below), will be created and placed in the Apache configuration folder. If set to false, you can place your own vhosts file into Apache's configuration folder and skip the convenient (but more basic) one added by this role. You can also override the template used and set a path to your own template, if you need to further customize the layout of your VirtualHosts. + + apache_remove_default_vhost: false + +On Debian/Ubuntu, a default virtualhost is included in Apache's configuration. Set this to `true` to remove that default virtualhost configuration file. + + apache_global_vhost_settings: | + DirectoryIndex index.php index.html + # Add other global settings on subsequent lines. + +You can add or override global Apache configuration settings in the role-provided vhosts file (assuming `apache_create_vhosts` is true) using this variable. By default it only sets the DirectoryIndex configuration. + + apache_vhosts: + # Additional optional properties: 'serveradmin, serveralias, extra_parameters'. + - servername: "local.dev" + documentroot: "/var/www/html" + +Add a set of properties per virtualhost, including `servername` (required), `documentroot` (required), `allow_override` (optional: defaults to the value of `apache_allow_override`), `options` (optional: defaults to the value of `apache_options`), `serveradmin` (optional), `serveralias` (optional) and `extra_parameters` (optional: you can add whatever additional configuration lines you'd like in here). + +Here's an example using `extra_parameters` to add a RewriteRule to redirect all requests to the `www.` site: + + - servername: "www.local.dev" + serveralias: "local.dev" + documentroot: "/var/www/html" + extra_parameters: | + RewriteCond %{HTTP_HOST} !^www\. [NC] + RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] + +The `|` denotes a multiline scalar block in YAML, so newlines are preserved in the resulting configuration file output. + + apache_vhosts_ssl: [] + +No SSL vhosts are configured by default, but you can add them using the same pattern as `apache_vhosts`, with a few additional directives, like the following example: + + apache_vhosts_ssl: + - servername: "local.dev" + documentroot: "/var/www/html" + certificate_file: "/home/vagrant/example.crt" + certificate_key_file: "/home/vagrant/example.key" + certificate_chain_file: "/path/to/certificate_chain.crt" + extra_parameters: | + RewriteCond %{HTTP_HOST} !^www\. [NC] + RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] + +Other SSL directives can be managed with other SSL-related role variables. + + apache_ssl_protocol: "All -SSLv2 -SSLv3" + apache_ssl_cipher_suite: "AES256+EECDH:AES256+EDH" + +The SSL protocols and cipher suites that are used/allowed when clients make secure connections to your server. These are secure/sane defaults, but for maximum security, performand, and/or compatibility, you may need to adjust these settings. + + apache_allow_override: "All" + apache_options: "-Indexes +FollowSymLinks" + +The default values for the `AllowOverride` and `Options` directives for the `documentroot` directory of each vhost. A vhost can overwrite these values by specifying `allow_override` or `options`. + + apache_mods_enabled: + - rewrite.load + - ssl.load + apache_mods_disabled: [] + +(Debian/Ubuntu ONLY) Which Apache mods to enable or disable (these will be symlinked into the appropriate location). See the `mods-available` directory inside the apache configuration directory (`/etc/apache2/mods-available` by default) for all the available mods. + + apache_packages: + - [platform-specific] + +The list of packages to be installed. This defaults to a set of platform-specific packages for RedHat or Debian-based systems (see `vars/RedHat.yml` and `vars/Debian.yml` for the default values). + + apache_state: started + +Set initial Apache daemon state to be enforced when this role is run. This should generally remain `started`, but you can set it to `stopped` if you need to fix the Apache config during a playbook run or otherwise would not like Apache started at the time this role is run. + + apache_enabled: yes + +Set the Apache service boot time status. This should generally remain `yes`, but you can set it to `no` if you need to run Ansible while leaving the service disabled. + + apache_packages_state: present + +If you have enabled any additional repositories such as _ondrej/apache2_, [geerlingguy.repo-epel](https://github.com/geerlingguy/ansible-role-repo-epel), or [geerlingguy.repo-remi](https://github.com/geerlingguy/ansible-role-repo-remi), you may want an easy way to upgrade versions. You can set this to `latest` (combined with `apache_enablerepo` on RHEL) and can directly upgrade to a different Apache version from a different repo (instead of uninstalling and reinstalling Apache). + + apache_ignore_missing_ssl_certificate: true + +If you would like to only create SSL vhosts when the vhost certificate is present (e.g. when using Let’s Encrypt), set `apache_ignore_missing_ssl_certificate` to `false`. When doing this, you might need to run your playbook more than once so all the vhosts are configured (if another part of the playbook generates the SSL certificates). + +## .htaccess-based Basic Authorization + +If you require Basic Auth support, you can add it either through a custom template, or by adding `extra_parameters` to a VirtualHost configuration, like so: + + extra_parameters: | + <Directory "/var/www/password-protected-directory"> + Require valid-user + AuthType Basic + AuthName "Please authenticate" + AuthUserFile /var/www/password-protected-directory/.htpasswd + </Directory> + +To password protect everything within a VirtualHost directive, use the `Location` block instead of `Directory`: + + <Location "/"> + Require valid-user + .... + </Location> + +You would need to generate/upload your own `.htpasswd` file in your own playbook. There may be other roles that support this functionality in a more integrated way. + +## Dependencies + +None. + +## Example Playbook + + - hosts: webservers + vars_files: + - vars/main.yml + roles: + - { role: geerlingguy.apache } + +*Inside `vars/main.yml`*: + + apache_listen_port: 8080 + apache_vhosts: + - {servername: "example.com", documentroot: "/var/www/vhosts/example_com"} + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.apache/defaults/main.yml b/provisioning/roles/geerlingguy.apache/defaults/main.yml new file mode 100644 index 000000000..21d7726bf --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/defaults/main.yml @@ -0,0 +1,61 @@ +--- +apache_enablerepo: "" + +apache_listen_ip: "*" +apache_listen_port: 80 +apache_listen_port_ssl: 443 + +apache_create_vhosts: true +apache_vhosts_filename: "vhosts.conf" +apache_vhosts_template: "vhosts.conf.j2" + +# On Debian/Ubuntu, a default virtualhost is included in Apache's configuration. +# Set this to `true` to remove that default. +apache_remove_default_vhost: false + +apache_global_vhost_settings: | + DirectoryIndex index.php index.html + +apache_vhosts: + # Additional properties: + # 'serveradmin, serveralias, allow_override, options, extra_parameters'. + - servername: "local.dev" + documentroot: "/var/www/html" + +apache_allow_override: "All" +apache_options: "-Indexes +FollowSymLinks" + +apache_vhosts_ssl: [] +# Additional properties: +# 'serveradmin, serveralias, allow_override, options, extra_parameters'. +# - servername: "local.dev", +# documentroot: "/var/www/html", +# certificate_file: "/path/to/certificate.crt", +# certificate_key_file: "/path/to/certificate.key", +# # Optional. +# certificate_chain_file: "/path/to/certificate_chain.crt" + +apache_ignore_missing_ssl_certificate: true + +apache_ssl_protocol: "All -SSLv2 -SSLv3" +apache_ssl_cipher_suite: "AES256+EECDH:AES256+EDH" + +# Only used on Debian/Ubuntu. +apache_mods_enabled: + - rewrite.load + - ssl.load +apache_mods_disabled: [] + +# Set initial apache state. Recommended values: `started` or `stopped` +apache_state: started + +# Set initial apache service status. Recommended values: `yes` or `no` +apache_enabled: yes + +# Set apache state when configuration changes are made. Recommended values: +# `restarted` or `reloaded` +apache_restart_state: restarted + +# Apache package state; use `present` to make sure it's installed, or `latest` +# if you want to upgrade or switch versions using a new repo. +apache_packages_state: present diff --git a/provisioning/roles/geerlingguy.apache/handlers/main.yml b/provisioning/roles/geerlingguy.apache/handlers/main.yml new file mode 100644 index 000000000..53abffb69 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: restart apache + service: + name: "{{ apache_service }}" + state: "{{ apache_restart_state }}" diff --git a/provisioning/roles/geerlingguy.apache/meta/main.yml b/provisioning/roles/geerlingguy.apache/meta/main.yml new file mode 100644 index 000000000..5a28c0542 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/meta/main.yml @@ -0,0 +1,39 @@ +--- +dependencies: [] + +galaxy_info: + role_name: apache + author: geerlingguy + description: Apache 2.x for Linux. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + - name: Fedora + versions: + - all + - name: Amazon + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - trusty + - xenial + - bionic + - name: Solaris + versions: + - 11.3 + galaxy_tags: + - web + - apache + - webserver + - html + - httpd + +allow_duplicates: true diff --git a/provisioning/roles/geerlingguy.apache/molecule/default/converge.yml b/provisioning/roles/geerlingguy.apache/molecule/default/converge.yml new file mode 100644 index 000000000..416a2b968 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/molecule/default/converge.yml @@ -0,0 +1,21 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + apache_listen_port_ssl: 443 + apache_create_vhosts: true + apache_vhosts_filename: "vhosts.conf" + apache_vhosts: + - servername: "example.com" + documentroot: "/var/www/vhosts/example_com" + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + roles: + - role: geerlingguy.apache diff --git a/provisioning/roles/geerlingguy.apache/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.apache/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.apache/tasks/configure-Debian.yml b/provisioning/roles/geerlingguy.apache/tasks/configure-Debian.yml new file mode 100644 index 000000000..e9b2ad432 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/tasks/configure-Debian.yml @@ -0,0 +1,57 @@ +--- +- name: Configure Apache. + lineinfile: + dest: "{{ apache_server_root }}/ports.conf" + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + state: present + mode: 0644 + with_items: "{{ apache_ports_configuration_items }}" + notify: restart apache + +- name: Enable Apache mods. + file: + src: "{{ apache_server_root }}/mods-available/{{ item }}" + dest: "{{ apache_server_root }}/mods-enabled/{{ item }}" + state: link + mode: 0644 + with_items: "{{ apache_mods_enabled }}" + notify: restart apache + +- name: Disable Apache mods. + file: + path: "{{ apache_server_root }}/mods-enabled/{{ item }}" + state: absent + with_items: "{{ apache_mods_disabled }}" + notify: restart apache + +- name: Check whether certificates defined in vhosts exist. + stat: "path={{ item.certificate_file }}" + register: apache_ssl_certificates + with_items: "{{ apache_vhosts_ssl }}" + +- name: Add apache vhosts configuration. + template: + src: "{{ apache_vhosts_template }}" + dest: "{{ apache_conf_path }}/sites-available/{{ apache_vhosts_filename }}" + owner: root + group: root + mode: 0644 + notify: restart apache + when: apache_create_vhosts | bool + +- name: Add vhost symlink in sites-enabled. + file: + src: "{{ apache_conf_path }}/sites-available/{{ apache_vhosts_filename }}" + dest: "{{ apache_conf_path }}/sites-enabled/{{ apache_vhosts_filename }}" + state: link + mode: 0644 + notify: restart apache + when: apache_create_vhosts | bool + +- name: Remove default vhost in sites-enabled. + file: + path: "{{ apache_conf_path }}/sites-enabled/{{ apache_default_vhost_filename }}" + state: absent + notify: restart apache + when: apache_remove_default_vhost diff --git a/provisioning/roles/geerlingguy.apache/tasks/configure-RedHat.yml b/provisioning/roles/geerlingguy.apache/tasks/configure-RedHat.yml new file mode 100644 index 000000000..857746149 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/tasks/configure-RedHat.yml @@ -0,0 +1,37 @@ +--- +- name: Configure Apache. + lineinfile: + dest: "{{ apache_server_root }}/conf/{{ apache_daemon }}.conf" + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + state: present + mode: 0644 + with_items: "{{ apache_ports_configuration_items }}" + notify: restart apache + +- name: Check whether certificates defined in vhosts exist. + stat: path={{ item.certificate_file }} + register: apache_ssl_certificates + with_items: "{{ apache_vhosts_ssl }}" + +- name: Add apache vhosts configuration. + template: + src: "{{ apache_vhosts_template }}" + dest: "{{ apache_conf_path }}/{{ apache_vhosts_filename }}" + owner: root + group: root + mode: 0644 + notify: restart apache + when: apache_create_vhosts | bool + +- name: Check if localhost cert exists (RHEL 8 and later). + stat: + path: /etc/pki/tls/certs/localhost.crt + register: localhost_cert + when: ansible_distribution_major_version | int >= 8 + +- name: Ensure httpd certs are installed (RHEL 8 and later). + command: /usr/libexec/httpd-ssl-gencerts + when: + - ansible_distribution_major_version | int >= 8 + - not localhost_cert.stat.exists diff --git a/provisioning/roles/geerlingguy.apache/tasks/configure-Solaris.yml b/provisioning/roles/geerlingguy.apache/tasks/configure-Solaris.yml new file mode 100644 index 000000000..2fbf83207 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/tasks/configure-Solaris.yml @@ -0,0 +1,20 @@ +--- +- name: Configure Apache. + lineinfile: + dest: "{{ apache_server_root }}/{{ apache_daemon }}.conf" + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + state: present + mode: 0644 + with_items: "{{ apache_ports_configuration_items }}" + notify: restart apache + +- name: Add apache vhosts configuration. + template: + src: "{{ apache_vhosts_template }}" + dest: "{{ apache_conf_path }}/{{ apache_vhosts_filename }}" + owner: root + group: root + mode: 0644 + notify: restart apache + when: apache_create_vhosts | bool diff --git a/provisioning/roles/geerlingguy.apache/tasks/configure-Suse.yml b/provisioning/roles/geerlingguy.apache/tasks/configure-Suse.yml new file mode 100644 index 000000000..9f084cfd7 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/tasks/configure-Suse.yml @@ -0,0 +1,25 @@ +--- +- name: Configure Apache. + lineinfile: + dest: "{{ apache_server_root }}/listen.conf" + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + state: present + mode: 0644 + with_items: "{{ apache_ports_configuration_items }}" + notify: restart apache + +- name: Check whether certificates defined in vhosts exist. + stat: path={{ item.certificate_file }} + register: apache_ssl_certificates + with_items: "{{ apache_vhosts_ssl }}" + +- name: Add apache vhosts configuration. + template: + src: "{{ apache_vhosts_template }}" + dest: "{{ apache_conf_path }}/{{ apache_vhosts_filename }}" + owner: root + group: root + mode: 0644 + notify: restart apache + when: apache_create_vhosts | bool diff --git a/provisioning/roles/geerlingguy.apache/tasks/main.yml b/provisioning/roles/geerlingguy.apache/tasks/main.yml new file mode 100644 index 000000000..567356c04 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/tasks/main.yml @@ -0,0 +1,47 @@ +--- +# Include variables and define needed variables. +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Include variables for Amazon Linux. + include_vars: "AmazonLinux.yml" + when: + - ansible_distribution == "Amazon" + - ansible_distribution_major_version == "NA" + +- name: Define apache_packages. + set_fact: + apache_packages: "{{ __apache_packages | list }}" + when: apache_packages is not defined + +# Setup/install tasks. +- include_tasks: "setup-{{ ansible_os_family }}.yml" + +# Figure out what version of Apache is installed. +- name: Get installed version of Apache. + command: "{{ apache_daemon_path }}{{ apache_daemon }} -v" + changed_when: false + check_mode: false + register: _apache_version + +- name: Create apache_version variable. + set_fact: + apache_version: "{{ _apache_version.stdout.split()[2].split('/')[1] }}" + +- name: Include Apache 2.2 variables. + include_vars: apache-22.yml + when: "apache_version.split('.')[1] == '2'" + +- name: Include Apache 2.4 variables. + include_vars: apache-24.yml + when: "apache_version.split('.')[1] == '4'" + +# Configure Apache. +- name: Configure Apache. + include_tasks: "configure-{{ ansible_os_family }}.yml" + +- name: Ensure Apache has selected state and enabled on boot. + service: + name: "{{ apache_service }}" + state: "{{ apache_state }}" + enabled: "{{ apache_enabled }}" diff --git a/provisioning/roles/geerlingguy.apache/tasks/setup-Debian.yml b/provisioning/roles/geerlingguy.apache/tasks/setup-Debian.yml new file mode 100644 index 000000000..b5d141239 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/tasks/setup-Debian.yml @@ -0,0 +1,6 @@ +--- +- name: Update apt cache. + apt: update_cache=yes cache_valid_time=3600 + +- name: Ensure Apache is installed on Debian. + apt: "name={{ apache_packages }} state={{ apache_packages_state }}" diff --git a/provisioning/roles/geerlingguy.apache/tasks/setup-RedHat.yml b/provisioning/roles/geerlingguy.apache/tasks/setup-RedHat.yml new file mode 100644 index 000000000..dfc901617 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/tasks/setup-RedHat.yml @@ -0,0 +1,6 @@ +--- +- name: Ensure Apache is installed on RHEL. + package: + name: "{{ apache_packages }}" + state: "{{ apache_packages_state }}" + enablerepo: "{{ apache_enablerepo | default(omit, true) }}" diff --git a/provisioning/roles/geerlingguy.apache/tasks/setup-Solaris.yml b/provisioning/roles/geerlingguy.apache/tasks/setup-Solaris.yml new file mode 100644 index 000000000..a4ae4504d --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/tasks/setup-Solaris.yml @@ -0,0 +1,5 @@ +--- +- name: Ensure Apache is installed on Solaris. + pkg5: + name: "{{ apache_packages }}" + state: "{{ apache_packages_state }}" diff --git a/provisioning/roles/geerlingguy.apache/tasks/setup-Suse.yml b/provisioning/roles/geerlingguy.apache/tasks/setup-Suse.yml new file mode 100644 index 000000000..725266b1a --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/tasks/setup-Suse.yml @@ -0,0 +1,5 @@ +--- +- name: Ensure Apache is installed on Suse. + zypper: + name: "{{ apache_packages }}" + state: "{{ apache_packages_state }}" diff --git a/provisioning/roles/geerlingguy.apache/templates/vhosts.conf.j2 b/provisioning/roles/geerlingguy.apache/templates/vhosts.conf.j2 new file mode 100644 index 000000000..b5307b94d --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/templates/vhosts.conf.j2 @@ -0,0 +1,82 @@ +{{ apache_global_vhost_settings }} + +{# Set up VirtualHosts #} +{% for vhost in apache_vhosts %} +<VirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}> + ServerName {{ vhost.servername }} +{% if vhost.serveralias is defined %} + ServerAlias {{ vhost.serveralias }} +{% endif %} +{% if vhost.documentroot is defined %} + DocumentRoot "{{ vhost.documentroot }}" +{% endif %} + +{% if vhost.serveradmin is defined %} + ServerAdmin {{ vhost.serveradmin }} +{% endif %} +{% if vhost.documentroot is defined %} + <Directory "{{ vhost.documentroot }}"> + AllowOverride {{ vhost.allow_override | default(apache_allow_override) }} + Options {{ vhost.options | default(apache_options) }} +{% if apache_vhosts_version == "2.2" %} + Order allow,deny + Allow from all +{% else %} + Require all granted +{% endif %} + </Directory> +{% endif %} +{% if vhost.extra_parameters is defined %} +{{ vhost.extra_parameters | indent(width=2, first=True) }} +{% endif %} +</VirtualHost> + +{% endfor %} + +{# Set up SSL VirtualHosts #} +{% for vhost in apache_vhosts_ssl %} +{% if apache_ignore_missing_ssl_certificate or apache_ssl_certificates.results[loop.index0].stat.exists %} +<VirtualHost {{ apache_listen_ip }}:{{ apache_listen_port_ssl }}> + ServerName {{ vhost.servername }} +{% if vhost.serveralias is defined %} + ServerAlias {{ vhost.serveralias }} +{% endif %} +{% if vhost.documentroot is defined %} + DocumentRoot "{{ vhost.documentroot }}" +{% endif %} + + SSLEngine on + SSLCipherSuite {{ apache_ssl_cipher_suite }} + SSLProtocol {{ apache_ssl_protocol }} + SSLHonorCipherOrder On +{% if apache_vhosts_version == "2.4" %} + SSLCompression off +{% endif %} + SSLCertificateFile {{ vhost.certificate_file }} + SSLCertificateKeyFile {{ vhost.certificate_key_file }} +{% if vhost.certificate_chain_file is defined %} + SSLCertificateChainFile {{ vhost.certificate_chain_file }} +{% endif %} + +{% if vhost.serveradmin is defined %} + ServerAdmin {{ vhost.serveradmin }} +{% endif %} +{% if vhost.documentroot is defined %} + <Directory "{{ vhost.documentroot }}"> + AllowOverride {{ vhost.allow_override | default(apache_allow_override) }} + Options {{ vhost.options | default(apache_options) }} +{% if apache_vhosts_version == "2.2" %} + Order allow,deny + Allow from all +{% else %} + Require all granted +{% endif %} + </Directory> +{% endif %} +{% if vhost.extra_parameters is defined %} +{{ vhost.extra_parameters | indent(width=2, first=True) }} +{% endif %} +</VirtualHost> + +{% endif %} +{% endfor %} diff --git a/provisioning/roles/geerlingguy.apache/vars/AmazonLinux.yml b/provisioning/roles/geerlingguy.apache/vars/AmazonLinux.yml new file mode 100644 index 000000000..165f65d88 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/vars/AmazonLinux.yml @@ -0,0 +1,18 @@ +--- +apache_service: httpd +apache_daemon: httpd +apache_daemon_path: /usr/sbin/ +apache_server_root: /etc/httpd +apache_conf_path: /etc/httpd/conf.d + +apache_vhosts_version: "2.4" + +__apache_packages: + - httpd24 + - httpd24-devel + - mod24_ssl + - openssh + +apache_ports_configuration_items: + - regexp: "^Listen " + line: "Listen {{ apache_listen_port }}" diff --git a/provisioning/roles/geerlingguy.apache/vars/Debian.yml b/provisioning/roles/geerlingguy.apache/vars/Debian.yml new file mode 100644 index 000000000..7ff09c5f8 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/vars/Debian.yml @@ -0,0 +1,14 @@ +--- +apache_service: apache2 +apache_daemon: apache2 +apache_daemon_path: /usr/sbin/ +apache_server_root: /etc/apache2 +apache_conf_path: /etc/apache2 + +__apache_packages: + - apache2 + - apache2-utils + +apache_ports_configuration_items: + - regexp: "^Listen " + line: "Listen {{ apache_listen_port }}" diff --git a/provisioning/roles/geerlingguy.apache/vars/RedHat.yml b/provisioning/roles/geerlingguy.apache/vars/RedHat.yml new file mode 100644 index 000000000..d79fa5ac5 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/vars/RedHat.yml @@ -0,0 +1,20 @@ +--- +apache_service: httpd +apache_daemon: httpd +apache_daemon_path: /usr/sbin/ +apache_server_root: /etc/httpd +apache_conf_path: /etc/httpd/conf.d + +apache_vhosts_version: "2.2" + +__apache_packages: + - httpd + - httpd-devel + - mod_ssl + - openssh + +apache_ports_configuration_items: + - regexp: "^Listen " + line: "Listen {{ apache_listen_port }}" + - regexp: "^#?NameVirtualHost " + line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}" diff --git a/provisioning/roles/geerlingguy.apache/vars/Solaris.yml b/provisioning/roles/geerlingguy.apache/vars/Solaris.yml new file mode 100644 index 000000000..576291e8d --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/vars/Solaris.yml @@ -0,0 +1,19 @@ +--- +apache_service: apache24 +apache_daemon: httpd +apache_daemon_path: /usr/apache2/2.4/bin/ +apache_server_root: /etc/apache2/2.4/ +apache_conf_path: /etc/apache2/2.4/conf.d + +apache_vhosts_version: "2.2" + +__apache_packages: + - web/server/apache-24 + - web/server/apache-24/module/apache-ssl + - web/server/apache-24/module/apache-security + +apache_ports_configuration_items: + - regexp: "^Listen " + line: "Listen {{ apache_listen_port }}" + - regexp: "^#?NameVirtualHost " + line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}" diff --git a/provisioning/roles/geerlingguy.apache/vars/Suse.yml b/provisioning/roles/geerlingguy.apache/vars/Suse.yml new file mode 100644 index 000000000..27703f336 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/vars/Suse.yml @@ -0,0 +1,18 @@ +--- +apache_service: apache2 +apache_daemon: httpd2 +apache_daemon_path: /usr/sbin/ +apache_server_root: /etc/apache2 +apache_conf_path: /etc/apache2/conf.d + +apache_vhosts_version: "2.2" + +__apache_packages: + - apache2 + - openssh + +apache_ports_configuration_items: + - regexp: "^Listen " + line: "Listen {{ apache_listen_port }}" + - regexp: "^#?NameVirtualHost " + line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}" diff --git a/provisioning/roles/geerlingguy.apache/vars/apache-22.yml b/provisioning/roles/geerlingguy.apache/vars/apache-22.yml new file mode 100644 index 000000000..c932f93f5 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/vars/apache-22.yml @@ -0,0 +1,12 @@ +--- +apache_vhosts_version: "2.2" +apache_default_vhost_filename: 000-default +apache_ports_configuration_items: + - { + regexp: "^Listen ", + line: "Listen {{ apache_listen_port }}" + } + - { + regexp: "^#?NameVirtualHost ", + line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}" + } diff --git a/provisioning/roles/geerlingguy.apache/vars/apache-24.yml b/provisioning/roles/geerlingguy.apache/vars/apache-24.yml new file mode 100644 index 000000000..449a444e8 --- /dev/null +++ b/provisioning/roles/geerlingguy.apache/vars/apache-24.yml @@ -0,0 +1,8 @@ +--- +apache_vhosts_version: "2.4" +apache_default_vhost_filename: 000-default.conf +apache_ports_configuration_items: + - { + regexp: "^Listen ", + line: "Listen {{ apache_listen_port }}" + } diff --git a/provisioning/roles/geerlingguy.blackfire/.ansible-lint b/provisioning/roles/geerlingguy.blackfire/.ansible-lint new file mode 100644 index 000000000..d09fda886 --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/.ansible-lint @@ -0,0 +1,2 @@ +skip_list: + - '503' diff --git a/provisioning/roles/geerlingguy.blackfire/.github/FUNDING.yml b/provisioning/roles/geerlingguy.blackfire/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.blackfire/.gitignore b/provisioning/roles/geerlingguy.blackfire/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.blackfire/.travis.yml b/provisioning/roles/geerlingguy.blackfire/.travis.yml new file mode 100644 index 000000000..dc43b419b --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/.travis.yml @@ -0,0 +1,28 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: blackfire + matrix: + - MOLECULE_DISTRO: centos7 + - MOLECULE_DISTRO: ubuntu1804 + - MOLECULE_DISTRO: debian9 + +install: + # Install test dependencies. + - pip install molecule yamllint ansible-lint docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.blackfire/.yamllint b/provisioning/roles/geerlingguy.blackfire/.yamllint new file mode 100644 index 000000000..a3dbc38ee --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/.yamllint @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 120 + level: warning diff --git a/provisioning/roles/geerlingguy.blackfire/LICENSE b/provisioning/roles/geerlingguy.blackfire/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.blackfire/README.md b/provisioning/roles/geerlingguy.blackfire/README.md new file mode 100644 index 000000000..60999b04c --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/README.md @@ -0,0 +1,46 @@ +# Ansible Role: Blackfire + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-blackfire.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-blackfire) + +Installs [Blackfire](https://blackfire.io/) on RHEL/CentOS or Debian/Ubuntu. + +## Requirements + +After installation, you need to complete Blackfire setup manually before profiling: + + 1. Register the Blackfire agent: `sudo blackfire-agent -register` + 2. Configure Blackfire: `blackfire config` + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + blackfire_packages: + - blackfire-agent + - blackfire-php + +The Blackfire packages this role will install on the server. Note that `blackfire-php` may not work well with XHProf and/or XDebug. + + blackfire_gpg_key_url: https://packages.blackfire.io/gpg.key + blackfire_repo_url: http://packages.blackfire.io/fedora/blackfire.repo + +Variables used for Blackfire package setup and installation. + +## Dependencies + +Requires the `geerlingguy.php` role. + +## Example Playbook + + - hosts: webserver + roles: + - geerlingguy.php + - geerlingguy.blackfire + +## License + +MIT / BSD + +## Author Information + +This role was created in 2016 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.blackfire/defaults/main.yml b/provisioning/roles/geerlingguy.blackfire/defaults/main.yml new file mode 100644 index 000000000..e263820d9 --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/defaults/main.yml @@ -0,0 +1,7 @@ +--- +blackfire_packages: + - blackfire-agent + - blackfire-php + +blackfire_gpg_key_url: https://packages.blackfire.io/gpg.key +blackfire_repo_url: http://packages.blackfire.io/fedora/blackfire.repo diff --git a/provisioning/roles/geerlingguy.blackfire/meta/main.yml b/provisioning/roles/geerlingguy.blackfire/meta/main.yml new file mode 100644 index 000000000..20bf33662 --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/meta/main.yml @@ -0,0 +1,29 @@ +--- +dependencies: + - geerlingguy.php + +galaxy_info: + author: geerlingguy + description: Blackfire installation for Linux + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - 6 + - 7 + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - precise + - raring + - saucy + - trusty + - xenial + - bionic + galaxy_tags: + - development + - web diff --git a/provisioning/roles/geerlingguy.blackfire/molecule/default/converge.yml b/provisioning/roles/geerlingguy.blackfire/molecule/default/converge.yml new file mode 100644 index 000000000..97ed5e181 --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/molecule/default/converge.yml @@ -0,0 +1,56 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + php_enable_php_fpm: true + + handlers: + - name: update apt cache + apt: update_cache=true + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + # Ubuntu-specific tasks. + - name: Add dependencies for apt key (Ubuntu). + apt: + name: dirmngr + state: present + when: ansible_distribution == 'Ubuntu' + + - name: Add repository for PHP 7 (Ubuntu). + apt_repository: repo='ppa:ondrej/php' + when: ansible_distribution == 'Ubuntu' + + # Debian-specific tasks. + - name: Add dependencies for PHP versions (Debian). + apt: + name: + - apt-transport-https + - ca-certificates + state: present + when: ansible_distribution == "Debian" + + - name: Add Ondrej Sury's apt key (Debian). + apt_key: + url: https://packages.sury.org/php/apt.gpg + state: present + when: ansible_distribution == "Debian" + + - name: Add Ondrej Sury's repo (Debian). + apt_repository: + repo: "deb https://packages.sury.org/php/ {{ ansible_distribution_release }} main" + state: present + when: ansible_distribution == "Debian" + notify: update apt cache + + - meta: flush_handlers + + roles: + - geerlingguy.php + - geerlingguy.blackfire diff --git a/provisioning/roles/geerlingguy.blackfire/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.blackfire/molecule/default/molecule.yml new file mode 100644 index 000000000..38eb962bd --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/molecule/default/molecule.yml @@ -0,0 +1,20 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: | + yamllint . + ansible-lint +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.blackfire/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.blackfire/molecule/default/requirements.yml new file mode 100644 index 000000000..de297a054 --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/molecule/default/requirements.yml @@ -0,0 +1,2 @@ +--- +- src: geerlingguy.php diff --git a/provisioning/roles/geerlingguy.blackfire/tasks/main.yml b/provisioning/roles/geerlingguy.blackfire/tasks/main.yml new file mode 100644 index 000000000..d45192a1c --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/tasks/main.yml @@ -0,0 +1,14 @@ +--- +- include_tasks: setup-RedHat.yml + when: ansible_os_family == 'RedHat' + +- include_tasks: setup-Debian.yml + when: ansible_os_family == 'Debian' + +- name: Ensure Blackfire packages are installed. + package: + name: "{{ blackfire_packages }}" + state: present + notify: + - restart webserver + - restart php-fpm diff --git a/provisioning/roles/geerlingguy.blackfire/tasks/setup-Debian.yml b/provisioning/roles/geerlingguy.blackfire/tasks/setup-Debian.yml new file mode 100644 index 000000000..2dbf56a92 --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/tasks/setup-Debian.yml @@ -0,0 +1,22 @@ +--- +- name: Ensure dirmngr is installed (gnupg dependency). + apt: + name: dirmngr + state: present + +- name: Add packagecloud apt key. + apt_key: + url: "{{ blackfire_gpg_key_url }}" + state: present + +- name: Add packagecloud repository. + apt_repository: + repo: "{{ item }}" + state: present + register: packagecloud_repos + with_items: + - "deb http://packages.blackfire.io/debian any main" + +- name: Update apt caches after repo is added. + apt: update_cache=yes + when: packagecloud_repos.changed diff --git a/provisioning/roles/geerlingguy.blackfire/tasks/setup-RedHat.yml b/provisioning/roles/geerlingguy.blackfire/tasks/setup-RedHat.yml new file mode 100644 index 000000000..d2285352c --- /dev/null +++ b/provisioning/roles/geerlingguy.blackfire/tasks/setup-RedHat.yml @@ -0,0 +1,18 @@ +--- +- name: Check if Blackfire repository file exists. + stat: path=/etc/yum.repos.d/blackfire.repo + register: repo_file_stat + +- name: Add Blackfire repository. + get_url: + url: "{{ blackfire_repo_url }}" + dest: /etc/yum.repos.d/blackfire.repo + mode: 0644 + when: not repo_file_stat.stat.exists + +- name: Disable gpg_repocheck for non-bleeding-edge CentOS. + lineinfile: + dest: /etc/yum.repos.d/blackfire.repo + regexp: "^repo_gpgcheck=" + line: "repo_gpgcheck=0" + state: present diff --git a/provisioning/roles/geerlingguy.composer/.ansible-lint b/provisioning/roles/geerlingguy.composer/.ansible-lint new file mode 100644 index 000000000..192211d37 --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/.ansible-lint @@ -0,0 +1,3 @@ +skip_list: + - '106' + - '204' diff --git a/provisioning/roles/geerlingguy.composer/.github/FUNDING.yml b/provisioning/roles/geerlingguy.composer/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.composer/.github/stale.yml b/provisioning/roles/geerlingguy.composer/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.composer/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.composer/.github/workflows/ci.yml new file mode 100644 index 000000000..493f349e3 --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/.github/workflows/ci.yml @@ -0,0 +1,68 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "0 6 * * 0" + +defaults: + run: + working-directory: 'geerlingguy.composer' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.composer' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint ansible-lint + + - name: Lint code. + run: | + yamllint . + ansible-lint + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + distro: + - centos7 + - ubuntu1804 + - debian9 + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.composer' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} diff --git a/provisioning/roles/geerlingguy.composer/.github/workflows/release.yml b/provisioning/roles/geerlingguy.composer/.github/workflows/release.yml new file mode 100644 index 000000000..054152bef --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.composer' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.composer' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.composer/.gitignore b/provisioning/roles/geerlingguy.composer/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.composer/.yamllint b/provisioning/roles/geerlingguy.composer/.yamllint new file mode 100644 index 000000000..7107275b1 --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 140 + level: warning + +ignore: | + .github/stale.yml + .travis.ci diff --git a/provisioning/roles/geerlingguy.composer/LICENSE b/provisioning/roles/geerlingguy.composer/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.composer/README.md b/provisioning/roles/geerlingguy.composer/README.md new file mode 100644 index 000000000..b932b3cf8 --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/README.md @@ -0,0 +1,80 @@ +# Ansible Role: Composer + +[![CI](https://github.com/geerlingguy/ansible-role-composer/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-composer/actions?query=workflow%3ACI) + +Installs Composer, the PHP Dependency Manager, on any Linux or UNIX system. + +## Requirements + + - `php` (version 5.4+) should be installed and working (you can use the `geerlingguy.php` role to install). + - `git` should be installed and working (you can use the `geerlingguy.git` role to install). + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + composer_path: /usr/local/bin/composer + +The path where composer will be installed and available to your system. Should be in your user's `$PATH` so you can run commands simply with `composer` instead of the full path. + + composer_keep_updated: false + +Set this to `true` to update Composer to the latest release every time the playbook is run. + + composer_home_path: '~/.composer' + composer_home_owner: root + composer_home_group: root + +The `COMPOSER_HOME` path and directory ownership; this is the directory where global packages will be installed. + + composer_version: '' + +You can install a specific release of Composer, e.g. `composer_version: '1.0.0-alpha11'`. If left empty the latest development version will be installed. Note that `composer_keep_updated` will override this variable, as it will always install the latest development version. + + composer_version_branch: '--2' + +You can choose which major branch of composer you wish to use. Default is `--2`. Note that `composer_keep_updated` will update the latest version available for this branch. + + composer_global_packages: [] + +A list of packages to install globally (using `composer global require`). If you want to install any packages globally, add a list item with a dictionary with the `name` of the package and a `release`, e.g. `- { name: phpunit/phpunit, release: "4.7.*" }`. The 'release' is optional, and defaults to `@stable`. + + composer_add_to_path: true + +If `true`, and if there are any configured `composer_global_packages`, the `vendor/bin` directory inside `composer_home_path` will be added to the system's default `$PATH` (for all users). + + composer_project_path: /path/to/project + +Path to a composer project. + + composer_add_project_to_path: false + +If `true`, and if you have configured a `composer_project_path`, the `vendor/bin` directory inside `composer_project_path` will be added to the system's default `$PATH` (for all users). + + composer_github_oauth_token: '' + +GitHub OAuth token, used to avoid GitHub API rate limiting errors when building and rebuilding applications using Composer. Follow GitHub's directions to [Create a personal access token](https://help.github.com/articles/creating-an-access-token-for-command-line-use/) if you run into these rate limit errors. + + php_executable: php + +The executable name or full path to the PHP executable. This is defaulted to `php` if you don't override the variable. + +## Dependencies + +None (but make sure you've installed PHP; the `geerlingguy.php` role is recommended). + +## Example Playbook + + - hosts: servers + roles: + - geerlingguy.composer + +After the playbook runs, `composer` will be placed in `/usr/local/bin/composer` (this location is configurable), and will be accessible via normal system accounts. + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.composer/defaults/main.yml b/provisioning/roles/geerlingguy.composer/defaults/main.yml new file mode 100644 index 000000000..3cd45a773 --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/defaults/main.yml @@ -0,0 +1,25 @@ +--- +composer_path: /usr/local/bin/composer +composer_keep_updated: false +composer_version: '' +composer_version_branch: '--2' + +# The directory where global packages will be installed. +composer_home_path: '~/.composer' +composer_home_owner: root +composer_home_group: root + +# A list of packages to install globally. See commented examples below for +# usage; the 'release' is optional, and defaults to '@stable'. +composer_global_packages: [] +# - { name: phpunit/phpunit, release: "4.7.x" } +# - { name: phpunit/phpunit, release: "@stable" } + +composer_add_to_path: true + +# Add a project vendor/bin directory to the PATH +composer_add_project_to_path: false +# composer_project_path: /path/to/project/vendor/bin + +# GitHub OAuth token (used to help overcome API rate limits). +composer_github_oauth_token: '' diff --git a/provisioning/roles/geerlingguy.composer/meta/main.yml b/provisioning/roles/geerlingguy.composer/meta/main.yml new file mode 100644 index 000000000..0b3da1012 --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/meta/main.yml @@ -0,0 +1,44 @@ +--- +dependencies: [] + +galaxy_info: + role_name: composer + author: geerlingguy + description: Composer PHP Dependency Manager + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + - name: GenericUNIX + versions: + - all + - name: Fedora + versions: + - all + - name: opensuse + versions: + - all + - name: GenericBSD + versions: + - all + - name: FreeBSD + versions: + - all + - name: Ubuntu + versions: + - all + - name: SLES + versions: + - all + - name: GenericLinux + versions: + - all + - name: Debian + versions: + - all + galaxy_tags: + - packaging + - web diff --git a/provisioning/roles/geerlingguy.composer/molecule/default/converge.yml b/provisioning/roles/geerlingguy.composer/molecule/default/converge.yml new file mode 100644 index 000000000..f6470f99a --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/molecule/default/converge.yml @@ -0,0 +1,54 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enablerepo: "remi,remi-php70" + php_enable_webserver: false + + # Test a global requirement. + composer_global_packages: + - name: phpunit/phpunit + release: "@stable" + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_distribution == 'Ubuntu' + + - name: Set php_packages for PHP 7.0 Debian 8 install. + set_fact: + php_packages: + - php7.0-common + - php7.0-cli + - php7.0-dev + - php7.0-fpm + - libpcre3-dev + - php7.0-opcache + - php7.0-apcu + - php7.0-xml + when: ansible_distribution == 'Debian' + + - name: Set php_packages for Fedora install. + set_fact: + php_packages: + - php + - php-cli + - php-common + - php-devel + - php-mbstring + - php-opcache + - php-pecl-apcu + - php-xml + - php-json + when: ansible_distribution == 'Fedora' + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' and ansible_distribution != 'Fedora' + - role: geerlingguy.repo-dotdeb + when: ansible_distribution == 'Debian' + - role: geerlingguy.git + - role: geerlingguy.php + - role: geerlingguy.composer diff --git a/provisioning/roles/geerlingguy.composer/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.composer/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.composer/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.composer/molecule/default/requirements.yml new file mode 100644 index 000000000..8263a0c90 --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/molecule/default/requirements.yml @@ -0,0 +1,5 @@ +--- +- src: geerlingguy.repo-remi +- src: geerlingguy.repo-dotdeb +- src: geerlingguy.git +- src: geerlingguy.php diff --git a/provisioning/roles/geerlingguy.composer/tasks/global-require.yml b/provisioning/roles/geerlingguy.composer/tasks/global-require.yml new file mode 100644 index 000000000..d9f3b0def --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/tasks/global-require.yml @@ -0,0 +1,18 @@ +--- +- name: Install configured globally-required packages. + command: > + {{ composer_path }} global require {{ item.name }}:{{ item.release | default('@stable') }} --no-progress --no-interaction + creates={{ composer_home_path }}/vendor/{{ item.name }} + environment: + COMPOSER_HOME: "{{ composer_home_path }}" + become: true + become_user: "{{ composer_home_owner }}" + register: composer_global_require_result + with_items: "{{ composer_global_packages }}" + +- name: Add composer_home_path bin directory to global $PATH. + template: + src: composer.sh.j2 + dest: /etc/profile.d/composer.sh + mode: 0644 + when: composer_add_to_path | bool diff --git a/provisioning/roles/geerlingguy.composer/tasks/main.yml b/provisioning/roles/geerlingguy.composer/tasks/main.yml new file mode 100644 index 000000000..db8f6f154 --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/tasks/main.yml @@ -0,0 +1,70 @@ +--- +- name: Set php_executable variable to a default if not defined. + set_fact: + php_executable: php + when: php_executable is not defined + +- name: Check if Composer is installed. + stat: "path={{ composer_path }}" + register: composer_bin + +- name: Get Composer installer signature. + uri: + url: https://composer.github.io/installer.sig + return_content: true + register: composer_installer_signature + when: not composer_bin.stat.exists + +- name: Download Composer installer. + get_url: + url: https://getcomposer.org/installer + dest: /tmp/composer-installer.php + mode: 0755 + checksum: "sha384:{{ composer_installer_signature.content }}" + when: not composer_bin.stat.exists + +- name: Run Composer installer. + command: > + {{ php_executable }} composer-installer.php {% if composer_version_branch %} {{ composer_version_branch }}{% elif composer_version %} --version={{ composer_version }}{% endif %} + chdir=/tmp + when: not composer_bin.stat.exists + +- name: Move Composer into globally-accessible location. + command: > + mv /tmp/composer.phar {{ composer_path }} + creates={{ composer_path }} + when: not composer_bin.stat.exists + +- name: Update Composer to latest version (if configured). + command: > + {{ php_executable }} {{ composer_path }} self-update {{ composer_version_branch }} + register: composer_update + changed_when: "'Updating to version' in composer_update.stdout" + when: composer_keep_updated | bool + +- name: Ensure composer directory exists. + become: true + become_user: "{{ composer_home_owner }}" + file: + path: "{{ composer_home_path }}" + owner: "{{ composer_home_owner }}" + group: "{{ composer_home_group }}" + state: directory + mode: 0755 + +- name: Add GitHub OAuth token for Composer (if configured). + become: true + become_user: "{{ composer_home_owner }}" + template: + src: "auth.json.j2" + dest: "{{ composer_home_path }}/auth.json" + owner: "{{ composer_home_owner }}" + group: "{{ composer_home_group }}" + mode: 0644 + when: composer_github_oauth_token | length > 0 + +- include_tasks: global-require.yml + when: composer_global_packages | length > 0 + +- include_tasks: project-bin.yml + when: composer_add_project_to_path | bool diff --git a/provisioning/roles/geerlingguy.composer/tasks/project-bin.yml b/provisioning/roles/geerlingguy.composer/tasks/project-bin.yml new file mode 100644 index 000000000..3f9112e36 --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/tasks/project-bin.yml @@ -0,0 +1,6 @@ +--- +- name: Add composer_project_path bin directory to global $PATH. + template: + src: composer-project.sh.j2 + dest: /etc/profile.d/composer-project.sh + mode: 0644 diff --git a/provisioning/roles/geerlingguy.composer/templates/auth.json.j2 b/provisioning/roles/geerlingguy.composer/templates/auth.json.j2 new file mode 100644 index 000000000..a41c2142d --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/templates/auth.json.j2 @@ -0,0 +1,5 @@ +{ + "github-oauth": { + "github.com": "{{ composer_github_oauth_token }}" + } +} diff --git a/provisioning/roles/geerlingguy.composer/templates/composer-project.sh.j2 b/provisioning/roles/geerlingguy.composer/templates/composer-project.sh.j2 new file mode 100644 index 000000000..9c77dbeec --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/templates/composer-project.sh.j2 @@ -0,0 +1 @@ +export PATH={{ composer_project_path }}:$PATH diff --git a/provisioning/roles/geerlingguy.composer/templates/composer.sh.j2 b/provisioning/roles/geerlingguy.composer/templates/composer.sh.j2 new file mode 100644 index 000000000..3e6cd7a36 --- /dev/null +++ b/provisioning/roles/geerlingguy.composer/templates/composer.sh.j2 @@ -0,0 +1 @@ +export PATH=$PATH:{{ composer_home_path }}/vendor/bin diff --git a/provisioning/roles/geerlingguy.daemonize/.ansible-lint b/provisioning/roles/geerlingguy.daemonize/.ansible-lint new file mode 100644 index 000000000..555729425 --- /dev/null +++ b/provisioning/roles/geerlingguy.daemonize/.ansible-lint @@ -0,0 +1,2 @@ +skip_list: + - '106' diff --git a/provisioning/roles/geerlingguy.daemonize/.github/FUNDING.yml b/provisioning/roles/geerlingguy.daemonize/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.daemonize/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.daemonize/.github/stale.yml b/provisioning/roles/geerlingguy.daemonize/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.daemonize/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.daemonize/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.daemonize/.github/workflows/ci.yml new file mode 100644 index 000000000..4c3c89e84 --- /dev/null +++ b/provisioning/roles/geerlingguy.daemonize/.github/workflows/ci.yml @@ -0,0 +1,67 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "30 6 * * 0" + +defaults: + run: + working-directory: 'geerlingguy.daemonize' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.daemonize' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint ansible-lint + + - name: Lint code. + run: | + yamllint . + ansible-lint + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + distro: + - centos7 + - ubuntu1804 + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.daemonize' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} diff --git a/provisioning/roles/geerlingguy.daemonize/.github/workflows/release.yml b/provisioning/roles/geerlingguy.daemonize/.github/workflows/release.yml new file mode 100644 index 000000000..e733f503b --- /dev/null +++ b/provisioning/roles/geerlingguy.daemonize/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.daemonize' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.daemonize' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.daemonize/.gitignore b/provisioning/roles/geerlingguy.daemonize/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.daemonize/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.daemonize/.yamllint b/provisioning/roles/geerlingguy.daemonize/.yamllint new file mode 100644 index 000000000..f2033dd21 --- /dev/null +++ b/provisioning/roles/geerlingguy.daemonize/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/provisioning/roles/geerlingguy.daemonize/LICENSE b/provisioning/roles/geerlingguy.daemonize/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.daemonize/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.daemonize/README.md b/provisioning/roles/geerlingguy.daemonize/README.md new file mode 100644 index 000000000..2f7f0118b --- /dev/null +++ b/provisioning/roles/geerlingguy.daemonize/README.md @@ -0,0 +1,43 @@ +# Ansible Role: Daemonize + +[![CI](https://github.com/geerlingguy/ansible-role-daemonize/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-daemonize/actions?query=workflow%3ACI) + +Installs [Daemonize](http://software.clapper.org/daemonize/), a tool for running commands as a Unix daemon. + +## Requirements + +Make sure you have `gcc` or other build tools installed (e.g. `yum install make automake gcc gcc-c++ kernel-devel` on RedHat, or `apt-get install build-essential` on Debian) prior to running this role, as it builds Daemonize from source. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + workspace: /root + +The location where code will be downloaded and compiled. + + daemonize_version: 1.7.5 + +The daemonize release version to install. + + daemonize_install_path: "/usr" + +The path where the compiled daemonize binary will be installed. + +## Dependencies + +None. + +## Example Playbook + + - hosts: servers + roles: + - { role: geerlingguy.daemonize } + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.daemonize/defaults/main.yml b/provisioning/roles/geerlingguy.daemonize/defaults/main.yml new file mode 100644 index 000000000..29b95d5a3 --- /dev/null +++ b/provisioning/roles/geerlingguy.daemonize/defaults/main.yml @@ -0,0 +1,5 @@ +--- +workspace: /root + +daemonize_version: 1.7.7 +daemonize_install_path: "/usr" diff --git a/provisioning/roles/geerlingguy.daemonize/meta/main.yml b/provisioning/roles/geerlingguy.daemonize/meta/main.yml new file mode 100644 index 000000000..2711c4bc4 --- /dev/null +++ b/provisioning/roles/geerlingguy.daemonize/meta/main.yml @@ -0,0 +1,29 @@ +--- +dependencies: [] + +galaxy_info: + role_name: daemonize + author: geerlingguy + description: "Daemonize for Unix-like operating systems" + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.0 + platforms: + - name: EL + versions: + - all + - name: Ubuntu + versions: + - all + - name: Debian + versions: + - all + - name: GenericUNIX + versions: + - all + - any + galaxy_tags: + - development + - web + - system + - mail diff --git a/provisioning/roles/geerlingguy.daemonize/molecule/default/converge.yml b/provisioning/roles/geerlingguy.daemonize/molecule/default/converge.yml new file mode 100644 index 000000000..7ef4de602 --- /dev/null +++ b/provisioning/roles/geerlingguy.daemonize/molecule/default/converge.yml @@ -0,0 +1,30 @@ +--- +- name: Converge + hosts: all + become: true + + pre_tasks: + - name: Ensure build dependencies are installed (RedHat). + yum: 'name="{{ item }}" state=present' + with_items: + - "@Development tools" + - tar + - unzip + when: ansible_os_family == 'RedHat' + + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + - name: Ensure build dependencies are installed (Debian). + apt: 'name="{{ item }}" state=present' + with_items: + - build-essential + - unzip + - tar + - sudo + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.daemonize diff --git a/provisioning/roles/geerlingguy.daemonize/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.daemonize/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.daemonize/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.daemonize/tasks/main.yml b/provisioning/roles/geerlingguy.daemonize/tasks/main.yml new file mode 100644 index 000000000..765cfbdb6 --- /dev/null +++ b/provisioning/roles/geerlingguy.daemonize/tasks/main.yml @@ -0,0 +1,31 @@ +--- +- name: Download daemonize archive. + get_url: + url: "https://github.com/bmc/daemonize/archive/release-{{ daemonize_version }}.tar.gz" + dest: "{{ workspace }}/daemonize-{{ daemonize_version }}.tar.gz" + +- name: Expand daemonize archive. + unarchive: + src: "{{ workspace }}/daemonize-{{ daemonize_version }}.tar.gz" + dest: "{{ workspace }}" + creates: "{{ workspace }}/daemonize-release-{{ daemonize_version }}/INSTALL" + copy: false + mode: 0755 + +- name: Check if daemonize is installed. + command: which daemonize + changed_when: false + failed_when: false + register: daemonize_installed + +- name: Build daemonize. + command: > + {{ item }} + chdir={{ workspace }}/daemonize-release-{{ daemonize_version }} + when: daemonize_installed.rc != 0 + ignore_errors: "{{ ansible_check_mode }}" + with_items: + - "./configure --prefix={{ daemonize_install_path }}" + - make + - make install + become: true diff --git a/provisioning/roles/geerlingguy.drupal-console/.gitignore b/provisioning/roles/geerlingguy.drupal-console/.gitignore new file mode 100644 index 000000000..c9b2377e3 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal-console/.gitignore @@ -0,0 +1,2 @@ +*.retry +tests/test.sh diff --git a/provisioning/roles/geerlingguy.drupal-console/.travis.yml b/provisioning/roles/geerlingguy.drupal-console/.travis.yml new file mode 100644 index 000000000..38bb908c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal-console/.travis.yml @@ -0,0 +1,28 @@ +--- +services: docker + +env: + - distro: ubuntu1604 + playbook: test.yml + - distro: ubuntu1404 + playbook: test.yml + - distro: ubuntu1604 + playbook: test-self-update.yml + +script: + # Configure test script so we can run extra tests after playbook is run. + - export container_id=$(date +%s) + - export cleanup=false + + # Download test shim. + - wget -O ${PWD}/tests/test.sh https://gist.githubusercontent.com/geerlingguy/73ef1e5ee45d8694570f334be385e181/raw/ + - chmod +x ${PWD}/tests/test.sh + + # Run tests. + - ${PWD}/tests/test.sh + + # Ensure Drupal Console is installed and working. + - 'docker exec --tty ${container_id} env TERM=xterm drupal list || true' + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.drupal-console/LICENSE b/provisioning/roles/geerlingguy.drupal-console/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal-console/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.drupal-console/README.md b/provisioning/roles/geerlingguy.drupal-console/README.md new file mode 100644 index 000000000..0a46b09c7 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal-console/README.md @@ -0,0 +1,45 @@ +# Ansible Role: Drupal Console + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-drupal-console.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-drupal-console) + +Installs [Drupal Console](http://drupalconsole.com/) on any Linux or UNIX system. + +## Requirements + +`php` (version 5.6+) should be installed and working. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + drupal_console_path: /usr/local/bin/drupal + +The path where Drupal Console will be installed and available to your system. Should be in your user's `$PATH` so you can use Drupal Console by entering `drupal` instead of the full path. + + drupal_console_keep_updated: false + +By default, this role not update Drupal Console when it is run again. If you'd like always update Drupal Console to the latest version when this role is run, switch this variable to `true`. + + drupal_console_config: ~/.console + +The path to the Drupal Console configuration file. + +## Dependencies + + - geerlingguy.php (Installs PHP). + +## Example Playbook + + - hosts: servers + roles: + - role: geerlingguy.drupal-console + +After the playbook runs, `drupal` will be placed in `/usr/local/bin/drupal` (this location is configurable), and will be accessible via normal system accounts. + +## License + +MIT / BSD + +## Author Information + +This role was created in 2015 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.drupal-console/defaults/main.yml b/provisioning/roles/geerlingguy.drupal-console/defaults/main.yml new file mode 100644 index 000000000..5885c7a4e --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal-console/defaults/main.yml @@ -0,0 +1,4 @@ +--- +drupal_console_path: /usr/local/bin/drupal +drupal_console_keep_updated: false +drupal_console_config: ~/.console diff --git a/provisioning/roles/geerlingguy.drupal-console/meta/main.yml b/provisioning/roles/geerlingguy.drupal-console/meta/main.yml new file mode 100644 index 000000000..9b13c630c --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal-console/meta/main.yml @@ -0,0 +1,44 @@ +--- +dependencies: + - geerlingguy.php + +galaxy_info: + author: geerlingguy + description: Drupal Console + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 1.8 + platforms: + - name: EL + versions: + - all + - name: GenericUNIX + versions: + - all + - name: Fedora + versions: + - all + - name: opensuse + versions: + - all + - name: GenericBSD + versions: + - all + - name: FreeBSD + versions: + - all + - name: Ubuntu + versions: + - all + - name: SLES + versions: + - all + - name: GenericLinux + versions: + - all + - name: Debian + versions: + - all + galaxy_tags: + - packaging + - web diff --git a/provisioning/roles/geerlingguy.drupal-console/tasks/main.yml b/provisioning/roles/geerlingguy.drupal-console/tasks/main.yml new file mode 100644 index 000000000..0a413085d --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal-console/tasks/main.yml @@ -0,0 +1,45 @@ +--- +- name: Ensure pip is available for an extra dependency on Ubuntu 14.04. + package: + name: "{{ item }}" + state: present + with_items: + - python-pip + - python-openssl + - python-pyasn1 + when: + - ansible_distribution == 'Ubuntu' + - ansible_distribution_version == '14.04' + +- name: Upgrade setuptools on Ubuntu 14.04. + pip: + name: setuptools + state: latest + when: + - ansible_distribution == 'Ubuntu' + - ansible_distribution_version == '14.04' + +- name: Ensure ndg-httpsclient is available on Ubuntu 14.04. + pip: + name: ndg-httpsclient + state: present + when: + - ansible_distribution == 'Ubuntu' + - ansible_distribution_version == '14.04' + +- name: Install Drupal Console. + get_url: + url: https://drupalconsole.com/installer + dest: "{{ drupal_console_path }}" + +- name: Ensure Drupal Console is executable. + file: + path: "{{ drupal_console_path }}" + mode: 0755 + +- name: Update Drupal Console to latest version (if configured). + shell: > + php {{ drupal_console_path }} self-update + register: drupal_console_update + changed_when: "'console has been updated' in drupal_console_update.stdout" + when: drupal_console_keep_updated diff --git a/provisioning/roles/geerlingguy.drupal-console/tests/README.md b/provisioning/roles/geerlingguy.drupal-console/tests/README.md new file mode 100644 index 000000000..6fb211721 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal-console/tests/README.md @@ -0,0 +1,11 @@ +# Ansible Role tests + +To run the test playbook(s) in this directory: + + 1. Install and start Docker. + 1. Download the test shim (see .travis.yml file for the URL) into `tests/test.sh`: + - `wget -O tests/test.sh https://gist.githubusercontent.com/geerlingguy/73ef1e5ee45d8694570f334be385e181/raw/` + 1. Make the test shim executable: `chmod +x tests/test.sh`. + 1. Run (from the role root directory) `distro=[distro] playbook=[playbook] ./tests/test.sh` + +If you don't want the container to be automatically deleted after the test playbook is run, add the following environment variables: `cleanup=false container_id=$(date +%s)` diff --git a/provisioning/roles/geerlingguy.drupal-console/tests/requirements.yml b/provisioning/roles/geerlingguy.drupal-console/tests/requirements.yml new file mode 100644 index 000000000..de297a054 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal-console/tests/requirements.yml @@ -0,0 +1,2 @@ +--- +- src: geerlingguy.php diff --git a/provisioning/roles/geerlingguy.drupal-console/tests/test-self-update.yml b/provisioning/roles/geerlingguy.drupal-console/tests/test-self-update.yml new file mode 100644 index 000000000..78b4fe2f7 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal-console/tests/test-self-update.yml @@ -0,0 +1,16 @@ +--- +- hosts: all + + vars: + php_enable_webserver: false + drupal_console_keep_updated: true + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + roles: + - geerlingguy.php + - role_under_test diff --git a/provisioning/roles/geerlingguy.drupal-console/tests/test.yml b/provisioning/roles/geerlingguy.drupal-console/tests/test.yml new file mode 100644 index 000000000..b920c8d5b --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal-console/tests/test.yml @@ -0,0 +1,19 @@ +--- +- hosts: all + + vars: + php_enable_webserver: false + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + - name: Add repository for PHP 7.0 (Ubuntu). + apt_repository: repo='ppa:ondrej/php' + when: ansible_distribution == "Ubuntu" and ansible_distribution_version != "16.04" + + roles: + - geerlingguy.php + - role_under_test diff --git a/provisioning/roles/geerlingguy.drupal/.ansible-lint b/provisioning/roles/geerlingguy.drupal/.ansible-lint new file mode 100644 index 000000000..4b5e4fde5 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/.ansible-lint @@ -0,0 +1,4 @@ +skip_list: + - 'yaml' + - 'no-handler' + - 'role-name' diff --git a/provisioning/roles/geerlingguy.drupal/.github/FUNDING.yml b/provisioning/roles/geerlingguy.drupal/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.drupal/.github/stale.yml b/provisioning/roles/geerlingguy.drupal/.github/stale.yml new file mode 100644 index 000000000..3cc6ec313 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/.github/stale.yml @@ -0,0 +1,57 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - bug + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.drupal/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.drupal/.github/workflows/ci.yml new file mode 100644 index 000000000..cff7a133b --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/.github/workflows/ci.yml @@ -0,0 +1,73 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "30 5 * * 1" + +defaults: + run: + working-directory: 'geerlingguy.drupal' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.drupal' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + include: + - distro: rockylinux8 + playbook: converge.yml + - distro: ubuntu1804 + playbook: converge.yml + # - distro: debian10 + # playbook: converge.yml + - distro: rockylinux8 + playbook: deploy.yml + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.drupal' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} + MOLECULE_PLAYBOOK: ${{ matrix.playbook }} diff --git a/provisioning/roles/geerlingguy.drupal/.github/workflows/release.yml b/provisioning/roles/geerlingguy.drupal/.github/workflows/release.yml new file mode 100644 index 000000000..fec1983e9 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.drupal' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.drupal' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.drupal/.gitignore b/provisioning/roles/geerlingguy.drupal/.gitignore new file mode 100644 index 000000000..8840c8f02 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/.gitignore @@ -0,0 +1,5 @@ +*.retry +*/__pycache__ +*.pyc +.cache + diff --git a/provisioning/roles/geerlingguy.drupal/.yamllint b/provisioning/roles/geerlingguy.drupal/.yamllint new file mode 100644 index 000000000..a8dc58bd7 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 160 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/provisioning/roles/geerlingguy.drupal/LICENSE b/provisioning/roles/geerlingguy.drupal/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.drupal/README.md b/provisioning/roles/geerlingguy.drupal/README.md new file mode 100644 index 000000000..91d909a61 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/README.md @@ -0,0 +1,142 @@ +# Ansible Role: Drupal + +[![CI](https://github.com/geerlingguy/ansible-role-drupal/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-drupal/actions?query=workflow%3ACI) + +Builds and installs [Drupal](https://drupal.org/), an open source content management platform. + +## Requirements + +Drupal is a PHP-based application that is meant to run behind a typical LAMP/LEMP/LEPP/etc. stack, so you'll need at least the following: + + - Apache or Nginx (Recommended: `geerlingguy.apache` or `geerlingguy.nginx`) + - MySQL or similar Database server (Recommended: `geerlingguy.mysql` or `geerlingguy.postgresql`) + - PHP (Recommended: `geerlingguy.php` along with other PHP-related roles like `php-mysql`). + +Drush is not an absolute requirement, but it's handy to have, and also required if you use this role to Install a Drupal site (`drupal_install_site: true`). You can use `geerlingguy.drush` to install Drush. + +Git is not an absolute requirement, but is required if you're deploying from a Git repository (e.g. `drupal_deploy: true`). You can use `geerlingguy.git` to install Git. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + +### Deploy an existing project with Git + + drupal_deploy: false + drupal_deploy_repo: "" + drupal_deploy_version: master + drupal_deploy_update: true + drupal_deploy_dir: "/var/www/drupal" + drupal_deploy_accept_hostkey: false + +Set `drupal_deploy` to `true` and `drupal_build_composer*` to `false` if you would like to deploy Drupal to your server from an existing Git repository. The other options all apply to the Git checkout operation: + + - `repo`: Git repository address + - `version`: can be a branch, tag, or commit hash + - `update`: whether the repository should be updated to the latest commit, if `version` is a branch + - `dir`: The directory into which the repository will be checked out + - `accept_hostkey`: Whether to automatically accept the Git server's hostkey on the first connection. + +You can also control whether a `composer install` is run after the git clone is finished using the following variable: + + drupal_deploy_composer_install: true + +### Build a project from a Drush Make file + + drupal_build_makefile: false + drush_makefile_path: "/path/to/drupal.make.yml" + drush_make_options: "--no-gitinfofile" + +Set this to `true` and `drupal_build_composer*` to `false` if you would like to build a Drupal make file with Drush. + +### Build a project from a Composer file + + drupal_build_composer: false + drupal_composer_path: "/path/to/drupal.composer.json" + drupal_composer_install_dir: "/var/www/drupal" + drupal_composer_no_dev: true + drupal_composer_dependencies: + - "drush/drush:^10.1" + +Set `drupal_build_makefile` to `false` and this to `true` if you are using a Composer-based site deployment strategy. The other options should be relatively straightforward. + + drupal_composer_bin_dir: "vendor/bin" + +If you set the `bin-dir` in your project's `composer.json` file to a value other than `vendor/bin`, override this variable with the same directory path. + +### Create a new project using `composer create-project` (Composer) + + drupal_build_composer_project: true + drupal_composer_project_package: "drupal/recommended-project:^9@dev" + drupal_composer_project_options: "--prefer-dist --stability dev --no-interaction" + +Set this to `true` and `drupal_build_makefile`, `drupal_build_composer` to `false` if you are using Composer's `create-project` as a site deployment strategy. + +### Required Drupal site settings + + drupal_core_path: "{{ drupal_deploy_dir }}/web" + drupal_core_owner: "{{ ansible_ssh_user | default(ansible_env.SUDO_USER, true) | default(ansible_env.USER, true) | default(ansible_user_id) }}" + drupal_core_owner_become: false + +The path to Drupal's root, along with the ownership properties. If you are not running Ansible as the user that should have ownership over the core path, specify the desired system user in `drupal_core_owner` and set `drupal_core_owner_become: true`. + + drupal_db_user: drupal + drupal_db_password: drupal + drupal_db_name: drupal + drupal_db_backend: mysql + drupal_db_host: "127.0.0.1" + +Required Drupal settings. When used in a production or shared environment, you should update at least the `drupal_db_password` and use a secure password. + +### Drupal site installation options + + drupal_install_site: true + +Set this to `false` if you don't need to install Drupal (using the `drupal_*` settings below), but instead copy down a database (e.g. using `drush sql-sync`). + + drupal_domain: "drupaltest.test" + drupal_site_name: "Drupal" + drupal_install_profile: standard + drupal_site_install_extra_args: [] + drupal_enable_modules: [] + drupal_account_name: admin + drupal_account_pass: admin + +Settings for installing a Drupal site if `drupal_install_site` is `true`. If you need to pass additional arguments to the `drush site-install` command, you can pass them in as a list to the `drupal_site_install_extra_args` variable. + +## Dependencies + +N/A + +## Example Playbook + +See the example playbooks used for Travis CI tests (`tests/test.yml` and `tests/test-deploy.yml`) for simple examples. See also: [Drupal VM](https://www.drupalvm.com), which uses this role to set up Drupal. + + - hosts: webserver + vars_files: + - vars/main.yml + roles: + - geerlingguy.apache + - geerlingguy.mysql + - geerlingguy.php-versions + - geerlingguy.php + - geerlingguy.php-mysql + - geerlingguy.composer + - geerlingguy.drush + - geerlingguy.drupal + +*Inside `vars/main.yml`*: + + drupal_install_site: true + drupal_build_composer_project: true + drupal_composer_install_dir: "/var/www/drupal" + drupal_core_path: "{{ drupal_composer_install_dir }}/web" + drupal_domain: "example.com" + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.drupal/defaults/main.yml b/provisioning/roles/geerlingguy.drupal/defaults/main.yml new file mode 100644 index 000000000..3ff8b21ff --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/defaults/main.yml @@ -0,0 +1,58 @@ +--- +# Set this to 'true' and specify a Git repository if you want to deploy Drupal +# to your server from an existing repository. +drupal_deploy: false +drupal_deploy_repo: "" +drupal_deploy_version: master +drupal_deploy_update: true +drupal_deploy_dir: "/var/www/drupal" +drupal_deploy_accept_hostkey: false +drupal_deploy_composer_install: true + +# Set this to 'true' and 'drupal_build_composer*' to 'false' if you would like +# to build a Drupal make file with Drush. +drupal_build_makefile: false +drush_makefile_path: "/path/to/drupal.make.yml" +drush_make_options: "--no-gitinfofile" + +# You can configure the `bin-dir` in your project's composer.json `config` key. +drupal_composer_bin_dir: "vendor/bin" + +# Set 'drupal_build_makefile' to 'false' and this to 'true' if you are using a +# Composer-based site deployment strategy. +drupal_build_composer: false +drupal_composer_path: "/path/to/drupal.composer.json" +drupal_composer_install_dir: "{{ drupal_deploy_dir }}" +drupal_composer_no_dev: true +drupal_composer_dependencies: + - "drush/drush:^10.1" + +# Set this to 'true' and 'drupal_build_makefile', 'drupal_build_composer' to +# 'false' if you are using Composer's create-project as a site deployment +# strategy. +drupal_build_composer_project: true +drupal_composer_project_package: "drupal/recommended-project:^9@dev" +drupal_composer_project_options: "--prefer-dist --stability dev --no-interaction" + +# Required Drupal settings. +drupal_core_path: "{{ drupal_deploy_dir }}/web" +drupal_core_owner: "{{ ansible_ssh_user | default(ansible_env.SUDO_USER, true) | default(ansible_env.USER, true) | default(ansible_user_id) }}" +drupal_core_owner_become: false +drupal_db_user: drupal +drupal_db_password: drupal +drupal_db_name: drupal +drupal_db_backend: mysql +drupal_db_host: "127.0.0.1" + +# Set this to 'false' if you don't need to install Drupal (using the drupal_* +# settings below), but instead copy down a database (e.g. using drush sql-sync). +drupal_install_site: true + +# Settings for installing a Drupal site if 'drupal_install_site:' is 'true'. +drupal_domain: "drupaltest.test" +drupal_site_name: "Drupal" +drupal_install_profile: standard +drupal_site_install_extra_args: [] +drupal_enable_modules: [] +drupal_account_name: admin +drupal_account_pass: admin diff --git a/provisioning/roles/geerlingguy.drupal/handlers/main.yml b/provisioning/roles/geerlingguy.drupal/handlers/main.yml new file mode 100644 index 000000000..dbf5e75f4 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: clear opcache + shell: > + cd {{ drupal_core_path }} && + {{ drush_path }} eval "if (function_exists('apc_clear_cache')) { apc_clear_cache(); }; if (function_exists('opcache_reset')) { opcache_reset(); }" diff --git a/provisioning/roles/geerlingguy.drupal/meta/main.yml b/provisioning/roles/geerlingguy.drupal/meta/main.yml new file mode 100644 index 000000000..937648335 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/meta/main.yml @@ -0,0 +1,26 @@ +--- +dependencies: [] + +galaxy_info: + role_name: drupal + author: geerlingguy + description: Deploy or install Drupal on your servers. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + - name: Ubuntu + versions: + - all + - name: Debian + versions: + - all + galaxy_tags: + - development + - web + - drupal + - cms + - php diff --git a/provisioning/roles/geerlingguy.drupal/molecule/default/converge.yml b/provisioning/roles/geerlingguy.drupal/molecule/default/converge.yml new file mode 100644 index 000000000..1a4a81a4b --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/molecule/default/converge.yml @@ -0,0 +1,27 @@ +--- +- name: Converge + hosts: all + become: true + + environment: + COMPOSER_MEMORY_LIMIT: '-1' + + vars_files: + - test-vars.yml + + pre_tasks: + - import_tasks: test-setup.yml + + roles: + - name: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.repo-dotdeb + when: ansible_distribution == 'Debian' + - role: geerlingguy.apache + - role: geerlingguy.mysql + - role: geerlingguy.php-versions + - role: geerlingguy.php + - role: geerlingguy.php-mysql + - role: geerlingguy.git + - role: geerlingguy.composer + - role: geerlingguy.drupal diff --git a/provisioning/roles/geerlingguy.drupal/molecule/default/deploy.yml b/provisioning/roles/geerlingguy.drupal/molecule/default/deploy.yml new file mode 100644 index 000000000..3be18bfc9 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/molecule/default/deploy.yml @@ -0,0 +1,37 @@ +--- +- name: Converge + hosts: all + become: true + + vars_files: + - test-vars.yml + + vars: + # Deploy from the Drupal for Kubernetes example project. + drupal_deploy: true + drupal_deploy_repo: "https://github.com/geerlingguy/drupal-for-kubernetes.git" + drupal_deploy_dir: /var/www/drupal + drupal_domain: "test.pidramble.com" + + # Disable Composer-based codebase setup. + drupal_build_composer_project: false + drupal_build_composer: false + drupal_composer_dependencies: [] + + pre_tasks: + - import_tasks: test-setup.yml + + roles: + - name: geerlingguy.repo-remi + when: ansible_os_family == "RedHat" + - role: geerlingguy.repo-dotdeb + when: ansible_distribution == 'Debian' + - role: geerlingguy.apache + - role: geerlingguy.mysql + - role: geerlingguy.php-versions + - role: geerlingguy.php + - role: geerlingguy.php-mysql + - role: geerlingguy.git + - role: geerlingguy.composer + - role: geerlingguy.drush + - role: geerlingguy.drupal diff --git a/provisioning/roles/geerlingguy.drupal/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.drupal/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.drupal/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.drupal/molecule/default/requirements.yml new file mode 100644 index 000000000..c630c6cc5 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/molecule/default/requirements.yml @@ -0,0 +1,15 @@ +--- +- src: geerlingguy.repo-remi +- src: geerlingguy.repo-dotdeb +- src: geerlingguy.apache +- src: geerlingguy.apache-php-fpm +- src: geerlingguy.nginx +- src: geerlingguy.mysql +- src: geerlingguy.postgresql +- src: geerlingguy.php-versions +- src: geerlingguy.php +- src: geerlingguy.php-mysql +- src: geerlingguy.php-pgsql +- src: geerlingguy.git +- src: geerlingguy.composer +- src: geerlingguy.drush diff --git a/provisioning/roles/geerlingguy.drupal/molecule/default/test-setup.yml b/provisioning/roles/geerlingguy.drupal/molecule/default/test-setup.yml new file mode 100644 index 000000000..4a6d6c1f8 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/molecule/default/test-setup.yml @@ -0,0 +1,11 @@ +--- +- name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + +- name: Install dependencies. + package: + name: + - curl + - unzip + - sendmail diff --git a/provisioning/roles/geerlingguy.drupal/molecule/default/test-vars.yml b/provisioning/roles/geerlingguy.drupal/molecule/default/test-vars.yml new file mode 100644 index 000000000..e9f30da40 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/molecule/default/test-vars.yml @@ -0,0 +1,34 @@ +--- +php_version: "7.3" +php_enable_webserver: false +php_enablerepo: "remi,remi-php71" +php_enable_php_fpm: true +php_fpm_listen: "127.0.0.1:9000" + +apache_mods_enabled: + - expires.load + - ssl.load + - rewrite.load + - proxy.load + - proxy_fcgi.load +apache_remove_default_vhost: true +apache_vhosts: + - servername: "{{ drupal_domain }}" + serveralias: "www.{{ drupal_domain }}" + documentroot: "{{ drupal_core_path }}" + extra_parameters: | + <FilesMatch \.php$> + SetHandler "proxy:fcgi://{{ php_fpm_listen }}" + </FilesMatch> + +mysql_python_package_debian: python3-mysqldb +mysql_enablerepo: "remi" +mysql_databases: + - name: "{{ drupal_db_name }}" + encoding: utf8mb4 + collation: utf8mb4_general_ci +mysql_users: + - name: "{{ drupal_db_user }}" + host: "%" + password: "{{ drupal_db_password }}" + priv: "{{ drupal_db_name }}.*:ALL" diff --git a/provisioning/roles/geerlingguy.drupal/tasks/backwards-compatibility.yml b/provisioning/roles/geerlingguy.drupal/tasks/backwards-compatibility.yml new file mode 100644 index 000000000..f6732fd56 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/tasks/backwards-compatibility.yml @@ -0,0 +1,26 @@ +--- +# Shims for Drupal VM backwards compatibility. To be removed by 2018. +- name: build_makefile shim + set_fact: + drupal_build_makefile: "{{ build_makefile }}" + when: build_makefile|default('') + +- name: build_composer shim + set_fact: + drupal_build_composer: "{{ build_composer }}" + when: build_composer|default('') + +- name: build_composer_project shim + set_fact: + drupal_build_composer_project: "{{ build_composer_project }}" + when: build_composer_project|default('') + +- name: install_site shim + set_fact: + drupal_install_site: "{{ install_site }}" + when: install_site|default('') + +- name: drupalvm_database shim + set_fact: + drupal_db_backend: "{{ drupalvm_database }}" + when: drupalvm_database|default('') diff --git a/provisioning/roles/geerlingguy.drupal/tasks/build-composer-project.yml b/provisioning/roles/geerlingguy.drupal/tasks/build-composer-project.yml new file mode 100644 index 000000000..a84f1eb9c --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/tasks/build-composer-project.yml @@ -0,0 +1,45 @@ +--- +- name: Delete old /tmp/composer-project + file: + path: "/tmp/composer-project" + state: absent + when: not drupal_site_exists + +- name: Generate Drupal project with composer package in /tmp/composer-project (this may take a while). + command: > + {{ composer_path }} create-project + {{ drupal_composer_project_package }} /tmp/composer-project + {{ drupal_composer_project_options|default('--prefer-dist --no-interaction') }} + when: not drupal_site_exists + become: false + environment: + COMPOSER_PROCESS_TIMEOUT: 1200 + COMPOSER_MEMORY_LIMIT: '-1' + +- name: Ensure drupal_composer_install_dir directory has proper permissions. + file: + path: "{{ drupal_composer_install_dir }}" + state: directory + owner: "{{ drupal_core_owner }}" + group: "{{ drupal_core_owner }}" + mode: 0775 + when: not drupal_site_exists + failed_when: false + +- name: Move Drupal project files to drupal_composer_install_dir (this may take a while). + command: > + cp -r /tmp/composer-project/. {{ drupal_composer_install_dir }}/ + creates={{ drupal_core_path }}/index.php + become: false + when: not drupal_site_exists + +- name: Install dependencies with composer require (this may take a while). + composer: + command: require + arguments: "{{ item }}" + working_dir: "{{ drupal_composer_install_dir }}" + with_items: "{{ drupal_composer_dependencies | default([]) }}" + become: false + environment: + COMPOSER_PROCESS_TIMEOUT: 1200 + COMPOSER_MEMORY_LIMIT: '-1' diff --git a/provisioning/roles/geerlingguy.drupal/tasks/build-composer.yml b/provisioning/roles/geerlingguy.drupal/tasks/build-composer.yml new file mode 100644 index 000000000..81123969e --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/tasks/build-composer.yml @@ -0,0 +1,41 @@ +--- +- name: Ensure drupal_composer_install_dir directory exists. + file: + path: "{{ drupal_composer_install_dir }}" + state: directory + mode: 0775 + become: false + when: drupal_composer_path and not drupal_site_exists + +# Use copy-and-move to prevent issues in Windows with VirtualBox. See: +# https://github.com/ansible/ansible/issues/9526#issuecomment-62336962 +- name: Copy composer.json into temporary location. + copy: + src: "{{ drupal_composer_path }}" + dest: "/tmp/drupalvm-composer.json" + mode: 0644 + when: drupal_composer_path and not drupal_site_exists + become: false + +- name: Move composer.json into place. + command: "mv /tmp/drupalvm-composer.json {{ drupal_composer_install_dir }}/composer.json" + when: drupal_composer_path and not drupal_site_exists + become: false + +- name: Run composer install (this may take a while). + composer: + command: install + working_dir: "{{ drupal_composer_install_dir }}" + when: not drupal_site_exists + become: false + +- name: Install dependencies with composer require (this may take a while). + composer: + command: require + arguments: "{{ item }}" + working_dir: "{{ drupal_composer_install_dir }}" + with_items: "{{ drupal_composer_dependencies | default([]) }}" + become: false + environment: + COMPOSER_PROCESS_TIMEOUT: 1200 + COMPOSER_MEMORY_LIMIT: '-1' diff --git a/provisioning/roles/geerlingguy.drupal/tasks/build-makefile.yml b/provisioning/roles/geerlingguy.drupal/tasks/build-makefile.yml new file mode 100644 index 000000000..d905470dc --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/tasks/build-makefile.yml @@ -0,0 +1,35 @@ +--- +- name: Copy drush makefile into place. + copy: + src: "{{ drush_makefile_path }}" + dest: /tmp/drupal.make.yml + mode: 0644 + when: not drupal_site_exists + +- name: Ensure drupal_core_path directory exists. + file: + path: "{{ drupal_core_path }}" + state: directory + recurse: true + mode: 0775 + become: false + when: not drupal_site_exists + +- name: Generate Drupal site with drush makefile. + command: > + {{ drush_path }} make -y /tmp/drupal.make.yml {{ drush_make_options }} + chdir={{ drupal_core_path }} + when: not drupal_site_exists + become: false + +- name: Check if a composer.json file is present. + stat: "path={{ drupal_core_path }}/composer.json" + register: drupal_core_composer_file + when: not drupal_site_exists + +- name: Run composer install if composer.json is present. + command: > + composer install + chdir={{ drupal_core_path }} + when: not drupal_site_exists and drupal_core_composer_file.stat.exists + become: false diff --git a/provisioning/roles/geerlingguy.drupal/tasks/deploy.yml b/provisioning/roles/geerlingguy.drupal/tasks/deploy.yml new file mode 100644 index 000000000..b036acd15 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/tasks/deploy.yml @@ -0,0 +1,37 @@ +--- +- name: Ensure drupal_deploy_dir directory exists. + file: + path: "{{ drupal_deploy_dir }}" + state: directory + mode: 0775 + owner: "{{ drupal_core_owner }}" + group: "{{ drupal_core_owner }}" + when: drupal_composer_path and not drupal_site_exists + +- name: Check out Drupal to the docroot. + git: + repo: "{{ drupal_deploy_repo }}" + version: "{{ drupal_deploy_version }}" + update: "{{ drupal_deploy_update }}" + force: true + dest: "{{ drupal_deploy_dir }}" + accept_hostkey: "{{ drupal_deploy_accept_hostkey }}" + register: drupal_deploy_repo_updated + notify: clear opcache + become: "{{ drupal_core_owner_become }}" + become_user: "{{ drupal_core_owner }}" + +- name: Check if a composer.json file is present. + stat: "path={{ drupal_deploy_dir }}/composer.json" + register: drupal_deploy_composer_file + +- name: Run composer install if composer.json is present. + composer: + command: install + working_dir: "{{ drupal_deploy_dir }}" + no_dev: "{{ drupal_composer_no_dev }}" + when: + - drupal_deploy_composer_file.stat.exists + - drupal_deploy_composer_install + become: "{{ drupal_core_owner_become }}" + become_user: "{{ drupal_core_owner }}" diff --git a/provisioning/roles/geerlingguy.drupal/tasks/install-site.yml b/provisioning/roles/geerlingguy.drupal/tasks/install-site.yml new file mode 100644 index 000000000..a7be00777 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/tasks/install-site.yml @@ -0,0 +1,43 @@ +--- +- name: Check if site is already installed. + command: "{{ drush_path }} --root={{ drupal_core_path }} status bootstrap" + args: + chdir: "{{ drupal_core_path }}" + register: drupal_site_installed + failed_when: "drupal_site_installed.stdout is undefined" + changed_when: false + become: false + +# See: https://www.drupal.org/node/2569365#comment-11680807 +- name: Configure database correctly if using PostgreSQL. + command: psql -c "ALTER DATABASE {{ drupal_db_name }} SET bytea_output = 'escape';" + when: "('Drupal bootstrap' not in drupal_site_installed.stdout) and (drupal_db_backend == 'pgsql')" + become: true + become_user: "{{ postgresql_user }}" + # See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509 + vars: + ansible_ssh_pipelining: true + +- name: Install Drupal with drush. + command: > + {{ drush_path }} site-install {{ drupal_install_profile | default('standard') }} -y + --root={{ drupal_core_path }} + --site-name="{{ drupal_site_name }}" + --account-name="{{ drupal_account_name }}" + --account-pass={{ drupal_account_pass }} + --db-url={{ drupal_db_backend }}://{{ drupal_db_user }}:{{ drupal_db_password }}@{{ drupal_db_host }}/{{ drupal_db_name }} + {{ drupal_site_install_extra_args | join(" ") }} + args: + chdir: "{{ drupal_core_path }}" + notify: clear opcache + when: "'Drupal bootstrap' not in drupal_site_installed.stdout" + become: false + +- name: Install configured modules with drush. + command: > + {{ drush_path }} pm-enable -y {{ drupal_enable_modules | join(" ") }} + --root={{ drupal_core_path }} + args: + chdir: "{{ drupal_core_path }}" + when: ('Drupal bootstrap' not in drupal_site_installed.stdout) and drupal_enable_modules + become: false diff --git a/provisioning/roles/geerlingguy.drupal/tasks/main.yml b/provisioning/roles/geerlingguy.drupal/tasks/main.yml new file mode 100644 index 000000000..b520649a9 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/tasks/main.yml @@ -0,0 +1,56 @@ +--- +- name: Add backwards-compatibility shims. + include_tasks: backwards-compatibility.yml + +- name: Check if Drupal is already set up. + stat: "path={{ drupal_core_path }}/index.php" + register: drupal_site + ignore_errors: true + +- name: Define drush_path if it's not already defined. + set_fact: + drush_path: drush + when: drush_path is not defined + +- name: Define drupal_site_exists. + set_fact: + drupal_site_exists: "{{ drupal_site.stat.exists|default(false) }}" + +# Deploy Drupal if configured. +- include_tasks: deploy.yml + when: drupal_deploy + +- name: Define drupal_deploy_updated + set_fact: + drupal_deploy_updated: "{{ (drupal_deploy_repo_updated is defined and drupal_deploy_repo_updated.changed) | default(false) }}" + +# Run update tasks if Drupal was updated. +- include_tasks: update.yml + when: drupal_deploy_updated and drupal_site_exists + +# Build makefile if configured. +- include_tasks: build-makefile.yml + when: drupal_build_makefile + +# Build with composer if configured. +- include_tasks: build-composer.yml + when: drupal_build_composer + +# Build a composer project if configured. +- include_tasks: build-composer-project.yml + when: drupal_build_composer_project + +# Set Drush variables. +- name: Check if a project specific Drush binary exists. + stat: "path={{ drupal_composer_install_dir }}/{{ drupal_composer_bin_dir }}/drush" + register: drush_vendor_bin + ignore_errors: true + +- name: Use project specific Drush if available. + set_fact: + drush_path: "{{ drupal_composer_install_dir }}/{{ drupal_composer_bin_dir }}/drush" + when: drush_vendor_bin.stat.exists + +# Install site if configured. +- include_tasks: install-site.yml + when: drupal_install_site diff --git a/provisioning/roles/geerlingguy.drupal/tasks/update.yml b/provisioning/roles/geerlingguy.drupal/tasks/update.yml new file mode 100644 index 000000000..fd6078343 --- /dev/null +++ b/provisioning/roles/geerlingguy.drupal/tasks/update.yml @@ -0,0 +1,16 @@ +--- +- name: Run database updates. + command: "{{ drush_path }} updatedb -y" + args: + chdir: "{{ drupal_core_path }}" + register: drush_database_updates + changed_when: "'No database updates required.' not in drush_database_updates.stdout" + +# TODO: Import configuration if configured? +# TODO: Other commands if configured? + +- name: Rebuild Drupal caches. + command: "{{ drush_path }} cache-rebuild --quiet" + args: + chdir: "{{ drupal_core_path }}" + tags: ['skip_ansible_lint'] diff --git a/provisioning/roles/geerlingguy.drush/.ansible-lint b/provisioning/roles/geerlingguy.drush/.ansible-lint new file mode 100644 index 000000000..af2cdfe6f --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/.ansible-lint @@ -0,0 +1,3 @@ +skip_list: + - '503' + - '106' diff --git a/provisioning/roles/geerlingguy.drush/.github/FUNDING.yml b/provisioning/roles/geerlingguy.drush/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.drush/.github/stale.yml b/provisioning/roles/geerlingguy.drush/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.drush/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.drush/.github/workflows/ci.yml new file mode 100644 index 000000000..8cabc649b --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/.github/workflows/ci.yml @@ -0,0 +1,76 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "0 4 * * 1" + +defaults: + run: + working-directory: 'geerlingguy.drush' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.drush' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint ansible-lint + + - name: Lint code. + run: | + yamllint . + ansible-lint + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + include: + - distro: centos7 + playbook: converge.yml + - distro: ubuntu1804 + playbook: converge.yml + - distro: debian9 + playbook: converge.yml + - distro: centos7 + playbook: composer.yml + - distro: centos7 + playbook: source.yml + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.drush' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} + MOLECULE_PLAYBOOK: ${{ matrix.playbook }} diff --git a/provisioning/roles/geerlingguy.drush/.github/workflows/release.yml b/provisioning/roles/geerlingguy.drush/.github/workflows/release.yml new file mode 100644 index 000000000..611bd55ef --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.drush' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.drush' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.drush/.gitignore b/provisioning/roles/geerlingguy.drush/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.drush/.travis.yml b/provisioning/roles/geerlingguy.drush/.travis.yml new file mode 100644 index 000000000..a1672dc96 --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/.travis.yml @@ -0,0 +1,36 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: drush + matrix: + - MOLECULE_DISTRO: centos7 + - MOLECULE_DISTRO: ubuntu1804 + - MOLECULE_DISTRO: debian9 + - MOLECULE_DISTRO: centos7 + MOLECULE_PLAYBOOK: playbook-composer.yml + - MOLECULE_DISTRO: centos7 + MOLECULE_PLAYBOOK: playbook-source.yml + +before_install: + # Upgrade Docker to work with docker-py. + - curl https://gist.githubusercontent.com/geerlingguy/ce883ad4aec6a5f1187ef93bd338511e/raw/36612d28981d92863f839c5aefe5b7dd7193d6c6/travis-ci-docker-upgrade.sh | sudo bash + +install: + # Install test dependencies. + - pip install molecule[docker] yamllint ansible-lint docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.drush/.yamllint b/provisioning/roles/geerlingguy.drush/.yamllint new file mode 100644 index 000000000..f2033dd21 --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/provisioning/roles/geerlingguy.drush/LICENSE b/provisioning/roles/geerlingguy.drush/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.drush/README.md b/provisioning/roles/geerlingguy.drush/README.md new file mode 100644 index 000000000..9f8ccf9c5 --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/README.md @@ -0,0 +1,116 @@ +# Ansible Role: Drush + +[![CI](https://github.com/geerlingguy/ansible-role-drush/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-drush/actions?query=workflow%3ACI) + +Installs [Drush](http://www.drush.org), a command line shell and scripting interface for Drupal, on any Linux or UNIX system. + +## Requirements + +PHP must be installed on the system prior to running this role (suggested role: `geerlingguy.php`). + +Global composer installation requires Composer to also be installed on the system (suggested role: `geerlingguy.composer`). + +Source installation additionally requires Git and Composer to also be installed on the system (suggested roles: `geerlingguy.git` and `geerlingguy.composer`). + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + +### Drush Launcher + +[Drush Launcher](https://github.com/drush-ops/drush-launcher) is a small wrapper around Drush for your global `$PATH`. + +It is the recommended way to use `drush`, but there are some situations where you might wish to install and run Drush globally without using Drush Launcher. The following variables control Drush Launcher's installation: + + drush_launcher_install: true + +Set to `no` if you don't want the launcher installed. + + drush_launcher_version: "0.6.0" + +The version of the Drush Launcher to install. This should exactly match an available [Drush Launcher release](https://github.com/drush-ops/drush-launcher/releases). + + drush_launcher_phar_url: https://github.com/drush-ops/drush-launcher/releases/download/{{ drush_launcher_version }}/drush.phar + +The URL from which the Drush Launcher phar file will be downloaded. + + drush_launcher_path: /usr/local/bin/drush + +The path where drush will be installed and available to your system. Should be in your user's `$PATH` so you can run commands simply with `drush` instead of the full path. + +### Drush global install via Composer + +Some people need to have the full power of `drush` available globally, and this role allows the global install of Drush via Composer. If using this option, make sure you have Composer installed! + + drush_composer_global_install: false + +Set to `yes` (and set `drush_launcher_install` to `false`) if you want to install `drush` globally using Composer. + + drush_composer_version: "~9.0" + +The version constraint for the global Drush installation. + + drush_composer_update: false + +Whether to run `composer update drush/drush` to ensure the version of Drush installed globally is the latest version. + + drush_composer_global_bin_path: ~/.config/composer/vendor/bin + drush_composer_path: /usr/local/bin/drush + +The global path where Composer installs global binaries, and the path in which you'd like the `drush` binary to be placed. + +> NOTE: Composer 'global' installation is global _to the user under which Drush is installed_—e.g. if you install globally using the root user, `drush` will only work properly as `root` or when using `sudo`. + +### Variables used for source install (Git). + +You can also install Drush from source if you need a bleeding-edge release, or if you need a specific version which can't be installed via Composer. + + drush_install_from_source: false + +Set to `yes` (and set `drush_launcher_install` to `false`) if you want to install `drush` globally using the Drush source code. + + drush_source_install_bin_path: /usr/local/bin/drush + drush_source_install_path: /usr/local/share/drush + +The location of the entire drush installation (includes all the supporting files, as well as the `drush` executable file. + + drush_source_install_version: "8.x" + +The version of Drush to install (examples: `"master"` for the bleeding edge, `"8.x"`, `"7.x"`, `"6.2.0"`). This should be a string as it refers to a git branch, tag, or commit hash. + + drush_keep_updated: false + drush_force_update: false + +Whether to keep Drush up-to-date with the latest revision of the branch specified by `drush_version`, and whether to force the update (e.g. overwrite local modifications to the drush repository). + + drush_force_composer_install: false + +Use this if you get an error message when provisioning like `Unable to load autoload.php. Run composer install to fetch dependencies and write this file`. It will force a `composer install` inside the Drush directory. + + drush_composer_cli_options: "--prefer-source --no-interaction" + +These options are the safest for avoiding GitHub API rate limits when installing Drush, and can be very helpful when working on dependencies/installation, but builds can be sped up substantially by changing the first option to --prefer-dist. + + drush_clone_depth: 1 + +Whether to clone the entire repo (by default), or specify the number of previous commits for a smaller and faster clone. + +## Dependencies + +None. + +## Example Playbook + + - hosts: servers + roles: + - geerlingguy.drush + +After the playbook runs, the `drush` command will be accessible from normal system accounts. + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.drush/defaults/main.yml b/provisioning/roles/geerlingguy.drush/defaults/main.yml new file mode 100644 index 000000000..1723a1ab3 --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/defaults/main.yml @@ -0,0 +1,25 @@ +--- +# Install Drush Launcher. +drush_launcher_install: true +drush_launcher_version: "0.6.0" +drush_launcher_phar_url: >- + https://github.com/drush-ops/drush-launcher/releases/download/{{ drush_launcher_version }}/drush.phar +drush_launcher_path: /usr/local/bin/drush + +# Install Drush via Composer globally. +drush_composer_global_install: false +drush_composer_version: "~9.0" +drush_composer_update: false +drush_composer_global_bin_path: ~/.config/composer/vendor/bin +drush_composer_path: /usr/local/bin/drush + +# Install from source (git clone + composer-based install). +drush_install_from_source: false +drush_source_install_bin_path: /usr/local/bin/drush +drush_source_install_path: /usr/local/share/drush +drush_source_install_version: "8.x" +drush_keep_updated: false +drush_force_update: false +drush_force_composer_install: false +drush_composer_cli_options: "--prefer-dist --no-interaction" +drush_clone_depth: 1 diff --git a/provisioning/roles/geerlingguy.drush/meta/main.yml b/provisioning/roles/geerlingguy.drush/meta/main.yml new file mode 100644 index 000000000..14733bb6b --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/meta/main.yml @@ -0,0 +1,48 @@ +--- +dependencies: [] + +galaxy_info: + role_name: drush + author: geerlingguy + description: Drush - command line shell for Drupal + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + - name: GenericUNIX + versions: + - all + - name: Fedora + versions: + - all + - name: opensuse + versions: + - all + - name: GenericBSD + versions: + - all + - name: FreeBSD + versions: + - all + - name: Ubuntu + versions: + - all + - name: SLES + versions: + - all + - name: GenericLinux + versions: + - all + - name: Debian + versions: + - all + galaxy_tags: + - development + - web + - drush + - drupal + - command + - cli diff --git a/provisioning/roles/geerlingguy.drush/molecule/default/composer.yml b/provisioning/roles/geerlingguy.drush/molecule/default/composer.yml new file mode 100644 index 000000000..3ed04622b --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/molecule/default/composer.yml @@ -0,0 +1,30 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + php_opcache_enable: "0" + + # Use Composer global install. + drush_launcher_install: false + drush_composer_global_install: true + drush_composer_update: true + + pre_tasks: + + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + - name: Ensure unzip is installed. + package: name=unzip state=present + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.php-versions + - role: geerlingguy.php + - role: geerlingguy.composer + - role: geerlingguy.drush diff --git a/provisioning/roles/geerlingguy.drush/molecule/default/converge.yml b/provisioning/roles/geerlingguy.drush/molecule/default/converge.yml new file mode 100644 index 000000000..a31c174af --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/molecule/default/converge.yml @@ -0,0 +1,24 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + php_opcache_enable: "0" + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + - name: Ensure unzip is installed. + package: name=unzip state=present + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.php-versions + - role: geerlingguy.php + - role: geerlingguy.composer + - role: geerlingguy.drush diff --git a/provisioning/roles/geerlingguy.drush/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.drush/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.drush/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.drush/molecule/default/requirements.yml new file mode 100644 index 000000000..7c724e64b --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/molecule/default/requirements.yml @@ -0,0 +1,6 @@ +--- +- src: geerlingguy.repo-remi +- src: geerlingguy.php-versions +- src: geerlingguy.php +- src: geerlingguy.composer +- src: geerlingguy.git diff --git a/provisioning/roles/geerlingguy.drush/molecule/default/source.yml b/provisioning/roles/geerlingguy.drush/molecule/default/source.yml new file mode 100644 index 000000000..78883d4e0 --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/molecule/default/source.yml @@ -0,0 +1,25 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + php_opcache_enable: "0" + drush_launcher_install: false + drush_composer_global_install: false + drush_install_from_source: true + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.php-versions + - role: geerlingguy.php + - role: geerlingguy.composer + - role: geerlingguy.git + - role: geerlingguy.drush diff --git a/provisioning/roles/geerlingguy.drush/tasks/install-drush-composer.yml b/provisioning/roles/geerlingguy.drush/tasks/install-drush-composer.yml new file mode 100644 index 000000000..fadd11e0c --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/tasks/install-drush-composer.yml @@ -0,0 +1,39 @@ +--- +# Use manual composer tasks until Ansible 2.10.4 is released. +- name: Ensure Drush is installed globally via Composer. + command: "{{ composer_path }} global require drush/drush:{{ drush_composer_version }}" + register: drush_composer_require + changed_when: "'Nothing to install' not in drush_composer_require.stderr" + +- name: Update global Drush install if configured. + command: "{{ composer_path }} global update drush/drush --with-dependencies" + changed_when: "'Nothing to install' not in drush_composer_require.stderr" + register: tasky + when: + - drush_composer_update + - not drush_composer_require.changed + tags: ['skip_ansible_lint'] + +# Switch back to these tasks after Ansible 2.10.4 is released. +# - name: Ensure Drush is installed globally via Composer. +# composer: +# command: require +# global_command: true +# arguments: "drush/drush:{{ drush_composer_version }}" +# register: drush_composer_require +# +# - name: Update global Drush install if configured. +# composer: +# command: update +# global_command: true +# arguments: "drush/drush --with-dependencies" +# when: +# - drush_composer_update +# - not drush_composer_require.changed +# tags: ['skip_ansible_lint'] + +- name: Ensure globally-installed Drush is symlinked into bin dir. + file: # noqa 208 + src: "{{ drush_composer_global_bin_path }}/drush" + dest: "{{ drush_composer_path }}" + state: link diff --git a/provisioning/roles/geerlingguy.drush/tasks/install-drush-launcher.yml b/provisioning/roles/geerlingguy.drush/tasks/install-drush-launcher.yml new file mode 100644 index 000000000..449e01c57 --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/tasks/install-drush-launcher.yml @@ -0,0 +1,27 @@ +--- +- name: Check current state. + stat: + path: "{{ drush_launcher_path }}" + register: drush_path_state + +- name: Perform cleanup of old symlink. + file: + path: "{{ drush_launcher_path }}" + state: absent + when: drush_path_state.stat.islnk is defined and drush_path_state.stat.islnk + +- name: Ensure Drush path directory exists. + file: + path: "{{ drush_launcher_path | dirname }}" + state: directory + mode: 0755 + +- name: Install Drush. + get_url: + url: "{{ drush_launcher_phar_url }}" + dest: "{{ drush_launcher_path }}" + +- name: Ensure Drush is executable. + file: + path: "{{ drush_launcher_path }}" + mode: 0755 diff --git a/provisioning/roles/geerlingguy.drush/tasks/install-source.yml b/provisioning/roles/geerlingguy.drush/tasks/install-source.yml new file mode 100644 index 000000000..b95a07bbd --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/tasks/install-source.yml @@ -0,0 +1,45 @@ +--- +- name: Clone Drush from GitHub. + git: + repo: https://github.com/drush-ops/drush.git + dest: "{{ drush_source_install_path }}" + version: "{{ drush_source_install_version }}" + update: "{{ drush_keep_updated }}" + force: "{{ drush_force_update }}" + depth: "{{ drush_clone_depth }}" + register: drush_clone + +- name: Check for composer.json + stat: path={{ drush_source_install_path }}/composer.json + register: drush_composer + +# See: https://github.com/geerlingguy/ansible-role-drush/issues/6 +- name: Ensure Drush can be installed on Debian Wheezy. + command: > + {{ composer_path }} update {{ drush_composer_cli_options }} + chdir={{ drush_source_install_path }} + when: + - drush_clone.changed and ansible_distribution == "Debian" + - ansible_distribution_release == "wheezy" + - drush_composer.stat.exists + tags: ['skip_ansible_lint'] + +- name: Install Drush dependencies with Composer. + command: > + {{ composer_path }} install {{ drush_composer_cli_options }} + chdir={{ drush_source_install_path }} + when: (drush_clone.changed and drush_composer.stat.exists) or drush_force_composer_install + tags: ['skip_ansible_lint'] + +- name: Create drush symlink. + file: # noqa 208 + src: "{{ drush_source_install_path }}/drush" + dest: "{{ drush_source_install_bin_path }}" + state: link + force: true + +- name: Run drush to finish setting it up. + command: "{{ drush_source_install_bin_path }}" + register: drush_result + changed_when: "'Execute a drush command' not in drush_result.stdout" + become: false diff --git a/provisioning/roles/geerlingguy.drush/tasks/main.yml b/provisioning/roles/geerlingguy.drush/tasks/main.yml new file mode 100644 index 000000000..09a3a19dd --- /dev/null +++ b/provisioning/roles/geerlingguy.drush/tasks/main.yml @@ -0,0 +1,9 @@ +--- +- include_tasks: install-drush-launcher.yml + when: drush_launcher_install + +- include_tasks: install-drush-composer.yml + when: drush_composer_global_install + +- include_tasks: install-source.yml + when: drush_install_from_source diff --git a/provisioning/roles/geerlingguy.elasticsearch/.ansible-lint b/provisioning/roles/geerlingguy.elasticsearch/.ansible-lint new file mode 100644 index 000000000..acc82551f --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/.ansible-lint @@ -0,0 +1,3 @@ +skip_list: + - 'yaml' + - 'role-name' diff --git a/provisioning/roles/geerlingguy.elasticsearch/.github/FUNDING.yml b/provisioning/roles/geerlingguy.elasticsearch/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.elasticsearch/.github/stale.yml b/provisioning/roles/geerlingguy.elasticsearch/.github/stale.yml new file mode 100644 index 000000000..3cc6ec313 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/.github/stale.yml @@ -0,0 +1,57 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - bug + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.elasticsearch/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.elasticsearch/.github/workflows/ci.yml new file mode 100644 index 000000000..eb5ef4456 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/.github/workflows/ci.yml @@ -0,0 +1,66 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "30 4 * * 1" + +defaults: + run: + working-directory: 'geerlingguy.elasticsearch' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.elasticsearch' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + distro: + - centos7 + - ubuntu1804 + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.elasticsearch' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} diff --git a/provisioning/roles/geerlingguy.elasticsearch/.github/workflows/release.yml b/provisioning/roles/geerlingguy.elasticsearch/.github/workflows/release.yml new file mode 100644 index 000000000..3fcb691d3 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.elasticsearch' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.elasticsearch' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.elasticsearch/.gitignore b/provisioning/roles/geerlingguy.elasticsearch/.gitignore new file mode 100644 index 000000000..8840c8f02 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/.gitignore @@ -0,0 +1,5 @@ +*.retry +*/__pycache__ +*.pyc +.cache + diff --git a/provisioning/roles/geerlingguy.elasticsearch/.yamllint b/provisioning/roles/geerlingguy.elasticsearch/.yamllint new file mode 100644 index 000000000..76a383c6a --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/.yamllint @@ -0,0 +1,10 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml diff --git a/provisioning/roles/geerlingguy.elasticsearch/LICENSE b/provisioning/roles/geerlingguy.elasticsearch/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.elasticsearch/README.md b/provisioning/roles/geerlingguy.elasticsearch/README.md new file mode 100644 index 000000000..9b9054532 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/README.md @@ -0,0 +1,77 @@ +# Ansible Role: Elasticsearch + +[![CI](https://github.com/geerlingguy/ansible-role-elasticsearch/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-elasticsearch/actions?query=workflow%3ACI) + +An Ansible Role that installs Elasticsearch on RedHat/CentOS or Debian/Ubuntu. + +## Requirements + +Requires at least Java 8. You can use the [`geerlingguy.java`](https://github.com/geerlingguy/ansible-role-java) to easilly install Java. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml` for default role variables, `vars/RedHat.yml` and `vars/Debian.yml` for distribution specific variables): + + elasticsearch_version: '7.x' + +The major version to use when installing Elasticsearch. + + elasticsearch_package: elasticsearch + +If you want to follow the latest release in the `elasticsearch_version` major release cycle, keep the default here. Otherwise you can add `-7.13.2` (for RHEL-based systems) or `=7.13.2` (for Debian-based systems) to lock in a specific version, e.g. `7.13.2`. + + elasticsearch_package_state: present + +The `elasticsearch` package state; set to `latest` to upgrade or change versions. + + elasticsearch_service_state: started + elasticsearch_service_enabled: true + +Controls the Elasticsearch service options. + + elasticsearch_network_host: localhost + +Network host to listen for incoming connections on. By default we only listen on the localhost interface. Change this to the IP address to listen on a specific interface, or `"0.0.0.0"` to listen on all interfaces. + +When listening on multiple interfaces, if you're setting up a single Elasticsearch server (not a cluster), you should also add `discovery.type: single-node` to `elasticsearch_extra_options`. + + elasticsearch_http_port: 9200 + +The port to listen for HTTP connections on. + + elasticsearch_heap_size_min: 1g + +The minimum jvm heap size. + + elasticsearch_heap_size_max: 2g + +The maximum jvm heap size. + + elasticsearch_extra_options: '' + +A placeholder for arbitrary configuration options not exposed by the role. This will be appended as-is to the end of the `elasticsearch.yml` file, as long as your variable preserves formatting with a `|`. For example: + +```yaml +elasticsearch_extra_options: | # Dont forget the pipe! + some.option: true + another.option: false +``` + +## Dependencies + +None. + +## Example Playbook + + - hosts: search + roles: + - geerlingguy.java + - geerlingguy.elasticsearch + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.elasticsearch/defaults/main.yml b/provisioning/roles/geerlingguy.elasticsearch/defaults/main.yml new file mode 100644 index 000000000..132a30147 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/defaults/main.yml @@ -0,0 +1,15 @@ +--- +elasticsearch_version: '7.x' +elasticsearch_package: elasticsearch +elasticsearch_package_state: present + +elasticsearch_service_state: started +elasticsearch_service_enabled: true + +elasticsearch_network_host: localhost +elasticsearch_http_port: 9200 + +elasticsearch_heap_size_min: 1g +elasticsearch_heap_size_max: 2g + +elasticsearch_extra_options: '' diff --git a/provisioning/roles/geerlingguy.elasticsearch/handlers/main.yml b/provisioning/roles/geerlingguy.elasticsearch/handlers/main.yml new file mode 100644 index 000000000..a4c1162a1 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: restart elasticsearch + service: name=elasticsearch state=restarted diff --git a/provisioning/roles/geerlingguy.elasticsearch/meta/main.yml b/provisioning/roles/geerlingguy.elasticsearch/meta/main.yml new file mode 100644 index 000000000..013d34976 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/meta/main.yml @@ -0,0 +1,29 @@ +--- +dependencies: [] + +galaxy_info: + role_name: elasticsearch + author: geerlingguy + description: Elasticsearch for Linux. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + galaxy_tags: + - web + - system + - monitoring + - logging + - lucene + - elk + - efk + - elasticsearch diff --git a/provisioning/roles/geerlingguy.elasticsearch/molecule/default/converge.yml b/provisioning/roles/geerlingguy.elasticsearch/molecule/default/converge.yml new file mode 100644 index 000000000..d2848a9e3 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/molecule/default/converge.yml @@ -0,0 +1,14 @@ +--- +- name: Converge + hosts: all + become: true + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + roles: + - role: geerlingguy.java + - role: geerlingguy.elasticsearch diff --git a/provisioning/roles/geerlingguy.elasticsearch/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.elasticsearch/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.elasticsearch/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.elasticsearch/molecule/default/requirements.yml new file mode 100644 index 000000000..8fbe7cb66 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/molecule/default/requirements.yml @@ -0,0 +1,2 @@ +--- +- src: geerlingguy.java diff --git a/provisioning/roles/geerlingguy.elasticsearch/tasks/main.yml b/provisioning/roles/geerlingguy.elasticsearch/tasks/main.yml new file mode 100644 index 000000000..1926fe78b --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/tasks/main.yml @@ -0,0 +1,54 @@ +--- + +- include_tasks: setup-RedHat.yml + when: ansible_os_family == 'RedHat' + +- include_tasks: setup-Debian.yml + when: ansible_os_family == 'Debian' + +- name: Install Elasticsearch. + package: + name: "{{ elasticsearch_package }}" + state: "{{ elasticsearch_package_state }}" + +- name: Configure Elasticsearch 6 or below. + template: + src: "{{ item | basename }}.j2" + dest: "{{ item }}" + owner: root + group: elasticsearch + mode: 0660 + with_items: + - /etc/elasticsearch/elasticsearch.yml + - /etc/elasticsearch/jvm.options + notify: restart elasticsearch + when: elasticsearch_version[0] | int < 7 + +- name: Configure Elasticsearch 7+. + template: + src: "{{ item | basename }}.j2" + dest: "{{ item }}" + owner: root + group: elasticsearch + mode: 0660 + with_items: + - /etc/elasticsearch/elasticsearch.yml + - /etc/elasticsearch/jvm.options.d/heap.options + notify: restart elasticsearch + when: elasticsearch_version[0] | int >= 7 + +- name: Force a restart if configuration has changed. + meta: flush_handlers + +- name: Start Elasticsearch. + service: + name: elasticsearch + state: "{{ elasticsearch_service_state }}" + enabled: "{{ elasticsearch_service_enabled }}" + +- name: Make sure Elasticsearch is running before proceeding. + wait_for: + host: "{{ elasticsearch_network_host }}" + port: "{{ elasticsearch_http_port }}" + delay: 3 + timeout: 300 diff --git a/provisioning/roles/geerlingguy.elasticsearch/tasks/setup-Debian.yml b/provisioning/roles/geerlingguy.elasticsearch/tasks/setup-Debian.yml new file mode 100644 index 000000000..9fde3c9f2 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/tasks/setup-Debian.yml @@ -0,0 +1,18 @@ +--- +- name: Add required dependencies. + apt: + name: + - apt-transport-https + - gnupg2 + state: present + +- name: Add Elasticsearch apt key. + apt_key: + url: https://artifacts.elastic.co/GPG-KEY-elasticsearch + state: present + +- name: Add Elasticsearch repository. + apt_repository: + repo: 'deb https://artifacts.elastic.co/packages/{{ elasticsearch_version }}/apt stable main' + state: present + update_cache: true diff --git a/provisioning/roles/geerlingguy.elasticsearch/tasks/setup-RedHat.yml b/provisioning/roles/geerlingguy.elasticsearch/tasks/setup-RedHat.yml new file mode 100644 index 000000000..3882cd237 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/tasks/setup-RedHat.yml @@ -0,0 +1,11 @@ +--- +- name: Add Elasticsearch GPG key. + rpm_key: + key: https://artifacts.elastic.co/GPG-KEY-elasticsearch + state: present + +- name: Add Elasticsearch repository. + template: + src: elasticsearch.repo.j2 + dest: /etc/yum.repos.d/elasticsearch.repo + mode: 0644 diff --git a/provisioning/roles/geerlingguy.elasticsearch/templates/elasticsearch.repo.j2 b/provisioning/roles/geerlingguy.elasticsearch/templates/elasticsearch.repo.j2 new file mode 100644 index 000000000..efdc65950 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/templates/elasticsearch.repo.j2 @@ -0,0 +1,8 @@ +[elasticsearch-{{ elasticsearch_version }}] +name=Elasticsearch repository for {{ elasticsearch_version }} packages +baseurl=https://artifacts.elastic.co/packages/{{ elasticsearch_version }}/yum +gpgcheck=1 +gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch +enabled=1 +autorefresh=1 +type=rpm-md diff --git a/provisioning/roles/geerlingguy.elasticsearch/templates/elasticsearch.yml.j2 b/provisioning/roles/geerlingguy.elasticsearch/templates/elasticsearch.yml.j2 new file mode 100644 index 000000000..85b3a9e81 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/templates/elasticsearch.yml.j2 @@ -0,0 +1,91 @@ +# {{ ansible_managed }} +# ======================== Elasticsearch Configuration ========================= +# +# NOTE: Elasticsearch comes with reasonable defaults for most settings. +# Before you set out to tweak and tune the configuration, make sure you +# understand what are you trying to accomplish and the consequences. +# +# The primary way of configuring a node is via this file. This template lists +# the most important settings you may want to configure for a production cluster. +# +# Please consult the documentation for further information on configuration options: +# https://www.elastic.co/guide/en/elasticsearch/reference/index.html +# +# ---------------------------------- Cluster ----------------------------------- +# +# Use a descriptive name for your cluster: +# +#cluster.name: my-application +# +# ------------------------------------ Node ------------------------------------ +# +# Use a descriptive name for the node: +# +#node.name: node-1 +# +# Add custom attributes to the node: +# +#node.attr.rack: r1 +# +# ----------------------------------- Paths ------------------------------------ +# +# Path to directory where to store the data (separate multiple locations by comma): +# +path.data: /var/lib/elasticsearch +# +# Path to log files: +# +path.logs: /var/log/elasticsearch +# +# ----------------------------------- Memory ----------------------------------- +# +# Lock the memory on startup: +# +#bootstrap.memory_lock: true +# +# Make sure that the heap size is set to about half the memory available +# on the system and that the owner of the process is allowed to use this +# limit. +# +# Elasticsearch performs poorly when the system is swapping the memory. +# +# ---------------------------------- Network ----------------------------------- +# +# Set the bind address to a specific IP (IPv4 or IPv6): +# +network.host: {{ elasticsearch_network_host }} +# +# Set a custom port for HTTP: +# +http.port: {{ elasticsearch_http_port }} +# +# For more information, consult the network module documentation. +# +# --------------------------------- Discovery ---------------------------------- +# +# Pass an initial list of hosts to perform discovery when new node is started: +# The default list of hosts is ["127.0.0.1", "[::1]"] +# +#discovery.zen.ping.unicast.hosts: ["host1", "host2"] +# +# Prevent the "split brain" by configuring the majority of nodes (total number of master-eligible nodes / 2 + 1): +# +#discovery.zen.minimum_master_nodes: +# +# For more information, consult the zen discovery module documentation. +# +# ---------------------------------- Gateway ----------------------------------- +# +# Block initial recovery after a full cluster restart until N nodes are started: +# +#gateway.recover_after_nodes: 3 +# +# For more information, consult the gateway module documentation. +# +# ---------------------------------- Various ----------------------------------- +# +# Require explicit names when deleting indices: +# +#action.destructive_requires_name: true + +{{ elasticsearch_extra_options }} diff --git a/provisioning/roles/geerlingguy.elasticsearch/templates/heap.options.j2 b/provisioning/roles/geerlingguy.elasticsearch/templates/heap.options.j2 new file mode 100644 index 000000000..5760fd1d2 --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/templates/heap.options.j2 @@ -0,0 +1,23 @@ +## JVM configuration + +################################################################ +## IMPORTANT: JVM heap size +################################################################ +## +## You should always set the min and max JVM heap +## size to the same value. For example, to set +## the heap to 4 GB, set: +## +## -Xms4g +## -Xmx4g +## +## See https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html +## for more information +## +################################################################ + +# Xms represents the initial size of total heap space +# Xmx represents the maximum size of total heap space + +-Xms{{ elasticsearch_heap_size_min }} +-Xmx{{ elasticsearch_heap_size_max }} diff --git a/provisioning/roles/geerlingguy.elasticsearch/templates/jvm.options.j2 b/provisioning/roles/geerlingguy.elasticsearch/templates/jvm.options.j2 new file mode 100644 index 000000000..d45ea640d --- /dev/null +++ b/provisioning/roles/geerlingguy.elasticsearch/templates/jvm.options.j2 @@ -0,0 +1,128 @@ +## JVM configuration + +################################################################ +## IMPORTANT: JVM heap size +################################################################ +## +## You should always set the min and max JVM heap +## size to the same value. For example, to set +## the heap to 4 GB, set: +## +## -Xms4g +## -Xmx4g +## +## See https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html +## for more information +## +################################################################ + +# Xms represents the initial size of total heap space +# Xmx represents the maximum size of total heap space + +-Xms{{ elasticsearch_heap_size_min }} +-Xmx{{ elasticsearch_heap_size_max }} + +################################################################ +## Expert settings +################################################################ +## +## All settings below this section are considered +## expert settings. Don't tamper with them unless +## you understand what you are doing +## +################################################################ + +## GC configuration +8-13:-XX:+UseConcMarkSweepGC +8-13:-XX:CMSInitiatingOccupancyFraction=75 +8-13:-XX:+UseCMSInitiatingOccupancyOnly + +## G1GC Configuration +# NOTE: G1 GC is only supported on JDK version 10 or later +# to use G1GC, uncomment the next two lines and update the version on the +# following three lines to your version of the JDK +# 10-13:-XX:-UseConcMarkSweepGC +# 10-13:-XX:-UseCMSInitiatingOccupancyOnly +14-:-XX:+UseG1GC +14-:-XX:G1ReservePercent=25 +14-:-XX:InitiatingHeapOccupancyPercent=30 + +## DNS cache policy +# cache ttl in seconds for positive DNS lookups noting that this overrides the +# JDK security property networkaddress.cache.ttl; set to -1 to cache forever +-Des.networkaddress.cache.ttl=60 +# cache ttl in seconds for negative DNS lookups noting that this overrides the +# JDK security property networkaddress.cache.negative ttl; set to -1 to cache +# forever +-Des.networkaddress.cache.negative.ttl=10 + +## optimizations + +# pre-touch memory pages used by the JVM during initialization +-XX:+AlwaysPreTouch + +## basic + +# explicitly set the stack size +-Xss1m + +# set to headless, just in case +-Djava.awt.headless=true + +# ensure UTF-8 encoding by default (e.g. filenames) +-Dfile.encoding=UTF-8 + +# use our provided JNA always versus the system one +-Djna.nosys=true + +# turn off a JDK optimization that throws away stack traces for common +# exceptions because stack traces are important for debugging +-XX:-OmitStackTraceInFastThrow + +# enable helpful NullPointerExceptions (https://openjdk.java.net/jeps/358), if +# they are supported +14-:-XX:+ShowCodeDetailsInExceptionMessages + +# flags to configure Netty +-Dio.netty.noUnsafe=true +-Dio.netty.noKeySetOptimization=true +-Dio.netty.recycler.maxCapacityPerThread=0 + +# log4j 2 +-Dlog4j.shutdownHookEnabled=false +-Dlog4j2.disable.jmx=true + +-Djava.io.tmpdir=${ES_TMPDIR} + +## heap dumps + +# generate a heap dump when an allocation from the Java heap fails +# heap dumps are created in the working directory of the JVM +-XX:+HeapDumpOnOutOfMemoryError + +# specify an alternative path for heap dumps; ensure the directory exists and +# has sufficient space +-XX:HeapDumpPath=data + +# specify an alternative path for JVM fatal error logs +-XX:ErrorFile=logs/hs_err_pid%p.log + +## JDK 8 GC logging + +8:-XX:+PrintGCDetails +8:-XX:+PrintGCDateStamps +8:-XX:+PrintTenuringDistribution +8:-XX:+PrintGCApplicationStoppedTime +8:-Xloggc:logs/gc.log +8:-XX:+UseGCLogFileRotation +8:-XX:NumberOfGCLogFiles=32 +8:-XX:GCLogFileSize=64m + +# JDK 9+ GC logging +9-:-Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m +# due to internationalization enhancements in JDK 9 Elasticsearch need to set the provider to COMPAT otherwise +# time/date parsing will break in an incompatible way for some date patterns and locals +9-:-Djava.locale.providers=COMPAT + +# temporary workaround for C2 bug with JDK 10 on hardware with AVX-512 +10-:-XX:UseAVX=2 diff --git a/provisioning/roles/geerlingguy.firewall/.github/FUNDING.yml b/provisioning/roles/geerlingguy.firewall/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.firewall/.github/stale.yml b/provisioning/roles/geerlingguy.firewall/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.firewall/.gitignore b/provisioning/roles/geerlingguy.firewall/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.firewall/.travis.yml b/provisioning/roles/geerlingguy.firewall/.travis.yml new file mode 100644 index 000000000..0d9b903ac --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/.travis.yml @@ -0,0 +1,30 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: firewall + matrix: + - MOLECULE_DISTRO: centos7 + - MOLECULE_DISTRO: centos6 + - MOLECULE_DISTRO: ubuntu1804 + - MOLECULE_DISTRO: ubuntu1604 + - MOLECULE_DISTRO: debian9 + +install: + # Install test dependencies. + - pip install molecule yamllint ansible-lint docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.firewall/.yamllint b/provisioning/roles/geerlingguy.firewall/.yamllint new file mode 100644 index 000000000..a3dbc38ee --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/.yamllint @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 120 + level: warning diff --git a/provisioning/roles/geerlingguy.firewall/LICENSE b/provisioning/roles/geerlingguy.firewall/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.firewall/README.md b/provisioning/roles/geerlingguy.firewall/README.md new file mode 100644 index 000000000..ac7dbdc14 --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/README.md @@ -0,0 +1,101 @@ +# Ansible Role: Firewall (iptables) + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-firewall.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-firewall) + +Installs an iptables-based firewall for Linux. Supports both IPv4 (`iptables`) and IPv6 (`ip6tables`). + +This firewall aims for simplicity over complexity, and only opens a few specific ports for incoming traffic (configurable through Ansible variables). If you have a rudimentary knowledge of `iptables` and/or firewalls in general, this role should be a good starting point for a secure system firewall. + +After the role is run, a `firewall` init service will be available on the server. You can use `service firewall [start|stop|restart|status]` to control the firewall. + +## Requirements + +None. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + firewall_state: started + firewall_enabled_at_boot: true + +Controls the state of the firewall service; whether it should be running (`firewall_state`) and/or enabled on system boot (`firewall_enabled_at_boot`). + + firewall_flush_rules_and_chains: true + +Whether to flush all rules and chains whenever the firewall is restarted. Set this to `false` if there are other processes managing iptables (e.g. Docker). + + firewall_allowed_tcp_ports: + - "22" + - "80" + ... + firewall_allowed_udp_ports: [] + +A list of TCP or UDP ports (respectively) to open to incoming traffic. + + firewall_forwarded_tcp_ports: + - { src: "22", dest: "2222" } + - { src: "80", dest: "8080" } + firewall_forwarded_udp_ports: [] + +Forward `src` port to `dest` port, either TCP or UDP (respectively). + + firewall_additional_rules: [] + firewall_ip6_additional_rules: [] + +Any additional (custom) rules to be added to the firewall (in the same format you would add them via command line, e.g. `iptables [rule]`/`ip6tables [rule]`). A few examples of how this could be used: + + # Allow only the IP 167.89.89.18 to access port 4949 (Munin). + firewall_additional_rules: + - "iptables -A INPUT -p tcp --dport 4949 -s 167.89.89.18 -j ACCEPT" + + # Allow only the IP 214.192.48.21 to access port 3306 (MySQL). + firewall_additional_rules: + - "iptables -A INPUT -p tcp --dport 3306 -s 214.192.48.21 -j ACCEPT" + +See [Iptables Essentials: Common Firewall Rules and Commands](https://www.digitalocean.com/community/tutorials/iptables-essentials-common-firewall-rules-and-commands) for more examples. + + firewall_log_dropped_packets: true + +Whether to log dropped packets to syslog (messages will be prefixed with "Dropped by firewall: "). + + firewall_disable_firewalld: false + firewall_disable_ufw: false + +Set to `true` to disable firewalld (installed by default on RHEL/CentOS) or ufw (installed by default on Ubuntu), respectively. + + firewall_enable_ipv6: true + +Set to `false` to disable configuration of ip6tables (for example, if your `GRUB_CMDLINE_LINUX` contains `ipv6.disable=1`). + +## Dependencies + +None. + +## Example Playbook + + - hosts: server + vars_files: + - vars/main.yml + roles: + - { role: geerlingguy.firewall } + +*Inside `vars/main.yml`*: + + firewall_allowed_tcp_ports: + - "22" + - "25" + - "80" + +## TODO + + - Make outgoing ports more configurable. + - Make other firewall features (like logging) configurable. + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.firewall/defaults/main.yml b/provisioning/roles/geerlingguy.firewall/defaults/main.yml new file mode 100644 index 000000000..d23986ebd --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/defaults/main.yml @@ -0,0 +1,22 @@ +--- +firewall_state: started +firewall_enabled_at_boot: true + +firewall_flush_rules_and_chains: true + +firewall_allowed_tcp_ports: + - "22" + - "25" + - "80" + - "443" +firewall_allowed_udp_ports: [] +firewall_forwarded_tcp_ports: [] +firewall_forwarded_udp_ports: [] +firewall_additional_rules: [] +firewall_enable_ipv6: true +firewall_ip6_additional_rules: [] +firewall_log_dropped_packets: true + +# Set to true to ensure other firewall management software is disabled. +firewall_disable_firewalld: false +firewall_disable_ufw: false diff --git a/provisioning/roles/geerlingguy.firewall/handlers/main.yml b/provisioning/roles/geerlingguy.firewall/handlers/main.yml new file mode 100644 index 000000000..378095524 --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: restart firewall + service: name=firewall state=restarted diff --git a/provisioning/roles/geerlingguy.firewall/meta/main.yml b/provisioning/roles/geerlingguy.firewall/meta/main.yml new file mode 100644 index 000000000..2587263d9 --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/meta/main.yml @@ -0,0 +1,26 @@ +--- +dependencies: [] + +galaxy_info: + author: geerlingguy + description: Simple iptables firewall for most Unix-like systems. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + galaxy_tags: + - networking + - system + - security + - firewall + - iptables + - tcp diff --git a/provisioning/roles/geerlingguy.firewall/molecule/default/converge.yml b/provisioning/roles/geerlingguy.firewall/molecule/default/converge.yml new file mode 100644 index 000000000..0c37558ff --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/molecule/default/converge.yml @@ -0,0 +1,21 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + # Added to prevent test failures in CI. + firewall_enable_ipv6: false + + # Added for a test. + firewall_allowed_tcp_ports: + - "9123" + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=1200 + when: ansible_os_family == 'Debian' + changed_when: false + + roles: + - role: geerlingguy.firewall diff --git a/provisioning/roles/geerlingguy.firewall/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.firewall/molecule/default/molecule.yml new file mode 100644 index 000000000..47c232d37 --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/molecule/default/molecule.yml @@ -0,0 +1,35 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: | + set -e + yamllint . + ansible-lint +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} +scenario: + test_sequence: + - lint + - destroy + - dependency + - syntax + - create + - prepare + - converge + - idempotence + - check + - side_effect + - verify + - destroy diff --git a/provisioning/roles/geerlingguy.firewall/tasks/disable-other-firewalls.yml b/provisioning/roles/geerlingguy.firewall/tasks/disable-other-firewalls.yml new file mode 100644 index 000000000..509196a30 --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/tasks/disable-other-firewalls.yml @@ -0,0 +1,66 @@ +--- +- name: Check if firewalld package is installed (on RHEL). + command: yum list installed firewalld + args: + warn: false + register: firewalld_installed + ignore_errors: true + changed_when: false + when: + - ansible_os_family == "RedHat" + - firewall_disable_firewalld + check_mode: false + +- name: Disable the firewalld service (on RHEL, if configured). + service: + name: firewalld + state: stopped + enabled: false + when: + - ansible_os_family == "RedHat" + - firewall_disable_firewalld + - firewalld_installed.rc == 0 + +- name: Check if ufw package is installed (on Ubuntu). + command: service ufw status + args: + warn: false + register: ufw_installed + ignore_errors: true + changed_when: false + when: + - ansible_distribution == "Ubuntu" + - firewall_disable_ufw + check_mode: false + +- name: Disable the ufw firewall (on Ubuntu, if configured). + service: + name: ufw + state: stopped + enabled: false + when: + - ansible_distribution == "Ubuntu" + - firewall_disable_ufw + - ufw_installed.rc == 0 + +- name: Check if ufw package is installed (on Archlinux). + command: pacman -Q ufw + args: + warn: false + register: ufw_installed + ignore_errors: true + changed_when: false + when: + - ansible_distribution == "Archlinux" + - firewall_disable_ufw + check_mode: false + +- name: Disable the ufw firewall (on Archlinux, if configured). + service: + name: ufw + state: stopped + enabled: false + when: + - ansible_distribution == "Archlinux" + - firewall_disable_ufw + - ufw_installed.rc == 0 diff --git a/provisioning/roles/geerlingguy.firewall/tasks/main.yml b/provisioning/roles/geerlingguy.firewall/tasks/main.yml new file mode 100644 index 000000000..df1a631d1 --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/tasks/main.yml @@ -0,0 +1,44 @@ +--- +- name: Ensure iptables is present. + package: name=iptables state=present + +- name: Flush iptables the first time playbook runs. + command: > + iptables -F + creates=/etc/firewall.bash + +- name: Copy firewall script into place. + template: + src: firewall.bash.j2 + dest: /etc/firewall.bash + owner: root + group: root + mode: 0744 + notify: restart firewall + +- name: Copy firewall init script into place. + template: + src: firewall.init.j2 + dest: /etc/init.d/firewall + owner: root + group: root + mode: 0755 + when: "ansible_service_mgr != 'systemd'" + +- name: Copy firewall systemd unit file into place (for systemd systems). + template: + src: firewall.unit.j2 + dest: /etc/systemd/system/firewall.service + owner: root + group: root + mode: 0644 + when: "ansible_service_mgr == 'systemd'" + +- name: Configure the firewall service. + service: + name: firewall + state: "{{ firewall_state }}" + enabled: "{{ firewall_enabled_at_boot }}" + +- import_tasks: disable-other-firewalls.yml + when: firewall_disable_firewalld or firewall_disable_ufw diff --git a/provisioning/roles/geerlingguy.firewall/templates/firewall.bash.j2 b/provisioning/roles/geerlingguy.firewall/templates/firewall.bash.j2 new file mode 100755 index 000000000..ac32abc53 --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/templates/firewall.bash.j2 @@ -0,0 +1,138 @@ +#!/bin/bash +# iptables firewall. +# +# This file should be located at /etc/firewall.bash, and is meant to work with +# the `geerlingguy.firewall` Ansible role. +# +# Common port reference: +# 22: SSH +# 25: SMTP +# 80: HTTP +# 123: NTP +# 443: HTTPS +# 2222: SSH alternate +# 8080: HTTP alternate +# +# @author Jeff Geerling + +# No spoofing. +if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ] +then +for filter in /proc/sys/net/ipv4/conf/*/rp_filter +do +echo 1 > $filter +done +fi + +# Set the default rules. +iptables -P INPUT ACCEPT +iptables -P FORWARD ACCEPT +iptables -P OUTPUT ACCEPT + +{% if firewall_flush_rules_and_chains %} +# Remove all rules and chains. +iptables -t nat -F +iptables -t mangle -F +iptables -F +iptables -X +{% endif %} + +# Accept traffic from loopback interface (localhost). +iptables -A INPUT -i lo -j ACCEPT + +# Forwarded ports. +{# Add a rule for each forwarded port #} +{% for forwarded_port in firewall_forwarded_tcp_ports %} +iptables -t nat -I PREROUTING -p tcp --dport {{ forwarded_port.src }} -j REDIRECT --to-port {{ forwarded_port.dest }} +iptables -t nat -I OUTPUT -p tcp -o lo --dport {{ forwarded_port.src }} -j REDIRECT --to-port {{ forwarded_port.dest }} +{% endfor %} +{% for forwarded_port in firewall_forwarded_udp_ports %} +iptables -t nat -I PREROUTING -p udp --dport {{ forwarded_port.src }} -j REDIRECT --to-port {{ forwarded_port.dest }} +iptables -t nat -I OUTPUT -p udp -o lo --dport {{ forwarded_port.src }} -j REDIRECT --to-port {{ forwarded_port.dest }} +{% endfor %} + +# Open ports. +{# Add a rule for each open port #} +{% for port in firewall_allowed_tcp_ports %} +iptables -A INPUT -p tcp -m tcp --dport {{ port }} -j ACCEPT +{% endfor %} +{% for port in firewall_allowed_udp_ports %} +iptables -A INPUT -p udp -m udp --dport {{ port }} -j ACCEPT +{% endfor %} + +# Accept icmp ping requests. +iptables -A INPUT -p icmp -j ACCEPT + +# Allow NTP traffic for time synchronization. +iptables -A OUTPUT -p udp --dport 123 -j ACCEPT +iptables -A INPUT -p udp --sport 123 -j ACCEPT + +# Additional custom rules. +{% for rule in firewall_additional_rules %} +{{ rule }} +{% endfor %} + +# Allow established connections: +iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT + +# Log EVERYTHING (ONLY for Debug). +# iptables -A INPUT -j LOG + +{% if firewall_log_dropped_packets %} +# Log other incoming requests (all of which are dropped) at 15/minute max. +iptables -A INPUT -m limit --limit 15/minute -j LOG --log-level 7 --log-prefix "Dropped by firewall: " +{% endif %} + +# Drop all other traffic. +iptables -A INPUT -j DROP + +{% if firewall_enable_ipv6 %} +# Configure IPv6 if ip6tables is present. +if [ -x "$(which ip6tables 2>/dev/null)" ]; then + +{% if firewall_flush_rules_and_chains %} + # Remove all rules and chains. + ip6tables -F + ip6tables -X +{% endif %} + + # Accept traffic from loopback interface (localhost). + ip6tables -A INPUT -i lo -j ACCEPT + + # Open ports. +{# Add a rule for each open port #} +{% for port in firewall_allowed_tcp_ports %} + ip6tables -A INPUT -p tcp -m tcp --dport {{ port }} -j ACCEPT +{% endfor %} +{% for port in firewall_allowed_udp_ports %} + ip6tables -A INPUT -p udp -m udp --dport {{ port }} -j ACCEPT +{% endfor %} + + # Accept icmp ping requests. + ip6tables -A INPUT -p icmpv6 -j ACCEPT + + # Allow NTP traffic for time synchronization. + ip6tables -A OUTPUT -p udp --dport 123 -j ACCEPT + ip6tables -A INPUT -p udp --sport 123 -j ACCEPT + + # Additional custom rules. +{% for rule in firewall_ip6_additional_rules %} + {{ rule }} +{% endfor %} + + # Allow established connections: + ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT + + # Log EVERYTHING (ONLY for Debug). + # ip6tables -A INPUT -j LOG + +{% if firewall_log_dropped_packets %} + # Log other incoming requests (all of which are dropped) at 15/minute max. + ip6tables -A INPUT -m limit --limit 15/minute -j LOG --log-level 7 --log-prefix "Dropped by firewall: " +{% endif %} + + # Drop all other traffic. + ip6tables -A INPUT -j DROP + +fi +{% endif %} diff --git a/provisioning/roles/geerlingguy.firewall/templates/firewall.init.j2 b/provisioning/roles/geerlingguy.firewall/templates/firewall.init.j2 new file mode 100644 index 000000000..1235e94c8 --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/templates/firewall.init.j2 @@ -0,0 +1,52 @@ +#! /bin/sh +# /etc/init.d/firewall +# +# Firewall init script, to be used with /etc/firewall.bash by Jeff Geerling. +# +# @author Jeff Geerling + +### BEGIN INIT INFO +# Provides: firewall +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start firewall at boot time. +# Description: Enable the firewall. +### END INIT INFO + +# Carry out specific functions when asked to by the system +case "$1" in + start) + echo "Starting firewall." + /etc/firewall.bash + ;; + stop) + echo "Stopping firewall." + iptables -F + if [ -x "$(which ip6tables 2>/dev/null)" ]; then + ip6tables -F + fi + ;; + restart) + echo "Restarting firewall." + /etc/firewall.bash + ;; + status) + echo -e "`iptables -L -n`" + EXIT=4 # program or service status is unknown + NUMBER_OF_RULES=$(iptables-save | grep '^\-' | wc -l) + if [ 0 -eq $NUMBER_OF_RULES ]; then + EXIT=3 # program is not running + else + EXIT=0 # program is running or service is OK + fi + exit $EXIT + ;; + *) + echo "Usage: /etc/init.d/firewall {start|stop|status|restart}" + exit 1 + ;; +esac + +exit 0 diff --git a/provisioning/roles/geerlingguy.firewall/templates/firewall.unit.j2 b/provisioning/roles/geerlingguy.firewall/templates/firewall.unit.j2 new file mode 100644 index 000000000..5165d88ff --- /dev/null +++ b/provisioning/roles/geerlingguy.firewall/templates/firewall.unit.j2 @@ -0,0 +1,12 @@ +[Unit] +Description=Firewall +After=syslog.target network.target + +[Service] +Type=oneshot +ExecStart=/etc/firewall.bash +ExecStop=/sbin/iptables -F +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/provisioning/roles/geerlingguy.git/.ansible-lint b/provisioning/roles/geerlingguy.git/.ansible-lint new file mode 100644 index 000000000..1ae5e6ccf --- /dev/null +++ b/provisioning/roles/geerlingguy.git/.ansible-lint @@ -0,0 +1,2 @@ +skip_list: + - '204' diff --git a/provisioning/roles/geerlingguy.git/.github/FUNDING.yml b/provisioning/roles/geerlingguy.git/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.git/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.git/.github/stale.yml b/provisioning/roles/geerlingguy.git/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.git/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.git/.gitignore b/provisioning/roles/geerlingguy.git/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.git/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.git/.travis.yml b/provisioning/roles/geerlingguy.git/.travis.yml new file mode 100644 index 000000000..23e723a5d --- /dev/null +++ b/provisioning/roles/geerlingguy.git/.travis.yml @@ -0,0 +1,34 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: git + matrix: + - MOLECULE_DISTRO: centos7 + MOLECULE_PLAYBOOK: playbook-source.yml + - MOLECULE_DISTRO: ubuntu1804 + MOLECULE_PLAYBOOK: playbook-source.yml + - MOLECULE_DISTRO: centos7 + - MOLECULE_DISTRO: centos6 + - MOLECULE_DISTRO: ubuntu1804 + - MOLECULE_DISTRO: ubuntu1604 + - MOLECULE_DISTRO: debian9 + +install: + # Install test dependencies. + - pip install molecule yamllint ansible-lint docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.git/.yamllint b/provisioning/roles/geerlingguy.git/.yamllint new file mode 100644 index 000000000..db22c42ea --- /dev/null +++ b/provisioning/roles/geerlingguy.git/.yamllint @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 160 + level: warning diff --git a/provisioning/roles/geerlingguy.git/LICENSE b/provisioning/roles/geerlingguy.git/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.git/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.git/README.md b/provisioning/roles/geerlingguy.git/README.md new file mode 100644 index 000000000..e64a2dee3 --- /dev/null +++ b/provisioning/roles/geerlingguy.git/README.md @@ -0,0 +1,54 @@ +# Ansible Role: Git + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-git.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-git) + +Installs Git, a distributed version control system, on any RHEL/CentOS or Debian/Ubuntu Linux system. + +## Requirements + +None. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + workspace: /root + +Where certain files will be downloaded and adjusted prior to git installation, if needed. + + git_enablerepo: "" + +This variable, a well as `git_packages`, will be used to install git via a particular `yum` repo if `git_install_from_source` is false (CentOS only). Any additional repositories you have installed that you would like to use for a newer/different Git version. + + git_packages: + - git + +The specific Git packages that will be installed. By default, only `git` is installed, but you could add additional git-related packages like `git-svn` if desired. + + git_install_from_source: false + git_install_path: "/usr" + git_version: "2.26.0" + +Whether to install Git from source; if set to `true`, `git_version` is required and will be used to install a particular version of git (see all available versions here: https://www.kernel.org/pub/software/scm/git/), and `git_install_path` defines where git should be installed. + + git_install_from_source_force_update: false + +If git is already installed at and older version, force a new source build. Only applies if `git_install_from_source` is `true`. + +## Dependencies + +None. + +## Example Playbook + + - hosts: servers + roles: + - { role: geerlingguy.git } + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.git/defaults/main.yml b/provisioning/roles/geerlingguy.git/defaults/main.yml new file mode 100644 index 000000000..53d320cc2 --- /dev/null +++ b/provisioning/roles/geerlingguy.git/defaults/main.yml @@ -0,0 +1,22 @@ +--- +workspace: /root + +# If git_install_from_source is set to false, these two variables define whether +# to use an additional repo for the package installation, and which git packages +# will be installed. +git_enablerepo: "" +git_packages: + - git + +# If set to TRUE, git will be installed from source, using the version set with +# the 'git_version' variable instead of using a package. +git_install_from_source: false +git_install_path: "/usr" +git_version: "2.26.0" + +# If git is already installed at and older version, force a new source build. +# Only applies if git_install_from_source is `true`. +git_install_from_source_force_update: false + +# Leave this at it's default. +git_reinstall_from_source: false diff --git a/provisioning/roles/geerlingguy.git/meta/main.yml b/provisioning/roles/geerlingguy.git/meta/main.yml new file mode 100644 index 000000000..e06b1c528 --- /dev/null +++ b/provisioning/roles/geerlingguy.git/meta/main.yml @@ -0,0 +1,29 @@ +--- +dependencies: [] + +galaxy_info: + author: geerlingguy + description: Git version control software + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.5 + platforms: + - name: EL + versions: + - all + - name: Fedora + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + galaxy_tags: + - development + - system + - git + - vcs + - source + - code diff --git a/provisioning/roles/geerlingguy.git/molecule/default/converge.yml b/provisioning/roles/geerlingguy.git/molecule/default/converge.yml new file mode 100644 index 000000000..2b5787499 --- /dev/null +++ b/provisioning/roles/geerlingguy.git/molecule/default/converge.yml @@ -0,0 +1,17 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + git_install_from_source: false + git_install_path: /usr/local + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + roles: + - role: geerlingguy.git diff --git a/provisioning/roles/geerlingguy.git/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.git/molecule/default/molecule.yml new file mode 100644 index 000000000..2da47dd1f --- /dev/null +++ b/provisioning/roles/geerlingguy.git/molecule/default/molecule.yml @@ -0,0 +1,21 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: | + set -e + yamllint . + ansible-lint +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.git/molecule/default/playbook-source.yml b/provisioning/roles/geerlingguy.git/molecule/default/playbook-source.yml new file mode 100644 index 000000000..02d2d5e8a --- /dev/null +++ b/provisioning/roles/geerlingguy.git/molecule/default/playbook-source.yml @@ -0,0 +1,18 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + git_install_from_source: true + git_install_from_source_force_update: true + git_version: "2.26.0" + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + roles: + - role: geerlingguy.git diff --git a/provisioning/roles/geerlingguy.git/tasks/install-from-source.yml b/provisioning/roles/geerlingguy.git/tasks/install-from-source.yml new file mode 100644 index 000000000..0d420f450 --- /dev/null +++ b/provisioning/roles/geerlingguy.git/tasks/install-from-source.yml @@ -0,0 +1,64 @@ +--- +- name: Include OS-specific variables (RedHat). + include_vars: "{{ ansible_os_family }}.yml" + when: + - ansible_os_family == "RedHat" + - ansible_distribution != "Fedora" + +- name: Include OS-specific variables (Fedora). + include_vars: "{{ ansible_distribution }}.yml" + when: ansible_distribution == "Fedora" + +- name: Include OS-specific variables (Debian). + include_vars: "{{ ansible_os_family }}.yml" + when: ansible_os_family == "Debian" + +- name: Define git_install_from_source_dependencies. + set_fact: + git_install_from_source_dependencies: "{{ __git_install_from_source_dependencies | list }}" + when: git_install_from_source_dependencies is not defined + +- name: Ensure git's dependencies are installed. + package: + name: "{{ git_install_from_source_dependencies }}" + state: present + +- name: Get installed version. + command: > + git --version + warn=no + changed_when: false + failed_when: false + check_mode: false + register: git_installed_version + +- name: Force git install if the version numbers do not match. + set_fact: + git_reinstall_from_source: true + when: + - git_install_from_source_force_update | bool + - (git_installed_version.rc == 0) and (git_installed_version.stdout | regex_replace("^.*?([0-9\.]+)$", "\\1") is version(git_version, operator="!=")) + +- name: Download git. + get_url: + url: "https://www.kernel.org/pub/software/scm/git/git-{{ git_version }}.tar.gz" + dest: "{{ workspace }}/git-{{ git_version }}.tar.gz" + when: (git_installed_version.rc != 0) or (git_reinstall_from_source | bool) + +- name: Expand git archive. + unarchive: + src: "{{ workspace }}/git-{{ git_version }}.tar.gz" + dest: "{{ workspace }}" + creates: "{{ workspace }}/git-{{ git_version }}/README" + copy: false + when: (git_installed_version.rc != 0) or (git_reinstall_from_source | bool) + +- name: Build git. + command: > + make prefix={{ git_install_path }} {{ item }} + chdir={{ workspace }}/git-{{ git_version }} + with_items: + - all + - install + when: (git_installed_version.rc != 0) or (git_reinstall_from_source | bool) + become: true diff --git a/provisioning/roles/geerlingguy.git/tasks/main.yml b/provisioning/roles/geerlingguy.git/tasks/main.yml new file mode 100644 index 000000000..d7cc5811b --- /dev/null +++ b/provisioning/roles/geerlingguy.git/tasks/main.yml @@ -0,0 +1,24 @@ +--- +- name: Ensure git is installed (RedHat). + package: + name: "{{ git_packages }}" + state: present + enablerepo: "{{ git_enablerepo | default(omit, true) }}" + when: + - not git_install_from_source | bool + - ansible_os_family == 'RedHat' + +- name: Update apt cache (Debian). + apt: update_cache=true cache_valid_time=86400 + when: ansible_os_family == 'Debian' + +- name: Ensure git is installed (Debian). + apt: + name: "{{ git_packages }}" + state: present + when: + - not git_install_from_source | bool + - ansible_os_family == 'Debian' + +- import_tasks: install-from-source.yml + when: git_install_from_source | bool diff --git a/provisioning/roles/geerlingguy.git/vars/Debian.yml b/provisioning/roles/geerlingguy.git/vars/Debian.yml new file mode 100644 index 000000000..230e6740b --- /dev/null +++ b/provisioning/roles/geerlingguy.git/vars/Debian.yml @@ -0,0 +1,9 @@ +--- +git_install_from_source_dependencies: + - libcurl4-gnutls-dev + - libexpat1-dev + - gettext + - libssl-dev + - zlib1g-dev + - build-essential + - gcc diff --git a/provisioning/roles/geerlingguy.git/vars/Fedora.yml b/provisioning/roles/geerlingguy.git/vars/Fedora.yml new file mode 100644 index 000000000..c0daee15d --- /dev/null +++ b/provisioning/roles/geerlingguy.git/vars/Fedora.yml @@ -0,0 +1,12 @@ +--- +git_install_from_source_dependencies: + - gettext-devel + - expat-devel + - curl-devel + - zlib-devel + - perl-devel + - openssl-devel + - subversion-perl + - make + - gcc + - tar diff --git a/provisioning/roles/geerlingguy.git/vars/RedHat.yml b/provisioning/roles/geerlingguy.git/vars/RedHat.yml new file mode 100644 index 000000000..d54dc5b2b --- /dev/null +++ b/provisioning/roles/geerlingguy.git/vars/RedHat.yml @@ -0,0 +1,11 @@ +--- +git_install_from_source_dependencies: + - gettext-devel + - expat-devel + - curl-devel + - zlib-devel + - perl-devel + - openssl-devel + - subversion-perl + - make + - gcc diff --git a/provisioning/roles/geerlingguy.git/vars/main.yml b/provisioning/roles/geerlingguy.git/vars/main.yml new file mode 100644 index 000000000..10e268ab3 --- /dev/null +++ b/provisioning/roles/geerlingguy.git/vars/main.yml @@ -0,0 +1,2 @@ +--- +# This space intentionally left blank. diff --git a/provisioning/roles/geerlingguy.java/.github/FUNDING.yml b/provisioning/roles/geerlingguy.java/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.java/.github/stale.yml b/provisioning/roles/geerlingguy.java/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.java/.gitignore b/provisioning/roles/geerlingguy.java/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.java/.travis.yml b/provisioning/roles/geerlingguy.java/.travis.yml new file mode 100644 index 000000000..ad0738edd --- /dev/null +++ b/provisioning/roles/geerlingguy.java/.travis.yml @@ -0,0 +1,34 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: java + matrix: + - MOLECULE_DISTRO: centos8 + - MOLECULE_DISTRO: centos7 + - MOLECULE_DISTRO: centos6 + - MOLECULE_DISTRO: fedora31 + - MOLECULE_DISTRO: ubuntu2004 + - MOLECULE_DISTRO: ubuntu1804 + - MOLECULE_DISTRO: ubuntu1604 + - MOLECULE_DISTRO: debian10 + - MOLECULE_DISTRO: debian9 + +install: + # Install test dependencies. + - pip install molecule yamllint ansible-lint docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.java/.yamllint b/provisioning/roles/geerlingguy.java/.yamllint new file mode 100644 index 000000000..a3dbc38ee --- /dev/null +++ b/provisioning/roles/geerlingguy.java/.yamllint @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 120 + level: warning diff --git a/provisioning/roles/geerlingguy.java/LICENSE b/provisioning/roles/geerlingguy.java/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.java/README.md b/provisioning/roles/geerlingguy.java/README.md new file mode 100644 index 000000000..b35fde806 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/README.md @@ -0,0 +1,67 @@ +# Ansible Role: Java + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-java.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-java) + +Installs Java for RedHat/CentOS and Debian/Ubuntu linux servers. + +## Requirements + +None. + +## Role Variables + +Available variables are listed below, along with default values: + + # The defaults provided by this role are specific to each distribution. + java_packages: + - java-1.8.0-openjdk + +Set the version/development kit of Java to install, along with any other necessary Java packages. Some other options include are included in the distribution-specific files in this role's 'defaults' folder. + + java_home: "" + +If set, the role will set the global environment variable `JAVA_HOME` to this value. + +## Dependencies + +None. + +## Example Playbook (using default package) + + - hosts: servers + roles: + - role: geerlingguy.java + become: yes + +## Example Playbook (install OpenJDK 8) + +For RHEL / CentOS: + + - hosts: server + roles: + - role: geerlingguy.java + when: "ansible_os_family == 'RedHat'" + java_packages: + - java-1.8.0-openjdk + +For Ubuntu < 16.04: + + - hosts: server + tasks: + - name: installing repo for Java 8 in Ubuntu + apt_repository: repo='ppa:openjdk-r/ppa' + + - hosts: server + roles: + - role: geerlingguy.java + when: "ansible_os_family == 'Debian'" + java_packages: + - openjdk-8-jdk + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.java/defaults/main.yml b/provisioning/roles/geerlingguy.java/defaults/main.yml new file mode 100644 index 000000000..3f51462e3 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/defaults/main.yml @@ -0,0 +1,6 @@ +--- +# Set java_packages if you would like to use a different version than the +# default for the OS (see defaults per OS in `vars` directory). +# java_packages: [] + +java_home: "" diff --git a/provisioning/roles/geerlingguy.java/meta/main.yml b/provisioning/roles/geerlingguy.java/meta/main.yml new file mode 100644 index 000000000..085bd5741 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/meta/main.yml @@ -0,0 +1,43 @@ +--- +dependencies: [] + +galaxy_info: + role_name: java + author: geerlingguy + description: Java for Linux + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - 6 + - 7 + - 8 + - name: Fedora + versions: + - all + - name: Debian + versions: + - wheezy + - jessie + - stretch + - buster + - name: Ubuntu + versions: + - precise + - trusty + - xenial + - bionic + - focal + - name: FreeBSD + versions: + - 10.2 + galaxy_tags: + - development + - system + - web + - java + - jdk + - openjdk + - oracle diff --git a/provisioning/roles/geerlingguy.java/molecule/default/converge.yml b/provisioning/roles/geerlingguy.java/molecule/default/converge.yml new file mode 100644 index 000000000..c99558da7 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/molecule/default/converge.yml @@ -0,0 +1,13 @@ +--- +- name: Converge + hosts: all + become: true + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + roles: + - role: geerlingguy.java diff --git a/provisioning/roles/geerlingguy.java/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.java/molecule/default/molecule.yml new file mode 100644 index 000000000..2da47dd1f --- /dev/null +++ b/provisioning/roles/geerlingguy.java/molecule/default/molecule.yml @@ -0,0 +1,21 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: | + set -e + yamllint . + ansible-lint +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.java/tasks/main.yml b/provisioning/roles/geerlingguy.java/tasks/main.yml new file mode 100644 index 000000000..b2a6dedfc --- /dev/null +++ b/provisioning/roles/geerlingguy.java/tasks/main.yml @@ -0,0 +1,41 @@ +--- +- name: Include OS-specific variables for Fedora or FreeBSD. + include_vars: "{{ ansible_distribution }}.yml" + when: ansible_distribution == 'FreeBSD' or ansible_distribution == 'Fedora' + +- name: Include version-specific variables for CentOS/RHEL. + include_vars: "RedHat-{{ ansible_distribution_version.split('.')[0] }}.yml" + when: ansible_distribution == 'CentOS' or + ansible_distribution == 'Red Hat Enterprise Linux' or + ansible_distribution == 'RedHat' + +- name: Include version-specific variables for Ubuntu. + include_vars: "{{ ansible_distribution }}-{{ ansible_distribution_version.split('.')[0] }}.yml" + when: ansible_distribution == 'Ubuntu' + +- name: Include version-specific variables for Debian. + include_vars: "{{ ansible_distribution|title }}-{{ ansible_distribution_version.split('.')[0] }}.yml" + when: ansible_os_family == 'Debian' + +- name: Define java_packages. + set_fact: + java_packages: "{{ __java_packages | list }}" + when: java_packages is not defined + +# Setup/install tasks. +- include_tasks: setup-RedHat.yml + when: ansible_os_family == 'RedHat' + +- include_tasks: setup-Debian.yml + when: ansible_os_family == 'Debian' + +- include_tasks: setup-FreeBSD.yml + when: ansible_os_family == 'FreeBSD' + +# Environment setup. +- name: Set JAVA_HOME if configured. + template: + src: java_home.sh.j2 + dest: /etc/profile.d/java_home.sh + mode: 0644 + when: java_home is defined and java_home diff --git a/provisioning/roles/geerlingguy.java/tasks/setup-Debian.yml b/provisioning/roles/geerlingguy.java/tasks/setup-Debian.yml new file mode 100644 index 000000000..ffeb9acb3 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/tasks/setup-Debian.yml @@ -0,0 +1,16 @@ +--- +# See: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=863199 and +# https://github.com/geerlingguy/ansible-role-java/issues/64 +- name: Ensure 'man' directory exists. + file: + path: /usr/share/man/man1 + state: directory + recurse: true + when: + - ansible_distribution == 'Ubuntu' + - ansible_distribution_major_version | int >= 18 + +- name: Ensure Java is installed. + apt: + name: "{{ java_packages }}" + state: present diff --git a/provisioning/roles/geerlingguy.java/tasks/setup-FreeBSD.yml b/provisioning/roles/geerlingguy.java/tasks/setup-FreeBSD.yml new file mode 100644 index 000000000..ba668728f --- /dev/null +++ b/provisioning/roles/geerlingguy.java/tasks/setup-FreeBSD.yml @@ -0,0 +1,11 @@ +--- +- name: Ensure Java is installed. + pkgng: + name: "{{ java_packages }}" + state: present + +- name: ensure proc is mounted + mount: name=/proc fstype=procfs src=proc opts=rw state=mounted + +- name: ensure fdesc is mounted + mount: name=/dev/fd fstype=fdescfs src=fdesc opts=rw state=mounted diff --git a/provisioning/roles/geerlingguy.java/tasks/setup-RedHat.yml b/provisioning/roles/geerlingguy.java/tasks/setup-RedHat.yml new file mode 100644 index 000000000..130694520 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/tasks/setup-RedHat.yml @@ -0,0 +1,5 @@ +--- +- name: Ensure Java is installed. + package: + name: "{{ java_packages }}" + state: present diff --git a/provisioning/roles/geerlingguy.java/templates/java_home.sh.j2 b/provisioning/roles/geerlingguy.java/templates/java_home.sh.j2 new file mode 100644 index 000000000..4859c4aab --- /dev/null +++ b/provisioning/roles/geerlingguy.java/templates/java_home.sh.j2 @@ -0,0 +1 @@ +export JAVA_HOME={{ java_home }} diff --git a/provisioning/roles/geerlingguy.java/vars/Debian-10.yml b/provisioning/roles/geerlingguy.java/vars/Debian-10.yml new file mode 100644 index 000000000..bd058c224 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/vars/Debian-10.yml @@ -0,0 +1,6 @@ +--- +# JDK version options include: +# - java +# - openjdk-11-jdk +__java_packages: + - openjdk-11-jdk diff --git a/provisioning/roles/geerlingguy.java/vars/Debian-8.yml b/provisioning/roles/geerlingguy.java/vars/Debian-8.yml new file mode 100644 index 000000000..8d620e47a --- /dev/null +++ b/provisioning/roles/geerlingguy.java/vars/Debian-8.yml @@ -0,0 +1,7 @@ +--- +# JDK version options include: +# - java +# - openjdk-6-jdk +# - openjdk-7-jdk +__java_packages: + - openjdk-7-jdk diff --git a/provisioning/roles/geerlingguy.java/vars/Debian-9.yml b/provisioning/roles/geerlingguy.java/vars/Debian-9.yml new file mode 100644 index 000000000..17e49bf36 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/vars/Debian-9.yml @@ -0,0 +1,6 @@ +--- +# JDK version options include: +# - java +# - openjdk-8-jdk +__java_packages: + - openjdk-8-jdk diff --git a/provisioning/roles/geerlingguy.java/vars/Fedora.yml b/provisioning/roles/geerlingguy.java/vars/Fedora.yml new file mode 100644 index 000000000..47c5a0184 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/vars/Fedora.yml @@ -0,0 +1,6 @@ +--- +# JDK version options include: +# - java +# - java-1.8.0-openjdk +__java_packages: + - java-1.8.0-openjdk diff --git a/provisioning/roles/geerlingguy.java/vars/FreeBSD.yml b/provisioning/roles/geerlingguy.java/vars/FreeBSD.yml new file mode 100644 index 000000000..0d712eb4d --- /dev/null +++ b/provisioning/roles/geerlingguy.java/vars/FreeBSD.yml @@ -0,0 +1,7 @@ +--- +# JDK version options for FreeBSD include: +# - openjdk +# - openjdk6 +# - openjdk8 +__java_packages: + - openjdk diff --git a/provisioning/roles/geerlingguy.java/vars/RedHat-6.yml b/provisioning/roles/geerlingguy.java/vars/RedHat-6.yml new file mode 100644 index 000000000..70694b7af --- /dev/null +++ b/provisioning/roles/geerlingguy.java/vars/RedHat-6.yml @@ -0,0 +1,7 @@ +--- +# JDK version options include: +# - java +# - java-1.6.0-openjdk +# - java-1.7.0-openjdk +__java_packages: + - java-1.7.0-openjdk diff --git a/provisioning/roles/geerlingguy.java/vars/RedHat-7.yml b/provisioning/roles/geerlingguy.java/vars/RedHat-7.yml new file mode 100644 index 000000000..64db5790f --- /dev/null +++ b/provisioning/roles/geerlingguy.java/vars/RedHat-7.yml @@ -0,0 +1,8 @@ +--- +# JDK version options include: +# - java +# - java-1.6.0-openjdk +# - java-1.7.0-openjdk +# - java-1.8.0-openjdk +__java_packages: + - java-1.8.0-openjdk diff --git a/provisioning/roles/geerlingguy.java/vars/RedHat-8.yml b/provisioning/roles/geerlingguy.java/vars/RedHat-8.yml new file mode 100644 index 000000000..d49b6f4dc --- /dev/null +++ b/provisioning/roles/geerlingguy.java/vars/RedHat-8.yml @@ -0,0 +1,7 @@ +--- +# JDK version options include: +# - java-1.8.0-openjdk +# - java-11-openjdk +# - java-latest-openjdk +__java_packages: + - java-11-openjdk diff --git a/provisioning/roles/geerlingguy.java/vars/Ubuntu-12.yml b/provisioning/roles/geerlingguy.java/vars/Ubuntu-12.yml new file mode 100644 index 000000000..8d620e47a --- /dev/null +++ b/provisioning/roles/geerlingguy.java/vars/Ubuntu-12.yml @@ -0,0 +1,7 @@ +--- +# JDK version options include: +# - java +# - openjdk-6-jdk +# - openjdk-7-jdk +__java_packages: + - openjdk-7-jdk diff --git a/provisioning/roles/geerlingguy.java/vars/Ubuntu-14.yml b/provisioning/roles/geerlingguy.java/vars/Ubuntu-14.yml new file mode 100644 index 000000000..8d620e47a --- /dev/null +++ b/provisioning/roles/geerlingguy.java/vars/Ubuntu-14.yml @@ -0,0 +1,7 @@ +--- +# JDK version options include: +# - java +# - openjdk-6-jdk +# - openjdk-7-jdk +__java_packages: + - openjdk-7-jdk diff --git a/provisioning/roles/geerlingguy.java/vars/Ubuntu-16.yml b/provisioning/roles/geerlingguy.java/vars/Ubuntu-16.yml new file mode 100644 index 000000000..0a0bd8209 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/vars/Ubuntu-16.yml @@ -0,0 +1,7 @@ +--- +# JDK version options include: +# - java +# - openjdk-8-jdk +# - openjdk-9-jdk +__java_packages: + - openjdk-8-jdk diff --git a/provisioning/roles/geerlingguy.java/vars/Ubuntu-18.yml b/provisioning/roles/geerlingguy.java/vars/Ubuntu-18.yml new file mode 100644 index 000000000..bd058c224 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/vars/Ubuntu-18.yml @@ -0,0 +1,6 @@ +--- +# JDK version options include: +# - java +# - openjdk-11-jdk +__java_packages: + - openjdk-11-jdk diff --git a/provisioning/roles/geerlingguy.java/vars/Ubuntu-20.yml b/provisioning/roles/geerlingguy.java/vars/Ubuntu-20.yml new file mode 100644 index 000000000..bd058c224 --- /dev/null +++ b/provisioning/roles/geerlingguy.java/vars/Ubuntu-20.yml @@ -0,0 +1,6 @@ +--- +# JDK version options include: +# - java +# - openjdk-11-jdk +__java_packages: + - openjdk-11-jdk diff --git a/provisioning/roles/geerlingguy.mailhog/.ansible-lint b/provisioning/roles/geerlingguy.mailhog/.ansible-lint new file mode 100644 index 000000000..477856412 --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/.ansible-lint @@ -0,0 +1,2 @@ +skip_list: + - '306' diff --git a/provisioning/roles/geerlingguy.mailhog/.gitignore b/provisioning/roles/geerlingguy.mailhog/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.mailhog/.travis.yml b/provisioning/roles/geerlingguy.mailhog/.travis.yml new file mode 100644 index 000000000..491578b53 --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/.travis.yml @@ -0,0 +1,28 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: mailhog + matrix: + - MOLECULE_DISTRO: centos7 + - MOLECULE_DISTRO: ubuntu1804 + - MOLECULE_DISTRO: debian9 + +install: + # Install test dependencies. + - pip install molecule docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.mailhog/LICENSE b/provisioning/roles/geerlingguy.mailhog/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.mailhog/README.md b/provisioning/roles/geerlingguy.mailhog/README.md new file mode 100644 index 000000000..174e4cdd1 --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/README.md @@ -0,0 +1,63 @@ +# Ansible Role: MailHog + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-mailhog.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-mailhog) + +Installs [MailHog](https://github.com/mailhog/MailHog), a Go-based SMTP server and web UI/API for displaying captured emails, on RedHat or Debian-based linux systems. + +Also installs [mhsendmail](https://github.com/mailhog/mhsendmail) so you can redirect system mail to MailHog's built-in SMTP server. + +If you're using PHP and would like to route all PHP email into MailHog, you will need to update the `sendmail_path` configuration option in php.ini, like so: + + sendmail_path = "{{ mailhog_install_dir }}/mhsendmail" + +(Replace `{{ mailhog_install_dir }}` with the actual MailHog installation directory, which is `/opt/mailhog` by default—e.g. `/opt/mailhog/mhsendmail`). + +## Requirements + +None. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + mailhog_install_dir: /opt/mailhog + +The directory into which the MailHog binary will be installed. + + mailhog_version: 1.0.0 + +The version of MailHog that will be installed. You can find the latest version by visiting the [MailHog project releases page](https://github.com/mailhog/MailHog/releases). + + mailhog_binary_url: "https://github.com/mailhog/MailHog/releases/download/v{{ mailhog_version }}/MailHog_linux_amd64" + +The MailHog binary that will be installed. You can find the latest version or a 32-bit version by visiting the [MailHog project releases page](https://github.com/mailhog/MailHog/releases). + + mailhog_daemonize_bin_path: /usr/sbin/daemonize + +The path to `daemonize`, which is used to launch MailHog via init script. + + mhsendmail_version: 0.2.0 + +The version of the mhsendmail binary that will be installed. You can find the latest version by visiting the [mhsendmail project releases page](https://github.com/mailhog/mhsendmail/releases). + + mhsendmail_binary_url: "https://github.com/mailhog/mhsendmail/releases/download/v{{ mhsendmail_version }}/mhsendmail_linux_amd64" + +The mhsendmail binary that will be installed. You can find the latest version or a 32-bit version by visiting the [mhsendmail project releases page](https://github.com/mailhog/mhsendmail/releases). + +## Dependencies + + - geerlingguy.daemonize + +## Example Playbook + + - hosts: servers + roles: + - { role: geerlingguy.mailhog } + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.mailhog/defaults/main.yml b/provisioning/roles/geerlingguy.mailhog/defaults/main.yml new file mode 100644 index 000000000..780cf2ad6 --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/defaults/main.yml @@ -0,0 +1,9 @@ +--- +mailhog_install_dir: /opt/mailhog +mailhog_version: 1.0.0 +mailhog_binary_url: "https://github.com/mailhog/MailHog/releases/download/v{{ mailhog_version }}/MailHog_linux_amd64" +mhsendmail_version: 0.2.0 +mhsendmail_binary_url: "https://github.com/mailhog/mhsendmail/releases/download/v{{ mhsendmail_version }}/mhsendmail_linux_amd64" + +# Path to daemonize, which is used to launch MailHog via init script. +mailhog_daemonize_bin_path: /usr/sbin/daemonize diff --git a/provisioning/roles/geerlingguy.mailhog/meta/main.yml b/provisioning/roles/geerlingguy.mailhog/meta/main.yml new file mode 100644 index 000000000..9acb172b1 --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/meta/main.yml @@ -0,0 +1,26 @@ +--- +dependencies: + - geerlingguy.daemonize + +galaxy_info: + author: geerlingguy + description: "MailHog for Linux" + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 1.8 + platforms: + - name: EL + versions: + - all + - name: Ubuntu + versions: + - all + - name: Debian + versions: + - all + galaxy_tags: + - development + - web + - system + - mail + - mailhog diff --git a/provisioning/roles/geerlingguy.mailhog/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.mailhog/molecule/default/molecule.yml new file mode 100644 index 000000000..2ca6feaf9 --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/molecule/default/molecule.yml @@ -0,0 +1,29 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-file: molecule/default/yaml-lint.yml +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + lint: + name: ansible-lint + playbooks: + converge: ${MOLECULE_PLAYBOOK:-playbook.yml} +scenario: + name: default +verifier: + name: testinfra + lint: + name: flake8 diff --git a/provisioning/roles/geerlingguy.mailhog/molecule/default/playbook.yml b/provisioning/roles/geerlingguy.mailhog/molecule/default/playbook.yml new file mode 100644 index 000000000..1a3da6b9f --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/molecule/default/playbook.yml @@ -0,0 +1,53 @@ +--- +- name: Converge + hosts: all + become: true + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + - name: Ensure build dependencies are installed (RedHat). + package: + name: + - "@Development tools" + - tar + - unzip + - net-tools + - curl + state: present + when: ansible_os_family == 'RedHat' + + - name: Ensure build dependencies are installed (Debian). + apt: + name: + - build-essential + - tar + - unzip + - net-tools + - curl + state: present + when: ansible_os_family == 'Debian' + + roles: + - geerlingguy.daemonize + - geerlingguy.mailhog + + post_tasks: + - name: Copy test message into place. + copy: + src: test-message + dest: /tmp/test-message + + - name: Send an email via mhsendmail. + shell: cat /tmp/test-message | /opt/mailhog/mhsendmail johndoe@example.com + changed_when: false + + - name: Test retrieiving messages from the MailHog API. + uri: + url: http://localhost:8025/api/v2/messages + register: result + until: result.status == 200 + retries: 60 + delay: 1 diff --git a/provisioning/roles/geerlingguy.mailhog/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.mailhog/molecule/default/requirements.yml new file mode 100644 index 000000000..96fb8e39b --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/molecule/default/requirements.yml @@ -0,0 +1,2 @@ +--- +- src: geerlingguy.daemonize diff --git a/provisioning/roles/geerlingguy.mailhog/molecule/default/test-message b/provisioning/roles/geerlingguy.mailhog/molecule/default/test-message new file mode 100644 index 000000000..582ec1e91 --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/molecule/default/test-message @@ -0,0 +1,5 @@ +From: johndoe@example.com +To: janedoe@example.com +Subject: Test email + +Hello world! \ No newline at end of file diff --git a/provisioning/roles/geerlingguy.mailhog/molecule/default/yaml-lint.yml b/provisioning/roles/geerlingguy.mailhog/molecule/default/yaml-lint.yml new file mode 100644 index 000000000..db22c42ea --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/molecule/default/yaml-lint.yml @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 160 + level: warning diff --git a/provisioning/roles/geerlingguy.mailhog/tasks/main.yml b/provisioning/roles/geerlingguy.mailhog/tasks/main.yml new file mode 100644 index 000000000..d21b8c9c7 --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/tasks/main.yml @@ -0,0 +1,43 @@ +--- +# Install and configure MailHog. +- name: Ensure mailhog install directory exists. + file: + path: "{{ mailhog_install_dir }}" + owner: root + group: root + state: directory + mode: 0755 + +- name: Download MailHog and mhsendmail binaries. + get_url: + url: "{{ item.url }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: 0755 + with_items: + - url: "{{ mailhog_binary_url }}" + dest: "{{ mailhog_install_dir }}/mailhog" + - url: "{{ mhsendmail_binary_url }}" + dest: "{{ mailhog_install_dir }}/mhsendmail" + +- name: Copy mailhog init script into place. + template: + src: mailhog.init.j2 + dest: /etc/init.d/mailhog + owner: root + group: root + mode: 0755 + when: "ansible_service_mgr != 'systemd'" + +- name: Copy mailhog systemd unit file into place (for systemd systems). + template: + src: mailhog.unit.j2 + dest: /etc/systemd/system/mailhog.service + owner: root + group: root + mode: 0755 + when: "ansible_service_mgr == 'systemd'" + +- name: Ensure mailhog is enabled and will start on boot. + service: name=mailhog state=started enabled=yes diff --git a/provisioning/roles/geerlingguy.mailhog/templates/mailhog.init.j2 b/provisioning/roles/geerlingguy.mailhog/templates/mailhog.init.j2 new file mode 100644 index 000000000..c20904c79 --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/templates/mailhog.init.j2 @@ -0,0 +1,61 @@ +#! /bin/sh +# /etc/init.d/mailhog +# +# MailHog init script. +# +# @author Jeff Geerling + +### BEGIN INIT INFO +# Provides: mailhog +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start MailHog at boot time. +# Description: Enable MailHog. +### END INIT INFO + +PID=/var/run/mailhog.pid +LOCK=/var/lock/mailhog.lock +USER=nobody +BIN={{ mailhog_install_dir }}/mailhog +DAEMONIZE_BIN={{ mailhog_daemonize_bin_path }} + +# Carry out specific functions when asked to by the system +case "$1" in + start) + echo "Starting mailhog." + $DAEMONIZE_BIN -p $PID -l $LOCK -u $USER $BIN + ;; + stop) + if [ -f $PID ]; then + echo "Stopping mailhog."; + kill -TERM $(cat $PID); + rm -f $PID; + else + echo "MailHog is not running."; + fi + ;; + restart) + echo "Restarting mailhog." + if [ -f $PID ]; then + kill -TERM $(cat $PID); + rm -f $PID; + fi + $DAEMONIZE_BIN -p $PID -l $LOCK -u $USER $BIN + ;; + status) + if [ -f $PID ]; then + echo "MailHog is running."; + else + echo "MailHog is not running."; + exit 3 + fi + ;; + *) + echo "Usage: /etc/init.d/mailhog {start|stop|status|restart}" + exit 1 + ;; +esac + +exit 0 \ No newline at end of file diff --git a/provisioning/roles/geerlingguy.mailhog/templates/mailhog.unit.j2 b/provisioning/roles/geerlingguy.mailhog/templates/mailhog.unit.j2 new file mode 100644 index 000000000..10f3b1f74 --- /dev/null +++ b/provisioning/roles/geerlingguy.mailhog/templates/mailhog.unit.j2 @@ -0,0 +1,12 @@ +[Unit] +Description=MailHog Email Catcher +After=syslog.target network.target + +[Service] +Type=simple +ExecStart={{ mailhog_install_dir }}/mailhog +StandardOutput=journal +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/provisioning/roles/geerlingguy.memcached/.ansible-lint b/provisioning/roles/geerlingguy.memcached/.ansible-lint new file mode 100644 index 000000000..acc82551f --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/.ansible-lint @@ -0,0 +1,3 @@ +skip_list: + - 'yaml' + - 'role-name' diff --git a/provisioning/roles/geerlingguy.memcached/.github/FUNDING.yml b/provisioning/roles/geerlingguy.memcached/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.memcached/.github/stale.yml b/provisioning/roles/geerlingguy.memcached/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.memcached/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.memcached/.github/workflows/ci.yml new file mode 100644 index 000000000..947307974 --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/.github/workflows/ci.yml @@ -0,0 +1,66 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "30 3 * * 3" + +defaults: + run: + working-directory: 'geerlingguy.memcached' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.memcached' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + distro: + - centos7 + - ubuntu1804 + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.memcached' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} diff --git a/provisioning/roles/geerlingguy.memcached/.github/workflows/release.yml b/provisioning/roles/geerlingguy.memcached/.github/workflows/release.yml new file mode 100644 index 000000000..0dae6077b --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.memcached' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.memcached' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.memcached/.gitignore b/provisioning/roles/geerlingguy.memcached/.gitignore new file mode 100644 index 000000000..8840c8f02 --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/.gitignore @@ -0,0 +1,5 @@ +*.retry +*/__pycache__ +*.pyc +.cache + diff --git a/provisioning/roles/geerlingguy.memcached/.yamllint b/provisioning/roles/geerlingguy.memcached/.yamllint new file mode 100644 index 000000000..76a383c6a --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/.yamllint @@ -0,0 +1,10 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml diff --git a/provisioning/roles/geerlingguy.memcached/LICENSE b/provisioning/roles/geerlingguy.memcached/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.memcached/README.md b/provisioning/roles/geerlingguy.memcached/README.md new file mode 100644 index 000000000..253230e4c --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/README.md @@ -0,0 +1,58 @@ +# Ansible Role: Memcached + +[![CI](https://github.com/geerlingguy/ansible-role-memcached/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-memcached/actions?query=workflow%3ACI) + +An Ansible Role that installs Memcached on RedHat/CentOS or Debian/Ubuntu Linux. + +## Requirements + +None. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + memcached_user: memcache + +The user under which the Memcached daemon will run. + + memcached_port: 11211 + memcached_listen_ip: 127.0.0.1 + +The port and IP address (127.0.0.1 for localhost) on which Memcached will listen for requests. + + memcached_threads: 4 + +Number of threads to run. + + memcached_memory_limit: 64 + memcached_max_item_size: 1m + memcached_connections: 1024 + +Memcached limits. The maximum amount of RAM `memcached` will consume (64MB is the default), the memory-limit of a single item and the maximum number of simultaneous connections memcached will handle. + + memcached_log_file: /var/log/memcached.log + +The location of the memcached log file. + + memcached_log_verbosity: "" + +Normally memcached does not log anything. Change to "-v" to enable logging or to "-vv" for debug logging. + +## Dependencies + +None. + +## Example Playbook + + - hosts: cache + roles: + - { role: geerlingguy.memcached } + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.memcached/defaults/main.yml b/provisioning/roles/geerlingguy.memcached/defaults/main.yml new file mode 100644 index 000000000..bef3ad052 --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/defaults/main.yml @@ -0,0 +1,13 @@ +--- +memcached_port: 11211 +memcached_listen_ip: 127.0.0.1 + +memcached_memory_limit: 64 +memcached_connections: 1024 + +memcached_log_file: /var/log/memcached.log +memcached_log_verbosity: "" + +memcached_max_item_size: 1m + +memcached_threads: 4 diff --git a/provisioning/roles/geerlingguy.memcached/handlers/main.yml b/provisioning/roles/geerlingguy.memcached/handlers/main.yml new file mode 100644 index 000000000..9aaea02cb --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: restart memcached + service: name=memcached state=restarted diff --git a/provisioning/roles/geerlingguy.memcached/meta/main.yml b/provisioning/roles/geerlingguy.memcached/meta/main.yml new file mode 100644 index 000000000..84be97de7 --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/meta/main.yml @@ -0,0 +1,33 @@ +--- +dependencies: [] + +galaxy_info: + role_name: memcached + author: geerlingguy + description: Memcached for Linux + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - 7 + - 8 + - name: Ubuntu + versions: + - precise + - trusty + - xenial + - bionic + - name: Debian + versions: + - all + galaxy_tags: + - web + - database + - memcached + - keyvalue + - kv + - cache + - caching + - performance diff --git a/provisioning/roles/geerlingguy.memcached/molecule/default/converge.yml b/provisioning/roles/geerlingguy.memcached/molecule/default/converge.yml new file mode 100644 index 000000000..09bd3c324 --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/molecule/default/converge.yml @@ -0,0 +1,12 @@ +--- +- name: Converge + hosts: all + become: true + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.memcached diff --git a/provisioning/roles/geerlingguy.memcached/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.memcached/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.memcached/tasks/main.yml b/provisioning/roles/geerlingguy.memcached/tasks/main.yml new file mode 100644 index 000000000..fc7ff4bba --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/tasks/main.yml @@ -0,0 +1,31 @@ +--- +# Include variables and define needed variables. +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define memcached_user. + set_fact: + memcached_user: "{{ __memcached_user }}" + when: memcached_user is not defined + +# Setup/install tasks. +- name: Update apt cache. + apt: update_cache=yes cache_valid_time=86400 + when: ansible_os_family == 'Debian' + +- name: Install Memcached. + package: name=memcached state=present + register: memcached_install + +# Configure Memcached. +- name: Copy Memcached configuration. + template: + src: memcached-{{ ansible_os_family }}.conf.j2 + dest: "{{ memcached_config_file }}" + owner: root + group: root + mode: 0644 + notify: restart memcached + +- name: Ensure Memcached is started and set to run on startup. + service: name=memcached state=started enabled=yes diff --git a/provisioning/roles/geerlingguy.memcached/templates/memcached-Debian.conf.j2 b/provisioning/roles/geerlingguy.memcached/templates/memcached-Debian.conf.j2 new file mode 100644 index 000000000..87e7021f8 --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/templates/memcached-Debian.conf.j2 @@ -0,0 +1,54 @@ +# {{ ansible_managed }} +# memcached default config file +# 2003 - Jay Bonci <jaybonci@debian.org> +# This configuration file is read by the start-memcached script provided as +# part of the Debian GNU/Linux distribution. + +# Run memcached as a daemon. This command is implied, and is not needed for the +# daemon to run. See the README.Debian that comes with this package for more +# information. +-d + +# Threads count +-t {{ memcached_threads }} + +# Log memcached's output to /var/log/memcached +logfile {{ memcached_log_file }} +{{ memcached_log_verbosity }} + +# Start with a cap of 64 megs of memory. It's reasonable, and the daemon default +# Note that the daemon will grow to this size, but does not start out holding this much +# memory +-m {{ memcached_memory_limit }} + +# Default connection port is 11211 +-p {{ memcached_port }} + +# Run the daemon as root. The start-memcached will default to running as root if no +# -u command is present in this config file +-u {{ memcached_user }} + +# Specify which IP address to listen on. The default is to listen on all IP addresses +# This parameter is one of the only security measures that memcached has, so make sure +# it's listening on a firewalled interface. +{% if memcached_listen_ip is string %} +-l {{ memcached_listen_ip }} +{% else %} +{% for ip in memcached_listen_ip %} +-l {{ ip }} +{% endfor %} +{% endif %} + +# Limit the number of simultaneous incoming connections. The daemon default is 1024 +-c {{ memcached_connections }} + +# Lock down all paged memory. Consult with the README and homepage before you do this +# -k + +# Return error when memory is exhausted (rather than removing items) +# -M + +# Maximize core file limit +# -r + +-I {{ memcached_max_item_size }} diff --git a/provisioning/roles/geerlingguy.memcached/templates/memcached-RedHat.conf.j2 b/provisioning/roles/geerlingguy.memcached/templates/memcached-RedHat.conf.j2 new file mode 100644 index 000000000..21efeaada --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/templates/memcached-RedHat.conf.j2 @@ -0,0 +1,20 @@ +# {{ ansible_managed }} +# Default connection port is 11211 +PORT="{{ memcached_port }}" + +# The user to run memcached as. +USER="{{ memcached_user }}" + +# Limit the number of simultaneous incoming connections. The daemon default is 1024. +MAXCONN="{{ memcached_connections }}" + +# Start with a cap of 64 megs of memory. It's reasonable, and the daemon default +# Note that the daemon will grow to this size, but does not start out holding this much +# memory +CACHESIZE="{{ memcached_memory_limit }}" + +# Extra options: +# -l Specify which IP address to listen on. The default is to listen on all IP addresses +# This parameter is one of the only security measures that memcached has, so make sure +# it's listening on a firewalled interface. +OPTIONS="{% if memcached_listen_ip is string %}-l {{ memcached_listen_ip }} {% else %}{% for ip in memcached_listen_ip %}-l {{ ip }} {% endfor %}{% endif %}-t {{ memcached_threads }} -I {{ memcached_max_item_size }} {{ memcached_log_verbosity }} >> {{ memcached_log_file }} 2>&1" diff --git a/provisioning/roles/geerlingguy.memcached/vars/Debian.yml b/provisioning/roles/geerlingguy.memcached/vars/Debian.yml new file mode 100644 index 000000000..6167345d3 --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/vars/Debian.yml @@ -0,0 +1,3 @@ +--- +__memcached_user: memcache +memcached_config_file: /etc/memcached.conf diff --git a/provisioning/roles/geerlingguy.memcached/vars/RedHat.yml b/provisioning/roles/geerlingguy.memcached/vars/RedHat.yml new file mode 100644 index 000000000..520ab013e --- /dev/null +++ b/provisioning/roles/geerlingguy.memcached/vars/RedHat.yml @@ -0,0 +1,3 @@ +--- +__memcached_user: memcached +memcached_config_file: /etc/sysconfig/memcached diff --git a/provisioning/roles/geerlingguy.mysql/.ansible-lint b/provisioning/roles/geerlingguy.mysql/.ansible-lint new file mode 100644 index 000000000..acc82551f --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/.ansible-lint @@ -0,0 +1,3 @@ +skip_list: + - 'yaml' + - 'role-name' diff --git a/provisioning/roles/geerlingguy.mysql/.github/FUNDING.yml b/provisioning/roles/geerlingguy.mysql/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.mysql/.github/stale.yml b/provisioning/roles/geerlingguy.mysql/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.mysql/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.mysql/.github/workflows/ci.yml new file mode 100644 index 000000000..e956354e9 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/.github/workflows/ci.yml @@ -0,0 +1,77 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "0 1 * * 3" + +defaults: + run: + working-directory: 'geerlingguy.mysql' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.mysql' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + distro: + - centos8 + - centos7 + - ubuntu1804 + - debian10 + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.mysql' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + # See: https://github.com/geerlingguy/ansible-role-mysql/issues/422 + - name: Disable AppArmor on Debian. + run: | + set -x + sudo apt-get install apparmor-profiles + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + if: ${{ startsWith(matrix.distro, 'debian') }} + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} diff --git a/provisioning/roles/geerlingguy.mysql/.github/workflows/release.yml b/provisioning/roles/geerlingguy.mysql/.github/workflows/release.yml new file mode 100644 index 000000000..f92b7d8e3 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.mysql' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.mysql' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.mysql/.gitignore b/provisioning/roles/geerlingguy.mysql/.gitignore new file mode 100644 index 000000000..554cc54a2 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/.gitignore @@ -0,0 +1,4 @@ +*.retry +*/__pycache__ +*.pyc +.cache diff --git a/provisioning/roles/geerlingguy.mysql/.yamllint b/provisioning/roles/geerlingguy.mysql/.yamllint new file mode 100644 index 000000000..2a66c05d6 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/.yamllint @@ -0,0 +1,10 @@ +--- +extends: default + +rules: + line-length: + max: 160 + level: warning + +ignore: | + .github/stale.yml diff --git a/provisioning/roles/geerlingguy.mysql/LICENSE b/provisioning/roles/geerlingguy.mysql/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.mysql/README.md b/provisioning/roles/geerlingguy.mysql/README.md new file mode 100644 index 000000000..6a69c3b73 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/README.md @@ -0,0 +1,199 @@ +# Ansible Role: MySQL + +[![CI](https://github.com/geerlingguy/ansible-role-mysql/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-mysql/actions?query=workflow%3ACI) + +Installs and configures MySQL or MariaDB server on RHEL/CentOS or Debian/Ubuntu servers. + +## Requirements + +No special requirements; note that this role requires root access, so either run it in a playbook with a global `become: yes`, or invoke the role in your playbook like: + + - hosts: database + roles: + - role: geerlingguy.mysql + become: yes + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + mysql_user_home: /root + mysql_user_name: root + mysql_user_password: root + +The home directory inside which Python MySQL settings will be stored, which Ansible will use when connecting to MySQL. This should be the home directory of the user which runs this Ansible role. The `mysql_user_name` and `mysql_user_password` can be set if you are running this role under a non-root user account and want to set a non-root user. + + mysql_root_home: /root + mysql_root_username: root + mysql_root_password: root + +The MySQL root user account details. + + mysql_root_password_update: false + +Whether to force update the MySQL root user's password. By default, this role will only change the root user's password when MySQL is first configured. You can force an update by setting this to `yes`. + +> Note: If you get an error like `ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)` after a failed or interrupted playbook run, this usually means the root password wasn't originally updated to begin with. Try either removing the `.my.cnf` file inside the configured `mysql_user_home` or updating it and setting `password=''` (the insecure default password). Run the playbook again, with `mysql_root_password_update` set to `yes`, and the setup should complete. + +> Note: If you get an error like `ERROR 1698 (28000): Access denied for user 'root'@'localhost' (using password: YES)` when trying to log in from the CLI you might need to run as root or sudoer. + + mysql_enabled_on_startup: true + +Whether MySQL should be enabled on startup. + + mysql_config_file: *default value depends on OS* + mysql_config_include_dir: *default value depends on OS* + +The main my.cnf configuration file and include directory. + + overwrite_global_mycnf: true + +Whether the global my.cnf should be overwritten each time this role is run. Setting this to `no` tells Ansible to only create the `my.cnf` file if it doesn't exist. This should be left at its default value (`yes`) if you'd like to use this role's variables to configure MySQL. + + mysql_config_include_files: [] + +A list of files that should override the default global my.cnf. Each item in the array requires a "src" parameter which is a path to a file. An optional "force" parameter can force the file to be updated each time ansible runs. + + mysql_databases: [] + +The MySQL databases to create. A database has the values `name`, `encoding` (defaults to `utf8`), `collation` (defaults to `utf8_general_ci`) and `replicate` (defaults to `1`, only used if replication is configured). The formats of these are the same as in the `mysql_db` module. + +You can also delete a database (or ensure it's not on the server) by setting `state` to `absent` (defaults to `present`). + + mysql_users: [] + +The MySQL users and their privileges. A user has the values: + + - `name` + - `host` (defaults to `localhost`) + - `password` (can be plaintext or encrypted—if encrypted, set `encrypted: yes`) + - `encrypted` (defaults to `no`) + - `priv` (defaults to `*.*:USAGE`) + - `append_privs` (defaults to `no`) + - `state` (defaults to `present`) + +The formats of these are the same as in the `mysql_user` module. + + mysql_packages: + - mysql + - mysql-server + +(OS-specific, RedHat/CentOS defaults listed here) Packages to be installed. In some situations, you may need to add additional packages, like `mysql-devel`. + + mysql_enablerepo: "" + +(RedHat/CentOS only) If you have enabled any additional repositories (might I suggest geerlingguy.repo-epel or geerlingguy.repo-remi), those repositories can be listed under this variable (e.g. `remi,epel`). This can be handy, as an example, if you want to install later versions of MySQL. + + mysql_python_package_debian: python3-mysqldb + +(Ubuntu/Debian only) If you need to explicitly override the MySQL Python package, you can set it here. Set this to `python-mysqldb` if using older distributions running Python 2. + + mysql_port: "3306" + mysql_bind_address: '0.0.0.0' + mysql_datadir: /var/lib/mysql + mysql_socket: *default value depends on OS* + mysql_pid_file: *default value depends on OS* + +Default MySQL connection configuration. + + mysql_log_file_group: mysql *adm on Debian* + mysql_log: "" + mysql_log_error: *default value depends on OS* + mysql_syslog_tag: *default value depends on OS* + +MySQL logging configuration. Setting `mysql_log` (the general query log) or `mysql_log_error` to `syslog` will make MySQL log to syslog using the `mysql_syslog_tag`. + + mysql_slow_query_log_enabled: false + mysql_slow_query_log_file: *default value depends on OS* + mysql_slow_query_time: 2 + +Slow query log settings. Note that the log file will be created by this role, but if you're running on a server with SELinux or AppArmor, you may need to add this path to the allowed paths for MySQL, or disable the mysql profile. For example, on Debian/Ubuntu, you can run `sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/usr.sbin.mysqld && sudo service apparmor restart`. + + mysql_key_buffer_size: "256M" + mysql_max_allowed_packet: "64M" + mysql_table_open_cache: "256" + [...] + +The rest of the settings in `defaults/main.yml` control MySQL's memory usage and some other common settings. The default values are tuned for a server where MySQL can consume ~512 MB RAM, so you should consider adjusting them to suit your particular server better. + + mysql_server_id: "1" + mysql_max_binlog_size: "100M" + mysql_binlog_format: "ROW" + mysql_expire_logs_days: "10" + mysql_replication_role: '' + mysql_replication_master: '' + mysql_replication_user: {} + +Replication settings. Set `mysql_server_id` and `mysql_replication_role` by server (e.g. the master would be ID `1`, with the `mysql_replication_role` of `master`, and the slave would be ID `2`, with the `mysql_replication_role` of `slave`). The `mysql_replication_user` uses the same keys as individual list items in `mysql_users`, and is created on master servers, and used to replicate on all the slaves. + +`mysql_replication_master` needs to resolve to an IP or a hostname which is accessable to the Slaves (this could be a `/etc/hosts` injection or some other means), otherwise the slaves cannot communicate to the master. + +### Later versions of MySQL on CentOS 7 + +If you want to install MySQL from the official repository instead of installing the system default MariaDB equivalents, you can add the following `pre_tasks` task in your playbook: + +```yaml + pre_tasks: + - name: Install the MySQL repo. + yum: + name: http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm + state: present + when: ansible_os_family == "RedHat" + + - name: Override variables for MySQL (RedHat). + set_fact: + mysql_daemon: mysqld + mysql_packages: ['mysql-server'] + mysql_log_error: /var/log/mysqld.err + mysql_syslog_tag: mysqld + mysql_pid_file: /var/run/mysqld/mysqld.pid + mysql_socket: /var/lib/mysql/mysql.sock + when: ansible_os_family == "RedHat" +``` + +### MariaDB usage + +This role works with either MySQL or a compatible version of MariaDB. On RHEL/CentOS 7+, the mariadb database engine was substituted as the default MySQL replacement package. No modifications are necessary though all of the variables still reference 'mysql' instead of mariadb. + +#### Ubuntu 14.04 and 16.04 MariaDB configuration + +On Ubuntu, the package names are named differently, so the `mysql_package` variable needs to be altered. Set the following variables (at a minimum): + + mysql_packages: + - mariadb-client + - mariadb-server + - python-mysqldb + +## Dependencies + +None. + +## Example Playbook + + - hosts: db-servers + become: yes + vars_files: + - vars/main.yml + roles: + - { role: geerlingguy.mysql } + +*Inside `vars/main.yml`*: + + mysql_root_password: super-secure-password + mysql_databases: + - name: example_db + encoding: latin1 + collation: latin1_general_ci + mysql_users: + - name: example_user + host: "%" + password: similarly-secure-password + priv: "example_db.*:ALL" + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.mysql/defaults/main.yml b/provisioning/roles/geerlingguy.mysql/defaults/main.yml new file mode 100644 index 000000000..318b16941 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/defaults/main.yml @@ -0,0 +1,130 @@ +--- +# Set this to the user ansible is logging in as - should have root +# or sudo access +mysql_user_home: /root +mysql_user_name: root +mysql_user_password: root + +# The default root user installed by mysql - almost always root +mysql_root_home: /root +mysql_root_username: root +mysql_root_password: root + +# Set this to `true` to forcibly update the root password. +mysql_root_password_update: false +mysql_user_password_update: false + +mysql_enabled_on_startup: true + +# Whether my.cnf should be updated on every run. +overwrite_global_mycnf: true + +# The following variables have a default value depending on operating system. +# mysql_config_file: /etc/my.cnf +# mysql_config_include_dir: /etc/my.cnf.d + +# Pass in a comma-separated list of repos to use (e.g. "remi,epel"). Used only +# for RedHat systems (and derivatives). +mysql_enablerepo: "" + +# Define a custom list of packages to install; if none provided, the default +# package list from vars/[OS-family].yml will be used. +# mysql_packages: +# - mysql +# - mysql-server +# - MySQL-python + +mysql_python_package_debian: python3-mysqldb + +# MySQL connection settings. +mysql_port: "3306" +mysql_bind_address: '0.0.0.0' +mysql_skip_name_resolve: false +mysql_datadir: /var/lib/mysql +mysql_sql_mode: ~ +# The following variables have a default value depending on operating system. +# mysql_pid_file: /var/run/mysqld/mysqld.pid +# mysql_socket: /var/lib/mysql/mysql.sock + +# Log file settings. +mysql_log_file_group: mysql + +# Slow query log settings. +mysql_slow_query_log_enabled: false +mysql_slow_query_time: "2" +# The following variable has a default value depending on operating system. +# mysql_slow_query_log_file: /var/log/mysql-slow.log + +# Memory settings (default values optimized ~512MB RAM). +mysql_key_buffer_size: "256M" +mysql_max_allowed_packet: "64M" +mysql_table_open_cache: "256" +mysql_sort_buffer_size: "1M" +mysql_read_buffer_size: "1M" +mysql_read_rnd_buffer_size: "4M" +mysql_myisam_sort_buffer_size: "64M" +mysql_thread_cache_size: "8" +mysql_query_cache_type: "0" +mysql_query_cache_size: "16M" +mysql_query_cache_limit: "1M" +mysql_max_connections: "151" +mysql_tmp_table_size: "16M" +mysql_max_heap_table_size: "16M" +mysql_group_concat_max_len: "1024" +mysql_join_buffer_size: "262144" + +# Other settings. +mysql_lower_case_table_names: "0" +mysql_wait_timeout: "28800" +mysql_event_scheduler_state: "OFF" + +# InnoDB settings. +mysql_innodb_file_per_table: "1" +# Set .._buffer_pool_size up to 80% of RAM but beware of setting too high. +mysql_innodb_buffer_pool_size: "256M" +# Set .._log_file_size to 25% of buffer pool size. +mysql_innodb_log_file_size: "64M" +mysql_innodb_log_buffer_size: "8M" +mysql_innodb_flush_log_at_trx_commit: "1" +mysql_innodb_lock_wait_timeout: "50" + +# These settings require MySQL > 5.5. +mysql_innodb_large_prefix: "1" +mysql_innodb_file_format: "barracuda" + +# mysqldump settings. +mysql_mysqldump_max_allowed_packet: "64M" + +# Logging settings. +mysql_log: "" +# The following variables have a default value depending on operating system. +# mysql_log_error: /var/log/mysql/mysql.err +# mysql_syslog_tag: mysql + +mysql_config_include_files: [] +# - src: path/relative/to/playbook/file.cnf +# - { src: path/relative/to/playbook/anotherfile.cnf, force: yes } + +# Databases. +mysql_databases: [] +# - name: example +# collation: utf8_general_ci +# encoding: utf8 +# replicate: 1 + +# Users. +mysql_users: [] +# - name: example +# host: 127.0.0.1 +# password: secret +# priv: *.*:USAGE + +# Replication settings (replication is only enabled if master/user have values). +mysql_server_id: "1" +mysql_max_binlog_size: "100M" +mysql_binlog_format: "ROW" +mysql_expire_logs_days: "10" +mysql_replication_role: '' +mysql_replication_master: '' +# Same keys as `mysql_users` above. +mysql_replication_user: [] diff --git a/provisioning/roles/geerlingguy.mysql/handlers/main.yml b/provisioning/roles/geerlingguy.mysql/handlers/main.yml new file mode 100644 index 000000000..429abe31b --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: restart mysql + service: "name={{ mysql_daemon }} state=restarted sleep=5" diff --git a/provisioning/roles/geerlingguy.mysql/meta/main.yml b/provisioning/roles/geerlingguy.mysql/meta/main.yml new file mode 100644 index 000000000..a1bdc8517 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/meta/main.yml @@ -0,0 +1,30 @@ +--- +dependencies: [] + +galaxy_info: + role_name: mysql + author: geerlingguy + description: MySQL server for RHEL/CentOS and Debian/Ubuntu. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - 7 + - 8 + - name: Ubuntu + versions: + - all + - name: Debian + versions: + - all + - name: Archlinux + versions: + - all + galaxy_tags: + - database + - mysql + - mariadb + - db + - sql diff --git a/provisioning/roles/geerlingguy.mysql/molecule/default/converge.yml b/provisioning/roles/geerlingguy.mysql/molecule/default/converge.yml new file mode 100644 index 000000000..c83b10216 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/molecule/default/converge.yml @@ -0,0 +1,16 @@ +--- +- name: Converge + hosts: all + become: true + + roles: + - role: geerlingguy.mysql + + post_tasks: + - name: Make sure we can connect to MySQL via Unix socket. + command: "mysql -u root -proot -e 'show databases;'" + changed_when: false + + - name: Make sure we can connect to MySQL via TCP. + command: "mysql -u root -proot -h 127.0.0.1 -e 'show databases;'" + changed_when: false diff --git a/provisioning/roles/geerlingguy.mysql/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.mysql/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.mysql/tasks/configure.yml b/provisioning/roles/geerlingguy.mysql/tasks/configure.yml new file mode 100644 index 000000000..b1f004fa1 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/tasks/configure.yml @@ -0,0 +1,87 @@ +--- +- name: Get MySQL version. + command: 'mysql --version' + register: mysql_cli_version + changed_when: false + check_mode: false + +- name: Copy my.cnf global MySQL configuration. + template: + src: my.cnf.j2 + dest: "{{ mysql_config_file }}" + owner: root + group: root + mode: 0644 + force: "{{ overwrite_global_mycnf }}" + notify: restart mysql + +- name: Verify mysql include directory exists. + file: + path: "{{ mysql_config_include_dir }}" + state: directory + owner: root + group: root + mode: 0755 + when: mysql_config_include_files | length + +- name: Copy my.cnf override files into include directory. + template: + src: "{{ item.src }}" + dest: "{{ mysql_config_include_dir }}/{{ item.src | basename }}" + owner: root + group: root + mode: 0644 + force: "{{ item.force | default(False) }}" + with_items: "{{ mysql_config_include_files }}" + notify: restart mysql + +- name: Create slow query log file (if configured). + command: "touch {{ mysql_slow_query_log_file }}" + args: + creates: "{{ mysql_slow_query_log_file }}" + warn: false + when: mysql_slow_query_log_enabled + +- name: Create datadir if it does not exist + file: + path: "{{ mysql_datadir }}" + state: directory + owner: mysql + group: mysql + mode: 0755 + setype: mysqld_db_t + +- name: Set ownership on slow query log file (if configured). + file: + path: "{{ mysql_slow_query_log_file }}" + state: file + owner: mysql + group: "{{ mysql_log_file_group }}" + mode: 0640 + when: mysql_slow_query_log_enabled + +- name: Create error log file (if configured). + command: "touch {{ mysql_log_error }}" + args: + creates: "{{ mysql_log_error }}" + warn: false + when: + - mysql_log | default(true) + - mysql_log_error | default(false) + tags: ['skip_ansible_galaxy'] + +- name: Set ownership on error log file (if configured). + file: + path: "{{ mysql_log_error }}" + state: file + owner: mysql + group: "{{ mysql_log_file_group }}" + mode: 0640 + when: + - mysql_log | default(true) + - mysql_log_error | default(false) + tags: ['skip_ansible_galaxy'] + +- name: Ensure MySQL is started and enabled on boot. + service: "name={{ mysql_daemon }} state=started enabled={{ mysql_enabled_on_startup }}" + register: mysql_service_configuration diff --git a/provisioning/roles/geerlingguy.mysql/tasks/databases.yml b/provisioning/roles/geerlingguy.mysql/tasks/databases.yml new file mode 100644 index 000000000..ca6243257 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/tasks/databases.yml @@ -0,0 +1,8 @@ +--- +- name: Ensure MySQL databases are present. + mysql_db: + name: "{{ item.name }}" + collation: "{{ item.collation | default('utf8_general_ci') }}" + encoding: "{{ item.encoding | default('utf8') }}" + state: "{{ item.state | default('present') }}" + with_items: "{{ mysql_databases }}" diff --git a/provisioning/roles/geerlingguy.mysql/tasks/main.yml b/provisioning/roles/geerlingguy.mysql/tasks/main.yml new file mode 100644 index 000000000..47cefcdc4 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/tasks/main.yml @@ -0,0 +1,26 @@ +--- +# Variable configuration. +- include_tasks: variables.yml + +# Setup/install tasks. +- include_tasks: setup-RedHat.yml + when: ansible_os_family == 'RedHat' + +- include_tasks: setup-Debian.yml + when: ansible_os_family == 'Debian' + +- include_tasks: setup-Archlinux.yml + when: ansible_os_family == 'Archlinux' + +- name: Check if MySQL packages were installed. + set_fact: + mysql_install_packages: "{{ (rh_mysql_install_packages is defined and rh_mysql_install_packages.changed) + or (deb_mysql_install_packages is defined and deb_mysql_install_packages.changed) + or (arch_mysql_install_packages is defined and arch_mysql_install_packages.changed) }}" + +# Configure MySQL. +- include_tasks: configure.yml +- include_tasks: secure-installation.yml +- include_tasks: databases.yml +- include_tasks: users.yml +- include_tasks: replication.yml diff --git a/provisioning/roles/geerlingguy.mysql/tasks/replication.yml b/provisioning/roles/geerlingguy.mysql/tasks/replication.yml new file mode 100644 index 000000000..51103875f --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/tasks/replication.yml @@ -0,0 +1,58 @@ +--- +- name: Ensure replication user exists on master. + mysql_user: + name: "{{ mysql_replication_user.name }}" + host: "{{ mysql_replication_user.host | default('%') }}" + password: "{{ mysql_replication_user.password }}" + priv: "{{ mysql_replication_user.priv | default('*.*:REPLICATION SLAVE,REPLICATION CLIENT') }}" + state: present + when: + - mysql_replication_role == 'master' + - mysql_replication_user.name is defined + - (mysql_replication_master | length) > 0 + tags: ['skip_ansible_galaxy'] + +- name: Check slave replication status. + mysql_replication: + mode: getslave + login_user: "{{ mysql_replication_user.name }}" + login_password: "{{ mysql_replication_user.password }}" + ignore_errors: true + register: slave + when: + - mysql_replication_role == 'slave' + - (mysql_replication_master | length) > 0 + tags: ['skip_ansible_galaxy'] + +- name: Check master replication status. + mysql_replication: mode=getmaster + delegate_to: "{{ mysql_replication_master }}" + register: master + when: + - (slave.Is_Slave is defined and not slave.Is_Slave) or (slave.Is_Slave is not defined and slave is failed) + - mysql_replication_role == 'slave' + - (mysql_replication_master | length) > 0 + tags: ['skip_ansible_galaxy'] + +- name: Configure replication on the slave. + mysql_replication: + mode: changemaster + master_host: "{{ mysql_replication_master }}" + master_user: "{{ mysql_replication_user.name }}" + master_password: "{{ mysql_replication_user.password }}" + master_log_file: "{{ master.File }}" + master_log_pos: "{{ master.Position }}" + ignore_errors: true + when: + - (slave.Is_Slave is defined and not slave.Is_Slave) or (slave.Is_Slave is not defined and slave is failed) + - mysql_replication_role == 'slave' + - mysql_replication_user.name is defined + - (mysql_replication_master | length) > 0 + +- name: Start replication. + mysql_replication: mode=startslave + when: + - (slave.Is_Slave is defined and not slave.Is_Slave) or (slave.Is_Slave is not defined and slave is failed) + - mysql_replication_role == 'slave' + - (mysql_replication_master | length) > 0 + tags: ['skip_ansible_galaxy'] diff --git a/provisioning/roles/geerlingguy.mysql/tasks/secure-installation.yml b/provisioning/roles/geerlingguy.mysql/tasks/secure-installation.yml new file mode 100644 index 000000000..d7a17b8f1 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/tasks/secure-installation.yml @@ -0,0 +1,86 @@ +--- +- name: Ensure default user is present. + mysql_user: + name: "{{ mysql_user_name }}" + host: 'localhost' + password: "{{ mysql_user_password }}" + priv: '*.*:ALL,GRANT' + state: present + when: mysql_user_name != mysql_root_username + +# Has to be after the password assignment, for idempotency. +- name: Copy user-my.cnf file with password credentials. + template: + src: "user-my.cnf.j2" + dest: "{{ mysql_user_home }}/.my.cnf" + owner: "{{ mysql_user_name }}" + mode: 0600 + when: > + mysql_user_name != mysql_root_username + and (mysql_install_packages | bool or mysql_user_password_update) + +- name: Disallow root login remotely + command: 'mysql -NBe "{{ item }}"' + with_items: + - DELETE FROM mysql.user WHERE User='{{ mysql_root_username }}' AND Host NOT IN ('localhost', '127.0.0.1', '::1') + changed_when: false + +- name: Get list of hosts for the root user. + command: mysql -NBe + "SELECT Host + FROM mysql.user + WHERE User = '{{ mysql_root_username }}' + ORDER BY (Host='localhost') ASC" + register: mysql_root_hosts + changed_when: false + check_mode: false + when: mysql_install_packages | bool or mysql_root_password_update + +# Note: We do not use mysql_user for this operation, as it doesn't always update +# the root password correctly. See: https://goo.gl/MSOejW +# Set root password for MySQL >= 5.7.x. +- name: Update MySQL root password for localhost root account (5.7.x). + shell: > + mysql -u root -NBe + 'ALTER USER "{{ mysql_root_username }}"@"{{ item }}" + IDENTIFIED WITH mysql_native_password BY "{{ mysql_root_password }}"; FLUSH PRIVILEGES;' + with_items: "{{ mysql_root_hosts.stdout_lines|default([]) }}" + when: > + ((mysql_install_packages | bool) or mysql_root_password_update) + and ('5.7.' in mysql_cli_version.stdout or '8.0.' in mysql_cli_version.stdout) + +# Set root password for MySQL < 5.7.x. +- name: Update MySQL root password for localhost root account (< 5.7.x). + shell: > + mysql -NBe + 'SET PASSWORD FOR "{{ mysql_root_username }}"@"{{ item }}" = PASSWORD("{{ mysql_root_password }}"); FLUSH PRIVILEGES;' + with_items: "{{ mysql_root_hosts.stdout_lines|default([]) }}" + when: > + ((mysql_install_packages | bool) or mysql_root_password_update) + and ('5.7.' not in mysql_cli_version.stdout and '8.0.' not in mysql_cli_version.stdout) + +# Has to be after the root password assignment, for idempotency. +- name: Copy .my.cnf file with root password credentials. + template: + src: "root-my.cnf.j2" + dest: "{{ mysql_root_home }}/.my.cnf" + owner: root + group: root + mode: 0600 + when: mysql_install_packages | bool or mysql_root_password_update + +- name: Get list of hosts for the anonymous user. + command: mysql -NBe 'SELECT Host FROM mysql.user WHERE User = ""' + register: mysql_anonymous_hosts + changed_when: false + check_mode: false + +- name: Remove anonymous MySQL users. + mysql_user: + name: "" + host: "{{ item }}" + state: absent + with_items: "{{ mysql_anonymous_hosts.stdout_lines|default([]) }}" + +- name: Remove MySQL test database. + mysql_db: "name='test' state=absent" diff --git a/provisioning/roles/geerlingguy.mysql/tasks/setup-Archlinux.yml b/provisioning/roles/geerlingguy.mysql/tasks/setup-Archlinux.yml new file mode 100644 index 000000000..e785290c5 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/tasks/setup-Archlinux.yml @@ -0,0 +1,12 @@ +--- +- name: Ensure MySQL Python libraries are installed. + pacman: "name=mysql-python state=present" + +- name: Ensure MySQL packages are installed. + pacman: "name={{ mysql_packages }} state=present" + register: arch_mysql_install_packages + +- name: Run mysql_install_db if MySQL packages were changed. + command: mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql + when: arch_mysql_install_packages.changed + tags: ['skip_ansible_lint'] diff --git a/provisioning/roles/geerlingguy.mysql/tasks/setup-Debian.yml b/provisioning/roles/geerlingguy.mysql/tasks/setup-Debian.yml new file mode 100644 index 000000000..7145c90ee --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/tasks/setup-Debian.yml @@ -0,0 +1,32 @@ +--- +- name: Check if MySQL is already installed. + stat: path=/etc/init.d/mysql + register: mysql_installed + +- name: Update apt cache if MySQL is not yet installed. + apt: update_cache=yes + when: not mysql_installed.stat.exists + +- name: Ensure MySQL Python libraries are installed. + apt: + name: "{{ mysql_python_package_debian }}" + state: present + +- name: Ensure MySQL packages are installed. + apt: + name: "{{ mysql_packages }}" + state: present + register: deb_mysql_install_packages + +# Because Ubuntu starts MySQL as part of the install process, we need to stop +# mysql and remove the logfiles in case the user set a custom log file size. +- name: Ensure MySQL is stopped after initial install. + service: "name={{ mysql_daemon }} state=stopped" + when: not mysql_installed.stat.exists + +- name: Delete innodb log files created by apt package after initial install. + file: path={{ mysql_datadir }}/{{ item }} state=absent + with_items: + - ib_logfile0 + - ib_logfile1 + when: not mysql_installed.stat.exists diff --git a/provisioning/roles/geerlingguy.mysql/tasks/setup-RedHat.yml b/provisioning/roles/geerlingguy.mysql/tasks/setup-RedHat.yml new file mode 100644 index 000000000..6835c0d6a --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/tasks/setup-RedHat.yml @@ -0,0 +1,7 @@ +--- +- name: Ensure MySQL packages are installed. + yum: + name: "{{ mysql_packages }}" + state: present + enablerepo: "{{ mysql_enablerepo | default(omit, true) }}" + register: rh_mysql_install_packages diff --git a/provisioning/roles/geerlingguy.mysql/tasks/users.yml b/provisioning/roles/geerlingguy.mysql/tasks/users.yml new file mode 100644 index 000000000..75265ea42 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/tasks/users.yml @@ -0,0 +1,12 @@ +--- +- name: Ensure MySQL users are present. + mysql_user: + name: "{{ item.name }}" + host: "{{ item.host | default('localhost') }}" + password: "{{ item.password }}" + priv: "{{ item.priv | default('*.*:USAGE') }}" + state: "{{ item.state | default('present') }}" + append_privs: "{{ item.append_privs | default('no') }}" + encrypted: "{{ item.encrypted | default('no') }}" + with_items: "{{ mysql_users }}" + no_log: true diff --git a/provisioning/roles/geerlingguy.mysql/tasks/variables.yml b/provisioning/roles/geerlingguy.mysql/tasks/variables.yml new file mode 100644 index 000000000..6e3810673 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/tasks/variables.yml @@ -0,0 +1,59 @@ +--- +# Variable configuration. +- name: Include OS-specific variables. + include_vars: "{{ item }}" + with_first_found: + - files: + - "vars/{{ ansible_os_family }}-{{ ansible_distribution_major_version }}.yml" + - "vars/{{ ansible_os_family }}.yml" + skip: true + +- name: Define mysql_packages. + set_fact: + mysql_packages: "{{ __mysql_packages | list }}" + when: mysql_packages is not defined + +- name: Define mysql_daemon. + set_fact: + mysql_daemon: "{{ __mysql_daemon }}" + when: mysql_daemon is not defined + +- name: Define mysql_slow_query_log_file. + set_fact: + mysql_slow_query_log_file: "{{ __mysql_slow_query_log_file }}" + when: mysql_slow_query_log_file is not defined + +- name: Define mysql_log_error. + set_fact: + mysql_log_error: "{{ __mysql_log_error }}" + when: mysql_log_error is not defined + +- name: Define mysql_syslog_tag. + set_fact: + mysql_syslog_tag: "{{ __mysql_syslog_tag }}" + when: mysql_syslog_tag is not defined + +- name: Define mysql_pid_file. + set_fact: + mysql_pid_file: "{{ __mysql_pid_file }}" + when: mysql_pid_file is not defined + +- name: Define mysql_config_file. + set_fact: + mysql_config_file: "{{ __mysql_config_file }}" + when: mysql_config_file is not defined + +- name: Define mysql_config_include_dir. + set_fact: + mysql_config_include_dir: "{{ __mysql_config_include_dir }}" + when: mysql_config_include_dir is not defined + +- name: Define mysql_socket. + set_fact: + mysql_socket: "{{ __mysql_socket }}" + when: mysql_socket is not defined + +- name: Define mysql_supports_innodb_large_prefix. + set_fact: + mysql_supports_innodb_large_prefix: "{{ __mysql_supports_innodb_large_prefix }}" + when: mysql_supports_innodb_large_prefix is not defined diff --git a/provisioning/roles/geerlingguy.mysql/templates/my.cnf.j2 b/provisioning/roles/geerlingguy.mysql/templates/my.cnf.j2 new file mode 100644 index 000000000..78e4e9125 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/templates/my.cnf.j2 @@ -0,0 +1,124 @@ +{{ ansible_managed | comment }} + +[client] +#password = your_password +port = {{ mysql_port }} +socket = {{ mysql_socket }} + +[mysqld] +port = {{ mysql_port }} +bind-address = {{ mysql_bind_address }} +datadir = {{ mysql_datadir }} +socket = {{ mysql_socket }} +pid-file = {{ mysql_pid_file }} +{% if mysql_skip_name_resolve %} +skip-name-resolve +{% endif %} +{% if mysql_sql_mode is not none %} +sql_mode = {{ mysql_sql_mode }} +{% endif %} + +# Logging configuration. +{% if mysql_log_error == 'syslog' or mysql_log == 'syslog' %} +syslog +syslog-tag = {{ mysql_syslog_tag }} +{% else %} +{% if mysql_log %} +log = {{ mysql_log }} +{% endif %} +log-error = {{ mysql_log_error }} +{% endif %} + +{% if mysql_slow_query_log_enabled %} +# Slow query log configuration. +slow_query_log = 1 +slow_query_log_file = {{ mysql_slow_query_log_file }} +long_query_time = {{ mysql_slow_query_time }} +{% endif %} + +{% if mysql_replication_master %} +# Replication +server-id = {{ mysql_server_id }} + +{% if mysql_replication_role == 'master' %} +log_bin = mysql-bin +log-bin-index = mysql-bin.index +expire_logs_days = {{ mysql_expire_logs_days }} +max_binlog_size = {{ mysql_max_binlog_size }} +binlog_format = {{mysql_binlog_format}} + +{% for db in mysql_databases %} +{% if db.replicate|default(1) %} +binlog_do_db = {{ db.name }} +{% else %} +binlog_ignore_db = {{ db.name }} +{% endif %} +{% endfor %} +{% endif %} + +{% if mysql_replication_role == 'slave' %} +read_only +relay-log = relay-bin +relay-log-index = relay-bin.index +{% endif %} +{% endif %} + +# Disabling symbolic-links is recommended to prevent assorted security risks +symbolic-links = 0 + +# User is ignored when systemd is used (fedora >= 15). +user = mysql + +# http://dev.mysql.com/doc/refman/5.5/en/performance-schema.html +;performance_schema + +# Memory settings. +key_buffer_size = {{ mysql_key_buffer_size }} +max_allowed_packet = {{ mysql_max_allowed_packet }} +table_open_cache = {{ mysql_table_open_cache }} +sort_buffer_size = {{ mysql_sort_buffer_size }} +read_buffer_size = {{ mysql_read_buffer_size }} +read_rnd_buffer_size = {{ mysql_read_rnd_buffer_size }} +myisam_sort_buffer_size = {{ mysql_myisam_sort_buffer_size }} +thread_cache_size = {{ mysql_thread_cache_size }} +{% if '8.0.' not in mysql_cli_version.stdout %} +query_cache_type = {{ mysql_query_cache_type }} +query_cache_size = {{ mysql_query_cache_size }} +query_cache_limit = {{ mysql_query_cache_limit }} +{% endif %} +max_connections = {{ mysql_max_connections }} +tmp_table_size = {{ mysql_tmp_table_size }} +max_heap_table_size = {{ mysql_max_heap_table_size }} +group_concat_max_len = {{ mysql_group_concat_max_len }} +join_buffer_size = {{ mysql_join_buffer_size }} + +# Other settings. +wait_timeout = {{ mysql_wait_timeout }} +lower_case_table_names = {{ mysql_lower_case_table_names }} +event_scheduler = {{ mysql_event_scheduler_state }} + +# InnoDB settings. +{% if mysql_supports_innodb_large_prefix and '8.0.' not in mysql_cli_version.stdout %} +innodb_large_prefix = {{ mysql_innodb_large_prefix }} +innodb_file_format = {{ mysql_innodb_file_format }} +{% endif %} +innodb_file_per_table = {{ mysql_innodb_file_per_table }} +innodb_buffer_pool_size = {{ mysql_innodb_buffer_pool_size }} +innodb_log_file_size = {{ mysql_innodb_log_file_size }} +innodb_log_buffer_size = {{ mysql_innodb_log_buffer_size }} +innodb_flush_log_at_trx_commit = {{ mysql_innodb_flush_log_at_trx_commit }} +innodb_lock_wait_timeout = {{ mysql_innodb_lock_wait_timeout }} + +[mysqldump] +quick +max_allowed_packet = {{ mysql_mysqldump_max_allowed_packet }} + +[mysqld_safe] +pid-file = {{ mysql_pid_file }} + +{% if mysql_config_include_files | length %} +# * IMPORTANT: Additional settings that can override those from this file! +# The files must end with '.cnf', otherwise they'll be ignored. +# +!includedir {{ mysql_config_include_dir }} +{% endif %} diff --git a/provisioning/roles/geerlingguy.mysql/templates/root-my.cnf.j2 b/provisioning/roles/geerlingguy.mysql/templates/root-my.cnf.j2 new file mode 100644 index 000000000..af13e810e --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/templates/root-my.cnf.j2 @@ -0,0 +1,5 @@ +{{ ansible_managed | comment }} + +[client] +user="{{ mysql_root_username }}" +password="{{ mysql_root_password }}" diff --git a/provisioning/roles/geerlingguy.mysql/templates/user-my.cnf.j2 b/provisioning/roles/geerlingguy.mysql/templates/user-my.cnf.j2 new file mode 100644 index 000000000..62e3692ea --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/templates/user-my.cnf.j2 @@ -0,0 +1,5 @@ +{{ ansible_managed | comment }} + +[client] +user="{{ mysql_user_name }}" +password="{{ mysql_user_password }}" diff --git a/provisioning/roles/geerlingguy.mysql/vars/Archlinux.yml b/provisioning/roles/geerlingguy.mysql/vars/Archlinux.yml new file mode 100644 index 000000000..2dd3c4750 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/vars/Archlinux.yml @@ -0,0 +1,12 @@ +--- +__mysql_daemon: mariadb +__mysql_packages: + - mariadb +__mysql_slow_query_log_file: /var/log/mysql/mysql-slow.log +__mysql_log_error: /var/log/mysql.err +__mysql_syslog_tag: mysql +__mysql_pid_file: /run/mysqld/mysqld.pid +__mysql_config_file: /etc/mysql/my.cnf +__mysql_config_include_dir: /etc/mysql/conf.d +__mysql_socket: /run/mysqld/mysqld.sock +__mysql_supports_innodb_large_prefix: true diff --git a/provisioning/roles/geerlingguy.mysql/vars/Debian-10.yml b/provisioning/roles/geerlingguy.mysql/vars/Debian-10.yml new file mode 100644 index 000000000..cb4935aeb --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/vars/Debian-10.yml @@ -0,0 +1,13 @@ +--- +__mysql_daemon: mariadb +__mysql_packages: + - default-mysql-server +mysql_log_file_group: adm +__mysql_slow_query_log_file: /var/log/mysql/mysql-slow.log +__mysql_log_error: /var/log/mysql/mysql.log +__mysql_syslog_tag: mariadb +__mysql_pid_file: /run/mysqld/mysqld.pid +__mysql_config_file: /etc/mysql/my.cnf +__mysql_config_include_dir: /etc/mysql/conf.d +__mysql_socket: /run/mysqld/mysqld.sock +__mysql_supports_innodb_large_prefix: true diff --git a/provisioning/roles/geerlingguy.mysql/vars/Debian.yml b/provisioning/roles/geerlingguy.mysql/vars/Debian.yml new file mode 100644 index 000000000..a96a025c6 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/vars/Debian.yml @@ -0,0 +1,14 @@ +--- +__mysql_daemon: mysql +__mysql_packages: + - mysql-common + - mysql-server +mysql_log_file_group: adm +__mysql_slow_query_log_file: /var/log/mysql/mysql-slow.log +__mysql_log_error: /var/log/mysql/mysql.err +__mysql_syslog_tag: mysql +__mysql_pid_file: /var/run/mysqld/mysqld.pid +__mysql_config_file: /etc/mysql/my.cnf +__mysql_config_include_dir: /etc/mysql/conf.d +__mysql_socket: /var/run/mysqld/mysqld.sock +__mysql_supports_innodb_large_prefix: true diff --git a/provisioning/roles/geerlingguy.mysql/vars/RedHat-7.yml b/provisioning/roles/geerlingguy.mysql/vars/RedHat-7.yml new file mode 100644 index 000000000..6f989b3a4 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/vars/RedHat-7.yml @@ -0,0 +1,16 @@ +--- +__mysql_daemon: mariadb +__mysql_packages: + - mariadb + - mariadb-server + - mariadb-libs + - MySQL-python + - perl-DBD-MySQL +__mysql_slow_query_log_file: /var/log/mysql-slow.log +__mysql_log_error: /var/log/mariadb/mariadb.log +__mysql_syslog_tag: mariadb +__mysql_pid_file: /var/run/mariadb/mariadb.pid +__mysql_config_file: /etc/my.cnf +__mysql_config_include_dir: /etc/my.cnf.d +__mysql_socket: /var/lib/mysql/mysql.sock +__mysql_supports_innodb_large_prefix: true diff --git a/provisioning/roles/geerlingguy.mysql/vars/RedHat-8.yml b/provisioning/roles/geerlingguy.mysql/vars/RedHat-8.yml new file mode 100644 index 000000000..12484af47 --- /dev/null +++ b/provisioning/roles/geerlingguy.mysql/vars/RedHat-8.yml @@ -0,0 +1,18 @@ +--- +__mysql_daemon: mariadb +__mysql_packages: + - mariadb + - mariadb-server + - mariadb-connector-c + - python3-PyMySQL + - perl-DBD-MySQL +__mysql_slow_query_log_file: /var/log/mysql-slow.log +__mysql_log_error: /var/log/mariadb/mariadb.log +__mysql_syslog_tag: mariadb +__mysql_pid_file: /var/run/mariadb/mariadb.pid +__mysql_config_file: /etc/my.cnf +__mysql_config_include_dir: /etc/my.cnf.d +__mysql_socket: /var/lib/mysql/mysql.sock +# The entries controlled by this value should not be used with MariaDB >= 10.2.2 +# See https://github.com/frappe/bench/issues/681#issuecomment-398984706 +__mysql_supports_innodb_large_prefix: false diff --git a/provisioning/roles/geerlingguy.nginx/.ansible-lint b/provisioning/roles/geerlingguy.nginx/.ansible-lint new file mode 100644 index 000000000..acc82551f --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/.ansible-lint @@ -0,0 +1,3 @@ +skip_list: + - 'yaml' + - 'role-name' diff --git a/provisioning/roles/geerlingguy.nginx/.github/FUNDING.yml b/provisioning/roles/geerlingguy.nginx/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.nginx/.github/stale.yml b/provisioning/roles/geerlingguy.nginx/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.nginx/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.nginx/.github/workflows/ci.yml new file mode 100644 index 000000000..bd266ca41 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/.github/workflows/ci.yml @@ -0,0 +1,69 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "0 6 * * 3" + +defaults: + run: + working-directory: 'geerlingguy.nginx' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.nginx' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + distro: + - centos8 + - rockylinux8 + - ubuntu2004 + - ubuntu1804 + - debian10 + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.nginx' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} diff --git a/provisioning/roles/geerlingguy.nginx/.github/workflows/release.yml b/provisioning/roles/geerlingguy.nginx/.github/workflows/release.yml new file mode 100644 index 000000000..de16921ba --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.nginx' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.nginx' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.nginx/.gitignore b/provisioning/roles/geerlingguy.nginx/.gitignore new file mode 100644 index 000000000..8840c8f02 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/.gitignore @@ -0,0 +1,5 @@ +*.retry +*/__pycache__ +*.pyc +.cache + diff --git a/provisioning/roles/geerlingguy.nginx/.yamllint b/provisioning/roles/geerlingguy.nginx/.yamllint new file mode 100644 index 000000000..f2033dd21 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/provisioning/roles/geerlingguy.nginx/LICENSE b/provisioning/roles/geerlingguy.nginx/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.nginx/README.md b/provisioning/roles/geerlingguy.nginx/README.md new file mode 100644 index 000000000..d418aaacf --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/README.md @@ -0,0 +1,246 @@ +# Ansible Role: Nginx + +[![CI](https://github.com/geerlingguy/ansible-role-nginx/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-nginx/actions?query=workflow%3ACI) + +**Note:** Please consider using the official [NGINX Ansible role](https://github.com/nginxinc/ansible-role-nginx) from NGINX, Inc. + +Installs Nginx on RedHat/CentOS, Debian/Ubuntu, Archlinux, FreeBSD or OpenBSD servers. + +This role installs and configures the latest version of Nginx from the Nginx yum repository (on RedHat-based systems), apt (on Debian-based systems), pacman (Archlinux), pkgng (on FreeBSD systems) or pkg_add (on OpenBSD systems). You will likely need to do extra setup work after this role has installed Nginx, like adding your own [virtualhost].conf file inside `/etc/nginx/conf.d/`, describing the location and options to use for your particular website. + +## Requirements + +None. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + + nginx_listen_ipv6: true + +Whether or not to listen on IPv6 (applied to all vhosts managed by this role). + + nginx_vhosts: [] + +A list of vhost definitions (server blocks) for Nginx virtual hosts. Each entry will create a separate config file named by `server_name`. If left empty, you will need to supply your own virtual host configuration. See the commented example in `defaults/main.yml` for available server options. If you have a large number of customizations required for your server definition(s), you're likely better off managing the vhost configuration file yourself, leaving this variable set to `[]`. + + nginx_vhosts: + - listen: "443 ssl http2" + server_name: "example.com" + server_name_redirect: "www.example.com" + root: "/var/www/example.com" + index: "index.php index.html index.htm" + error_page: "" + access_log: "" + error_log: "" + state: "present" + template: "{{ nginx_vhost_template }}" + filename: "example.com.conf" + extra_parameters: | + location ~ \.php$ { + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass unix:/var/run/php5-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; + ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; + ssl_protocols TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!MD5; + +An example of a fully-populated nginx_vhosts entry, using a `|` to declare a block of syntax for the `extra_parameters`. + +Please take note of the indentation in the above block. The first line should be a normal 2-space indent. All other lines should be indented normally relative to that line. In the generated file, the entire block will be 4-space indented. This style will ensure the config file is indented correctly. + + - listen: "80" + server_name: "example.com www.example.com" + return: "301 https://example.com$request_uri" + filename: "example.com.80.conf" + +An example of a secondary vhost which will redirect to the one shown above. + +*Note: The `filename` defaults to the first domain in `server_name`, if you have two vhosts with the same domain, eg. a redirect, you need to manually set the `filename` so the second one doesn't override the first one* + + nginx_remove_default_vhost: false + +Whether to remove the 'default' virtualhost configuration supplied by Nginx. Useful if you want the base `/` URL to be directed at one of your own virtual hosts configured in a separate .conf file. + + nginx_upstreams: [] + +If you are configuring Nginx as a load balancer, you can define one or more upstream sets using this variable. In addition to defining at least one upstream, you would need to configure one of your server blocks to proxy requests through the defined upstream (e.g. `proxy_pass http://myapp1;`). See the commented example in `defaults/main.yml` for more information. + + nginx_user: "nginx" + +The user under which Nginx will run. Defaults to `nginx` for RedHat, `www-data` for Debian and `www` on FreeBSD and OpenBSD. + + nginx_worker_processes: "{{ ansible_processor_vcpus|default(ansible_processor_count) }}" + nginx_worker_connections: "1024" + nginx_multi_accept: "off" + +`nginx_worker_processes` should be set to the number of cores present on your machine (if the default is incorrect, find this number with `grep processor /proc/cpuinfo | wc -l`). `nginx_worker_connections` is the number of connections per process. Set this higher to handle more simultaneous connections (and remember that a connection will be used for as long as the keepalive timeout duration for every client!). You can set `nginx_multi_accept` to `on` if you want Nginx to accept all connections immediately. + + nginx_error_log: "/var/log/nginx/error.log warn" + nginx_access_log: "/var/log/nginx/access.log main buffer=16k" + +Configuration of the default error and access logs. Set to `off` to disable a log entirely. + + nginx_sendfile: "on" + nginx_tcp_nopush: "on" + nginx_tcp_nodelay: "on" + +TCP connection options. See [this blog post](https://t37.net/nginx-optimization-understanding-sendfile-tcp_nodelay-and-tcp_nopush.html) for more information on these directives. + + nginx_keepalive_timeout: "65" + nginx_keepalive_requests: "100" + +Nginx keepalive settings. Timeout should be set higher (10s+) if you have more polling-style traffic (AJAX-powered sites especially), or lower (<10s) if you have a site where most users visit a few pages and don't send any further requests. + + nginx_server_tokens: "on" + +Nginx server_tokens settings. Controls whether nginx responds with it's version in HTTP headers. Set to `"off"` to disable. + + nginx_client_max_body_size: "64m" + +This value determines the largest file upload possible, as uploads are passed through Nginx before hitting a backend like `php-fpm`. If you get an error like `client intended to send too large body`, it means this value is set too low. + + nginx_server_names_hash_bucket_size: "64" + +If you have many server names, or have very long server names, you might get an Nginx error on startup requiring this value to be increased. + + nginx_proxy_cache_path: "" + +Set as the `proxy_cache_path` directive in the `nginx.conf` file. By default, this will not be configured (if left as an empty string), but if you wish to use Nginx as a reverse proxy, you can set this to a valid value (e.g. `"/var/cache/nginx keys_zone=cache:32m"`) to use Nginx's cache (further proxy configuration can be done in individual server configurations). + + nginx_extra_http_options: "" + +Extra lines to be inserted in the top-level `http` block in `nginx.conf`. The value should be defined literally (as you would insert it directly in the `nginx.conf`, adhering to the Nginx configuration syntax - such as `;` for line termination, etc.), for example: + + nginx_extra_http_options: | + proxy_buffering off; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + +See the template in `templates/nginx.conf.j2` for more details on the placement. + + nginx_extra_conf_options: "" + +Extra lines to be inserted in the top of `nginx.conf`. The value should be defined literally (as you would insert it directly in the `nginx.conf`, adhering to the Nginx configuration syntax - such as `;` for line termination, etc.), for example: + + nginx_extra_conf_options: | + worker_rlimit_nofile 8192; + +See the template in `templates/nginx.conf.j2` for more details on the placement. + + nginx_log_format: |- + '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"' + +Configures Nginx's [`log_format`](http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format). options. + + nginx_default_release: "" + +(For Debian/Ubuntu only) Allows you to set a different repository for the installation of Nginx. As an example, if you are running Debian's wheezy release, and want to get a newer version of Nginx, you can install the `wheezy-backports` repository and set that value here, and Ansible will use that as the `-t` option while installing Nginx. + + nginx_ppa_use: false + nginx_ppa_version: stable + +(For Ubuntu only) Allows you to use the official Nginx PPA instead of the system's package. You can set the version to `stable` or `development`. + + nginx_yum_repo_enabled: true + +(For RedHat/CentOS only) Set this to `false` to disable the installation of the `nginx` yum repository. This could be necessary if you want the default OS stable packages, or if you use Satellite. + + nginx_service_state: started + nginx_service_enabled: yes + +By default, this role will ensure Nginx is running and enabled at boot after Nginx is configured. You can use these variables to override this behavior if installing in a container or further control over the service state is required. + +## Overriding configuration templates + +If you can't customize via variables because an option isn't exposed, you can override the template used to generate the virtualhost configuration files or the `nginx.conf` file. + +```yaml +nginx_conf_template: "nginx.conf.j2" +nginx_vhost_template: "vhost.j2" +``` + +If necessary you can also set the template on a per vhost basis. + +```yaml +nginx_vhosts: + - listen: "80 default_server" + server_name: "site1.example.com" + root: "/var/www/site1.example.com" + index: "index.php index.html index.htm" + template: "{{ playbook_dir }}/templates/site1.example.com.vhost.j2" + - server_name: "site2.example.com" + root: "/var/www/site2.example.com" + index: "index.php index.html index.htm" + template: "{{ playbook_dir }}/templates/site2.example.com.vhost.j2" +``` + +You can either copy and modify the provided template, or extend it with [Jinja2 template inheritance](http://jinja.pocoo.org/docs/2.9/templates/#template-inheritance) and override the specific template block you need to change. + +### Example: Configure gzip in nginx configuration + +Set the `nginx_conf_template` to point to a template file in your playbook directory. + +```yaml +nginx_conf_template: "{{ playbook_dir }}/templates/nginx.conf.j2" +``` + +Create the child template in the path you configured above and extend `geerlingguy.nginx` template file relative to your `playbook.yml`. + +``` +{% extends 'roles/geerlingguy.nginx/templates/nginx.conf.j2' %} + +{% block http_gzip %} + gzip on; + gzip_proxied any; + gzip_static on; + gzip_http_version 1.0; + gzip_disable "MSIE [1-6]\."; + gzip_vary on; + gzip_comp_level 6; + gzip_types + text/plain + text/css + text/xml + text/javascript + application/javascript + application/x-javascript + application/json + application/xml + application/xml+rss + application/xhtml+xml + application/x-font-ttf + application/x-font-opentype + image/svg+xml + image/x-icon; + gzip_buffers 16 8k; + gzip_min_length 512; +{% endblock %} +``` + +## Dependencies + +None. + +## Example Playbook + + - hosts: server + roles: + - { role: geerlingguy.nginx } + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.nginx/defaults/main.yml b/provisioning/roles/geerlingguy.nginx/defaults/main.yml new file mode 100644 index 000000000..3178cd562 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/defaults/main.yml @@ -0,0 +1,93 @@ +--- +# Used only for Debian/Ubuntu installation, as the -t option for apt. +nginx_default_release: "" + +# Used only for Redhat installation, enables source Nginx repo. +nginx_yum_repo_enabled: true + +# Use the official Nginx PPA for Ubuntu, and the version to use if so. +nginx_ppa_use: false +nginx_ppa_version: stable + +# The name of the nginx package to install. +nginx_package_name: "nginx" + +nginx_service_state: started +nginx_service_enabled: true + +nginx_conf_template: "nginx.conf.j2" +nginx_vhost_template: "vhost.j2" + +nginx_worker_processes: >- + "{{ ansible_processor_vcpus | default(ansible_processor_count) }}" +nginx_worker_connections: "1024" +nginx_multi_accept: "off" + +nginx_error_log: "/var/log/nginx/error.log warn" +nginx_access_log: "/var/log/nginx/access.log main buffer=16k flush=2m" + +nginx_sendfile: "on" +nginx_tcp_nopush: "on" +nginx_tcp_nodelay: "on" + +nginx_keepalive_timeout: "65" +nginx_keepalive_requests: "100" + +nginx_server_tokens: "on" + +nginx_client_max_body_size: "64m" + +nginx_server_names_hash_bucket_size: "64" + +nginx_proxy_cache_path: "" + +nginx_extra_conf_options: "" +# Example extra main options, used within the main nginx's context: +# nginx_extra_conf_options: | +# env VARIABLE; +# include /etc/nginx/main.d/*.conf; + +nginx_extra_http_options: "" +# Example extra http options, printed inside the main server http config: +# nginx_extra_http_options: | +# proxy_buffering off; +# proxy_set_header X-Real-IP $remote_addr; +# proxy_set_header X-Scheme $scheme; +# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +# proxy_set_header Host $http_host; + +nginx_remove_default_vhost: false + +# Listen on IPv6 (default: true) +nginx_listen_ipv6: true + +nginx_vhosts: [] +# Example vhost below, showing all available options: +# - listen: "80" # default: "80" +# server_name: "example.com" # default: N/A +# root: "/var/www/example.com" # default: N/A +# index: "index.html index.htm" # default: "index.html index.htm" +# filename: "example.com.conf" # Can be used to set the vhost filename. +# +# # Properties that are only added if defined: +# server_name_redirect: "www.example.com" # default: N/A +# error_page: "" +# access_log: "" +# error_log: "" +# extra_parameters: "" # Can be used to add extra config blocks (multiline). +# template: "" # Can be used to override the `nginx_vhost_template` per host. +# state: "absent" # To remove the vhost configuration. + +nginx_upstreams: [] +# - name: myapp1 +# strategy: "ip_hash" # "least_conn", etc. +# keepalive: 16 # optional +# servers: +# - "srv1.example.com" +# - "srv2.example.com weight=3" +# - "srv3.example.com" + +nginx_log_format: |- + '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"' diff --git a/provisioning/roles/geerlingguy.nginx/handlers/main.yml b/provisioning/roles/geerlingguy.nginx/handlers/main.yml new file mode 100644 index 000000000..2db781ee4 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/handlers/main.yml @@ -0,0 +1,10 @@ +--- +- name: restart nginx + service: name=nginx state=restarted + +- name: validate nginx configuration + command: nginx -t -c /etc/nginx/nginx.conf + changed_when: false + +- name: reload nginx + service: name=nginx state=reloaded diff --git a/provisioning/roles/geerlingguy.nginx/meta/main.yml b/provisioning/roles/geerlingguy.nginx/meta/main.yml new file mode 100644 index 000000000..0033d24cb --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/meta/main.yml @@ -0,0 +1,45 @@ +--- +dependencies: [] + +galaxy_info: + role_name: nginx + author: geerlingguy + description: Nginx installation for Linux, FreeBSD and OpenBSD. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - 7 + - 8 + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - trusty + - xenial + - focal + - name: Archlinux + versions: + - all + - name: FreeBSD + versions: + - 10.3 + - 10.2 + - 10.1 + - 10.0 + - 9.3 + - name: OpenBSD + versions: + - 5.9 + - 6.0 + galaxy_tags: + - development + - web + - nginx + - reverse + - proxy + - load + - balancer diff --git a/provisioning/roles/geerlingguy.nginx/molecule/default/converge.yml b/provisioning/roles/geerlingguy.nginx/molecule/default/converge.yml new file mode 100644 index 000000000..ee651977b --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/molecule/default/converge.yml @@ -0,0 +1,19 @@ +--- +- name: Converge + hosts: all + + vars: + nginx_use_ppa: true + nginx_remove_default_vhost: true + nginx_vhosts: + - server_name: "test.dev" + root: "/var/www/test" + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + roles: + - role: geerlingguy.nginx diff --git a/provisioning/roles/geerlingguy.nginx/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.nginx/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.nginx/tasks/main.yml b/provisioning/roles/geerlingguy.nginx/tasks/main.yml new file mode 100644 index 000000000..bcf3ccec5 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/tasks/main.yml @@ -0,0 +1,48 @@ +--- +# Variable setup. +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define nginx_user. + set_fact: + nginx_user: "{{ __nginx_user }}" + when: nginx_user is not defined + +# Setup/install tasks. +- include_tasks: setup-RedHat.yml + when: ansible_os_family == 'RedHat' or ansible_os_family == 'Rocky' + +- include_tasks: setup-Ubuntu.yml + when: ansible_distribution == 'Ubuntu' + +- include_tasks: setup-Debian.yml + when: ansible_os_family == 'Debian' + +- include_tasks: setup-FreeBSD.yml + when: ansible_os_family == 'FreeBSD' + +- include_tasks: setup-OpenBSD.yml + when: ansible_os_family == 'OpenBSD' + +- include_tasks: setup-Archlinux.yml + when: ansible_os_family == 'Archlinux' + +# Vhost configuration. +- import_tasks: vhosts.yml + +# Nginx setup. +- name: Copy nginx configuration in place. + template: + src: "{{ nginx_conf_template }}" + dest: "{{ nginx_conf_file_path }}" + owner: root + group: "{{ root_group }}" + mode: 0644 + notify: + - reload nginx + +- name: Ensure nginx service is running as configured. + service: + name: nginx + state: "{{ nginx_service_state }}" + enabled: "{{ nginx_service_enabled }}" diff --git a/provisioning/roles/geerlingguy.nginx/tasks/setup-Archlinux.yml b/provisioning/roles/geerlingguy.nginx/tasks/setup-Archlinux.yml new file mode 100644 index 000000000..46e1f5bdf --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/tasks/setup-Archlinux.yml @@ -0,0 +1,5 @@ +--- +- name: Ensure nginx is installed. + pacman: + name: "{{ nginx_package_name }}" + state: present diff --git a/provisioning/roles/geerlingguy.nginx/tasks/setup-Debian.yml b/provisioning/roles/geerlingguy.nginx/tasks/setup-Debian.yml new file mode 100644 index 000000000..554dc2e77 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/tasks/setup-Debian.yml @@ -0,0 +1,10 @@ +--- +- name: Update apt cache. + apt: update_cache=yes cache_valid_time=86400 + changed_when: false + +- name: Ensure nginx is installed. + apt: + name: "{{ nginx_package_name }}" + state: present + default_release: "{{ nginx_default_release }}" diff --git a/provisioning/roles/geerlingguy.nginx/tasks/setup-FreeBSD.yml b/provisioning/roles/geerlingguy.nginx/tasks/setup-FreeBSD.yml new file mode 100644 index 000000000..637c5202d --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/tasks/setup-FreeBSD.yml @@ -0,0 +1,17 @@ +--- +- name: Update pkg cache. + command: pkg update -f + environment: + ASSUME_ALWAYS_YES: "yes" + tags: ['skip_ansible_lint'] + +- name: Ensure nginx is installed. + pkgng: + name: "{{ nginx_package_name }}" + state: present + +- name: Create logs directory. + file: + path: /var/log/nginx + state: directory + mode: 0755 diff --git a/provisioning/roles/geerlingguy.nginx/tasks/setup-OpenBSD.yml b/provisioning/roles/geerlingguy.nginx/tasks/setup-OpenBSD.yml new file mode 100644 index 000000000..c75c27e4d --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/tasks/setup-OpenBSD.yml @@ -0,0 +1,11 @@ +--- +- name: Ensure nginx is installed. + openbsd_pkg: + name: "{{ nginx_package_name }}" + state: present + +- name: Create logs directory. + file: + path: /var/log/nginx + state: directory + mode: 0755 diff --git a/provisioning/roles/geerlingguy.nginx/tasks/setup-RedHat.yml b/provisioning/roles/geerlingguy.nginx/tasks/setup-RedHat.yml new file mode 100644 index 000000000..250739784 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/tasks/setup-RedHat.yml @@ -0,0 +1,14 @@ +--- +- name: Enable nginx repo. + template: + src: nginx.repo.j2 + dest: /etc/yum.repos.d/nginx.repo + owner: root + group: "{{ root_group }}" + mode: 0644 + when: nginx_yum_repo_enabled | bool + +- name: Ensure nginx is installed. + package: + name: "{{ nginx_package_name }}" + state: present diff --git a/provisioning/roles/geerlingguy.nginx/tasks/setup-Ubuntu.yml b/provisioning/roles/geerlingguy.nginx/tasks/setup-Ubuntu.yml new file mode 100644 index 000000000..c608d25b9 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/tasks/setup-Ubuntu.yml @@ -0,0 +1,20 @@ +--- +- name: Ensure dirmngr is installed (gnupg dependency). + apt: + name: dirmngr + state: present + +- name: Add PPA for Nginx (if configured). + apt_repository: + repo: 'ppa:nginx/{{ nginx_ppa_version }}' + state: present + update_cache: true + register: nginx_ppa_added + when: nginx_ppa_use | bool + +- name: Ensure nginx will reinstall if the PPA was just added. + apt: + name: nginx + state: absent + when: nginx_ppa_added is changed + tags: ['skip_ansible_lint'] diff --git a/provisioning/roles/geerlingguy.nginx/tasks/vhosts.yml b/provisioning/roles/geerlingguy.nginx/tasks/vhosts.yml new file mode 100644 index 000000000..8f990fb00 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/tasks/vhosts.yml @@ -0,0 +1,44 @@ +--- +- name: Remove default nginx vhost config file (if configured). + file: + path: "{{ nginx_default_vhost_path }}" + state: absent + when: nginx_remove_default_vhost | bool + notify: restart nginx + +- name: Ensure nginx_vhost_path exists. + file: + path: "{{ nginx_vhost_path }}" + state: directory + mode: 0755 + notify: reload nginx + +- name: Add managed vhost config files. + template: + src: "{{ item.template|default(nginx_vhost_template) }}" + dest: "{{ nginx_vhost_path }}/{{ item.filename|default(item.server_name.split(' ')[0] ~ '.conf') }}" + force: true + owner: root + group: "{{ root_group }}" + mode: 0644 + when: item.state|default('present') != 'absent' + with_items: "{{ nginx_vhosts }}" + notify: reload nginx + tags: + - skip_ansible_lint + +- name: Remove managed vhost config files. + file: + path: "{{ nginx_vhost_path }}/{{ item.filename|default(item.server_name.split(' ')[0] ~ '.conf') }}" + state: absent + when: item.state|default('present') == 'absent' + with_items: "{{ nginx_vhosts }}" + notify: reload nginx + tags: + - skip_ansible_lint + +- name: Remove legacy vhosts.conf file. + file: + path: "{{ nginx_vhost_path }}/vhosts.conf" + state: absent + notify: reload nginx diff --git a/provisioning/roles/geerlingguy.nginx/templates/nginx.conf.j2 b/provisioning/roles/geerlingguy.nginx/templates/nginx.conf.j2 new file mode 100644 index 000000000..7cdec6028 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/templates/nginx.conf.j2 @@ -0,0 +1,81 @@ +user {{ nginx_user }}; + +error_log {{ nginx_error_log }}; +pid {{ nginx_pidfile }}; + +{% block worker %} +worker_processes {{ nginx_worker_processes }}; +{% endblock %} + +{% if nginx_extra_conf_options %} +{{ nginx_extra_conf_options }} +{% endif %} + +{% block events %} +events { + worker_connections {{ nginx_worker_connections }}; + multi_accept {{ nginx_multi_accept }}; +} +{% endblock %} + +http { + {% block http_begin %}{% endblock %} + +{% block http_basic %} + include {{ nginx_mime_file_path }}; + default_type application/octet-stream; + + server_names_hash_bucket_size {{ nginx_server_names_hash_bucket_size }}; + + client_max_body_size {{ nginx_client_max_body_size }}; + + log_format main {{ nginx_log_format|indent(23) }}; + + access_log {{ nginx_access_log }}; + + sendfile {{ nginx_sendfile }}; + tcp_nopush {{ nginx_tcp_nopush }}; + tcp_nodelay {{ nginx_tcp_nodelay }}; + + keepalive_timeout {{ nginx_keepalive_timeout }}; + keepalive_requests {{ nginx_keepalive_requests }}; + + server_tokens {{ nginx_server_tokens }}; +{% if nginx_proxy_cache_path %} + proxy_cache_path {{ nginx_proxy_cache_path }}; +{% endif %} +{% endblock %} + +{% block http_gzip %} + # gzip on; +{% endblock %} + +{% if nginx_extra_http_options %} + {{ nginx_extra_http_options|indent(4, False) }} +{% endif %} + +{% block http_upstream %} +{% for upstream in nginx_upstreams %} + upstream {{ upstream.name }} { +{% if upstream.strategy is defined %} + {{ upstream.strategy }}; +{% endif %} +{% for server in upstream.servers %} + server {{ server }}; +{% endfor %} +{% if upstream.keepalive is defined %} + keepalive {{ upstream.keepalive }}; +{% endif %} + } +{% endfor %} +{% endblock %} + +{% block http_includes %} + include {{ nginx_conf_path }}/*.conf; +{% if nginx_conf_path != nginx_vhost_path %} + include {{ nginx_vhost_path }}/*; +{% endif %} +{% endblock %} + + {% block http_end %}{% endblock %} +} diff --git a/provisioning/roles/geerlingguy.nginx/templates/nginx.repo.j2 b/provisioning/roles/geerlingguy.nginx/templates/nginx.repo.j2 new file mode 100644 index 000000000..9a853b70b --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/templates/nginx.repo.j2 @@ -0,0 +1,5 @@ +[nginx] +name=nginx repo +baseurl=http://nginx.org/packages/centos/{{ ansible_distribution_major_version }}/$basearch/ +gpgcheck=0 +enabled=1 diff --git a/provisioning/roles/geerlingguy.nginx/templates/vhost.j2 b/provisioning/roles/geerlingguy.nginx/templates/vhost.j2 new file mode 100644 index 000000000..f419a0a02 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/templates/vhost.j2 @@ -0,0 +1,53 @@ +{% block server_redirect %} +{% if item.server_name_redirect is defined %} +server { + listen {{ item.listen | default('80') }}; +{% if nginx_listen_ipv6 %} + listen [::]:{{item.listen | default('80') }}; +{% endif %} + server_name {{ item.server_name_redirect }}; + return 301 $scheme://{{ item.server_name.split(' ')[0] }}$request_uri; +} +{% endif %} +{% endblock %} + +server { + {% block server_begin %}{% endblock %} + + {% block server_basic -%} + listen {{ item.listen | default('80') }}; +{% if nginx_listen_ipv6 %} + listen [::]:{{item.listen | default('80') }}; +{% endif %} + +{% if item.server_name is defined %} + server_name {{ item.server_name }}; +{% endif %} + +{% if item.root is defined %} + root {{ item.root }}; +{% endif %} + + index {{ item.index | default('index.html index.htm') }}; + +{% if item.error_page is defined %} + error_page {{ item.error_page }}; +{% endif %} +{% if item.access_log is defined %} + access_log {{ item.access_log }}; +{% endif %} +{% if item.error_log is defined %} + error_log {{ item.error_log }} error; +{% endif %} + +{% if item.return is defined %} + return {{ item.return }}; +{% endif %} + {% endblock %} + + {% block server_end %}{% endblock %} + +{% if item.extra_parameters is defined %} + {{ item.extra_parameters|indent(4) }} +{% endif %} +} diff --git a/provisioning/roles/geerlingguy.nginx/vars/Archlinux.yml b/provisioning/roles/geerlingguy.nginx/vars/Archlinux.yml new file mode 100644 index 000000000..593e100f1 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/vars/Archlinux.yml @@ -0,0 +1,9 @@ +--- +root_group: root +nginx_conf_path: /etc/nginx/conf.d +nginx_conf_file_path: /etc/nginx/nginx.conf +nginx_mime_file_path: /etc/nginx/mime.types +nginx_pidfile: /run/nginx.pid +nginx_vhost_path: /etc/nginx/sites-enabled +nginx_default_vhost_path: /etc/nginx/sites-enabled/default +__nginx_user: "http" diff --git a/provisioning/roles/geerlingguy.nginx/vars/Debian.yml b/provisioning/roles/geerlingguy.nginx/vars/Debian.yml new file mode 100644 index 000000000..cb127706c --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/vars/Debian.yml @@ -0,0 +1,9 @@ +--- +root_group: root +nginx_conf_path: /etc/nginx/conf.d +nginx_conf_file_path: /etc/nginx/nginx.conf +nginx_mime_file_path: /etc/nginx/mime.types +nginx_pidfile: /run/nginx.pid +nginx_vhost_path: /etc/nginx/sites-enabled +nginx_default_vhost_path: /etc/nginx/sites-enabled/default +__nginx_user: "www-data" diff --git a/provisioning/roles/geerlingguy.nginx/vars/FreeBSD.yml b/provisioning/roles/geerlingguy.nginx/vars/FreeBSD.yml new file mode 100644 index 000000000..b032f98bc --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/vars/FreeBSD.yml @@ -0,0 +1,9 @@ +--- +root_group: wheel +nginx_conf_path: /usr/local/etc/nginx/conf.d +nginx_conf_file_path: /usr/local/etc/nginx/nginx.conf +nginx_mime_file_path: /usr/local/etc/nginx/mime.types +nginx_pidfile: /var/run/nginx.pid +nginx_vhost_path: /usr/local/etc/nginx/sites-enabled +nginx_default_vhost_path: /usr/local/etc/nginx/sites-enabled/default +__nginx_user: "www" diff --git a/provisioning/roles/geerlingguy.nginx/vars/OpenBSD.yml b/provisioning/roles/geerlingguy.nginx/vars/OpenBSD.yml new file mode 100644 index 000000000..a5a5c9dc2 --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/vars/OpenBSD.yml @@ -0,0 +1,10 @@ +--- +root_group: wheel +nginx_conf_path: /etc/nginx/conf.d +nginx_conf_file_path: /etc/nginx/nginx.conf +nginx_mime_file_path: /etc/nginx/mime.types +nginx_pidfile: /var/run/nginx.pid +nginx_vhost_path: /etc/nginx/sites-enabled +nginx_default_vhost_path: /etc/nginx/sites-enabled/default +nginx_package_name: "nginx--" +__nginx_user: "www" diff --git a/provisioning/roles/geerlingguy.nginx/vars/RedHat.yml b/provisioning/roles/geerlingguy.nginx/vars/RedHat.yml new file mode 100644 index 000000000..0138f8daa --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/vars/RedHat.yml @@ -0,0 +1,9 @@ +--- +root_group: root +nginx_conf_path: /etc/nginx/conf.d +nginx_conf_file_path: /etc/nginx/nginx.conf +nginx_mime_file_path: /etc/nginx/mime.types +nginx_pidfile: /var/run/nginx.pid +nginx_vhost_path: /etc/nginx/conf.d +nginx_default_vhost_path: /etc/nginx/conf.d/default.conf +__nginx_user: "nginx" diff --git a/provisioning/roles/geerlingguy.nginx/vars/Rocky.yml b/provisioning/roles/geerlingguy.nginx/vars/Rocky.yml new file mode 100644 index 000000000..0138f8daa --- /dev/null +++ b/provisioning/roles/geerlingguy.nginx/vars/Rocky.yml @@ -0,0 +1,9 @@ +--- +root_group: root +nginx_conf_path: /etc/nginx/conf.d +nginx_conf_file_path: /etc/nginx/nginx.conf +nginx_mime_file_path: /etc/nginx/mime.types +nginx_pidfile: /var/run/nginx.pid +nginx_vhost_path: /etc/nginx/conf.d +nginx_default_vhost_path: /etc/nginx/conf.d/default.conf +__nginx_user: "nginx" diff --git a/provisioning/roles/geerlingguy.nodejs/.ansible-lint b/provisioning/roles/geerlingguy.nodejs/.ansible-lint new file mode 100644 index 000000000..acc82551f --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/.ansible-lint @@ -0,0 +1,3 @@ +skip_list: + - 'yaml' + - 'role-name' diff --git a/provisioning/roles/geerlingguy.nodejs/.github/FUNDING.yml b/provisioning/roles/geerlingguy.nodejs/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.nodejs/.github/stale.yml b/provisioning/roles/geerlingguy.nodejs/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.nodejs/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.nodejs/.github/workflows/ci.yml new file mode 100644 index 000000000..68009cdbd --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/.github/workflows/ci.yml @@ -0,0 +1,76 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "0 7 * * 3" + +defaults: + run: + working-directory: 'geerlingguy.nodejs' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.nodejs' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + include: + - distro: rockylinux8 + playbook: converge.yml + - distro: centos7 + playbook: converge.yml + - distro: ubuntu1804 + playbook: converge.yml + - distro: debian9 + playbook: converge.yml + + - distro: centos7 + playbook: playbook-latest.yml + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.nodejs' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} + MOLECULE_PLAYBOOK: ${{ matrix.playbook }} diff --git a/provisioning/roles/geerlingguy.nodejs/.github/workflows/release.yml b/provisioning/roles/geerlingguy.nodejs/.github/workflows/release.yml new file mode 100644 index 000000000..d4724394c --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.nodejs' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.nodejs' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.nodejs/.gitignore b/provisioning/roles/geerlingguy.nodejs/.gitignore new file mode 100644 index 000000000..8840c8f02 --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/.gitignore @@ -0,0 +1,5 @@ +*.retry +*/__pycache__ +*.pyc +.cache + diff --git a/provisioning/roles/geerlingguy.nodejs/.yamllint b/provisioning/roles/geerlingguy.nodejs/.yamllint new file mode 100644 index 000000000..dfae3893f --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 220 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/provisioning/roles/geerlingguy.nodejs/LICENSE b/provisioning/roles/geerlingguy.nodejs/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.nodejs/README.md b/provisioning/roles/geerlingguy.nodejs/README.md new file mode 100644 index 000000000..4cff0f3d9 --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/README.md @@ -0,0 +1,77 @@ +# Ansible Role: Node.js + +[![CI](https://github.com/geerlingguy/ansible-role-nodejs/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-nodejs/actions?query=workflow%3ACI) + +Installs Node.js on RHEL/CentOS or Debian/Ubuntu. + +## Requirements + +None. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + nodejs_version: "14.x" + +The Node.js version to install. "14.x" is the default and works on most supported OSes. Other versions such as "8.x", "10.x", "13.x", etc. should work on the latest versions of Debian/Ubuntu and RHEL/CentOS. + + nodejs_install_npm_user: "{{ ansible_ssh_user }}" + +The user for whom the npm packages will be installed can be set here, this defaults to `ansible_user`. + + npm_config_prefix: "/usr/local/lib/npm" + +The global installation directory. This should be writeable by the `nodejs_install_npm_user`. + + npm_config_unsafe_perm: "false" + +Set to true to suppress the UID/GID switching when running package scripts. If set explicitly to false, then installing as a non-root user will fail. + + nodejs_npm_global_packages: [] + +A list of npm packages with a `name` and (optional) `version` to be installed globally. For example: + + nodejs_npm_global_packages: + # Install a specific version of a package. + - name: jslint + version: 0.9.3 + # Install the latest stable release of a package. + - name: node-sass + # This shorthand syntax also works (same as previous example). + - node-sass +<!-- code block separator --> + + nodejs_package_json_path: "" + +Set a path pointing to a particular `package.json` (e.g. `"/var/www/app/package.json"`). This will install all of the defined packages globally using Ansible's `npm` module. + + nodejs_generate_etc_profile: "true" + +By default the role will create `/etc/profile.d/npm.sh` with exported variables (`PATH`, `NPM_CONFIG_PREFIX`, `NODE_PATH`). If you prefer to avoid generating that file (e.g. you want to set the variables yourself for a non-global install), set it to "false". + +## Dependencies + +None. + +## Example Playbook + + - hosts: utility + vars_files: + - vars/main.yml + roles: + - geerlingguy.nodejs + +*Inside `vars/main.yml`*: + + nodejs_npm_global_packages: + - name: jslint + - name: node-sass + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.nodejs/defaults/main.yml b/provisioning/roles/geerlingguy.nodejs/defaults/main.yml new file mode 100644 index 000000000..54a8f32fb --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/defaults/main.yml @@ -0,0 +1,31 @@ +--- +# Set the version of Node.js to install ("12.x", "13.x", "14.x", "15.x", etc.). +# Version numbers from Nodesource: https://github.com/nodesource/distributions +nodejs_version: "14.x" + +# The user for whom the npm packages will be installed. +# nodejs_install_npm_user: username + +# The directory for global installations. +npm_config_prefix: "/usr/local/lib/npm" + +# Set to true to suppress the UID/GID switching when running package scripts. If +# set explicitly to false, then installing as a non-root user will fail. +npm_config_unsafe_perm: "false" + +# Define a list of global packages to be installed with NPM. +nodejs_npm_global_packages: [] +# # Install a specific version of a package. +# - name: jslint +# version: 0.9.3 +# # Install the latest stable release of a package. +# - name: node-sass +# # This shorthand syntax also works (same as previous example). +# - node-sass + +# The path of a package.json file used to install packages globally. +nodejs_package_json_path: "" + +# Whether or not /etc/profile.d/npm.sh (globa) must be generated. +# Set to false if you need to handle this manually with a per-user install. +nodejs_generate_etc_profile: "true" diff --git a/provisioning/roles/geerlingguy.nodejs/meta/main.yml b/provisioning/roles/geerlingguy.nodejs/meta/main.yml new file mode 100644 index 000000000..110fd78e0 --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/meta/main.yml @@ -0,0 +1,31 @@ +--- +dependencies: [] + +galaxy_info: + role_name: nodejs + author: geerlingguy + description: Node.js installation for Linux + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - 7 + - 8 + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - trusty + - xenial + - bionic + galaxy_tags: + - development + - web + - javascript + - js + - node + - npm + - nodejs diff --git a/provisioning/roles/geerlingguy.nodejs/molecule/default/converge.yml b/provisioning/roles/geerlingguy.nodejs/molecule/default/converge.yml new file mode 100644 index 000000000..d1d586322 --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/molecule/default/converge.yml @@ -0,0 +1,22 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + nodejs_install_npm_user: root + npm_config_prefix: /root/.npm-global + npm_config_unsafe_perm: "true" + nodejs_npm_global_packages: + - node-sass + - name: jslint + version: 0.12.0 + - name: yo + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.nodejs diff --git a/provisioning/roles/geerlingguy.nodejs/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.nodejs/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.nodejs/molecule/default/playbook-latest.yml b/provisioning/roles/geerlingguy.nodejs/molecule/default/playbook-latest.yml new file mode 100644 index 000000000..70d002cc5 --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/molecule/default/playbook-latest.yml @@ -0,0 +1,23 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + nodejs_version: "13.x" + nodejs_install_npm_user: root + npm_config_prefix: /root/.npm-global + npm_config_unsafe_perm: "true" + nodejs_npm_global_packages: + - slugify + - name: jslint + version: 0.12.0 + - name: yo + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.nodejs diff --git a/provisioning/roles/geerlingguy.nodejs/tasks/main.yml b/provisioning/roles/geerlingguy.nodejs/tasks/main.yml new file mode 100644 index 000000000..90afd6e16 --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/tasks/main.yml @@ -0,0 +1,44 @@ +--- +- import_tasks: setup-RedHat.yml + when: ansible_os_family == 'RedHat' + +- import_tasks: setup-Debian.yml + when: ansible_os_family == 'Debian' + +- name: Define nodejs_install_npm_user + set_fact: + nodejs_install_npm_user: "{{ ansible_user | default(lookup('env', 'USER')) }}" + when: nodejs_install_npm_user is not defined + +- name: Create npm global directory + file: + path: "{{ npm_config_prefix }}" + owner: "{{ nodejs_install_npm_user }}" + group: "{{ nodejs_install_npm_user }}" + state: directory + mode: 0755 + +- name: Add npm_config_prefix bin directory to global $PATH. + template: + src: npm.sh.j2 + dest: /etc/profile.d/npm.sh + mode: 0644 + when: nodejs_generate_etc_profile + +- name: Ensure npm global packages are installed. + npm: + name: "{{ item.name | default(item) }}" + version: "{{ item.version | default('latest') }}" + global: true + state: latest + environment: + NPM_CONFIG_PREFIX: "{{ npm_config_prefix }}" + NODE_PATH: "{{ npm_config_prefix }}/lib/node_modules" + NPM_CONFIG_UNSAFE_PERM: "{{ npm_config_unsafe_perm }}" + with_items: "{{ nodejs_npm_global_packages }}" + tags: ['skip_ansible_lint'] + +- name: Install packages defined in a given package.json. + npm: + path: "{{ nodejs_package_json_path }}" + when: nodejs_package_json_path is defined and nodejs_package_json_path diff --git a/provisioning/roles/geerlingguy.nodejs/tasks/setup-Debian.yml b/provisioning/roles/geerlingguy.nodejs/tasks/setup-Debian.yml new file mode 100644 index 000000000..442e134a3 --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/tasks/setup-Debian.yml @@ -0,0 +1,32 @@ +--- +- name: Ensure dependencies are present. + apt: + name: + - apt-transport-https + - gnupg2 + state: present + +- name: Add Nodesource apt key. + apt_key: + url: https://keyserver.ubuntu.com/pks/lookup?op=get&fingerprint=on&search=0x1655A0AB68576280 + id: "68576280" + state: present + +- name: Add NodeSource repositories for Node.js. + apt_repository: + repo: "{{ item }}" + state: present + with_items: + - "deb https://deb.nodesource.com/node_{{ nodejs_version }} {{ ansible_distribution_release }} main" + - "deb-src https://deb.nodesource.com/node_{{ nodejs_version }} {{ ansible_distribution_release }} main" + register: node_repo + +- name: Update apt cache if repo was added. + apt: update_cache=yes + when: node_repo.changed + tags: ['skip_ansible_lint'] + +- name: Ensure Node.js and npm are installed. + apt: + name: "nodejs={{ nodejs_version|regex_replace('x', '') }}*" + state: present diff --git a/provisioning/roles/geerlingguy.nodejs/tasks/setup-RedHat.yml b/provisioning/roles/geerlingguy.nodejs/tasks/setup-RedHat.yml new file mode 100644 index 000000000..e39771a4c --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/tasks/setup-RedHat.yml @@ -0,0 +1,42 @@ +--- +- name: Set up the Nodesource RPM directory. + set_fact: + nodejs_rhel_rpm_dir: "pub_{{ nodejs_version }}" + +- name: Import Nodesource RPM key (CentOS < 7). + rpm_key: + key: http://rpm.nodesource.com/pub/el/NODESOURCE-GPG-SIGNING-KEY-EL + state: present + when: ansible_distribution_major_version|int < 7 + +- name: Import Nodesource RPM key (CentOS 7+). + rpm_key: + key: https://rpm.nodesource.com/pub/el/NODESOURCE-GPG-SIGNING-KEY-EL + state: present + when: ansible_distribution_major_version|int >= 7 + +- name: Add Nodesource repositories for Node.js (CentOS < 7). + yum: + name: "http://rpm.nodesource.com/{{ nodejs_rhel_rpm_dir }}/el/{{ ansible_distribution_major_version }}/{{ ansible_architecture }}/nodesource-release-el{{ ansible_distribution_major_version }}-1.noarch.rpm" + state: present + when: ansible_distribution_major_version|int < 7 + +- name: Add Nodesource repositories for Node.js (CentOS 7+). + yum: + name: "https://rpm.nodesource.com/{{ nodejs_rhel_rpm_dir }}/el/{{ ansible_distribution_major_version }}/{{ ansible_architecture }}/nodesource-release-el{{ ansible_distribution_major_version }}-1.noarch.rpm" + state: present + when: ansible_distribution_major_version|int >= 7 + +- name: Ensure Node.js AppStream module is disabled (CentOS 8+). + command: yum module disable -y nodejs + args: + warn: false + register: module_disable + changed_when: "'Nothing to do.' not in module_disable.stdout" + when: ansible_distribution_major_version|int >= 8 + +- name: Ensure Node.js and npm are installed. + yum: + name: "nodejs-{{ nodejs_version|regex_replace('x', '') }}*" + state: present + enablerepo: nodesource diff --git a/provisioning/roles/geerlingguy.nodejs/templates/npm.sh.j2 b/provisioning/roles/geerlingguy.nodejs/templates/npm.sh.j2 new file mode 100644 index 000000000..aaeecee51 --- /dev/null +++ b/provisioning/roles/geerlingguy.nodejs/templates/npm.sh.j2 @@ -0,0 +1,3 @@ +export PATH=$PATH:{{ npm_config_prefix }}/bin +export NPM_CONFIG_PREFIX={{ npm_config_prefix }} +export NODE_PATH=$NODE_PATH:{{ npm_config_prefix }}/lib/node_modules diff --git a/provisioning/roles/geerlingguy.php-memcached/.gitignore b/provisioning/roles/geerlingguy.php-memcached/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.php-memcached/.travis.yml b/provisioning/roles/geerlingguy.php-memcached/.travis.yml new file mode 100644 index 000000000..f1d1693ab --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/.travis.yml @@ -0,0 +1,28 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: php-memcached + matrix: + - MOLECULE_DISTRO: centos7 + MOLECULE_DOCKER_COMMAND: /usr/lib/systemd/systemd + - MOLECULE_DISTRO: ubuntu1604 + +install: + # Install test dependencies. + - pip install molecule docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.php-memcached/LICENSE b/provisioning/roles/geerlingguy.php-memcached/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.php-memcached/README.md b/provisioning/roles/geerlingguy.php-memcached/README.md new file mode 100644 index 000000000..035eda6f8 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/README.md @@ -0,0 +1,39 @@ +# Ansible Role: PHP-Memcached + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-php-memcached.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-php-memcached) + +Installs PHP Memcached support on RedHat/CentOS/Debian/Ubuntu. + +## Requirements + +This role doesn't *explicitly* require Memcached to be installed, but if you don't have the daemon running somewhere (either on the same server, or somewhere else), this role won't be all that helpful. Check out `geerlingguy.memcached` for a simple role to install and configure Memcached (either on the same server, or separate servers). + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + php_enablerepo: "" + +(RedHat/CentOS only) If you have enabled any additional repositories (might I suggest geerlingguy.repo-epel or geerlingguy.repo-remi), those repositories can be listed under this variable (e.g. `remi,epel`). This can be handy, as an example, if you want to install the latest version of PHP from Remi's repository. + + php_memcached_package: php-memcached + +The package to install for PHP Memcached support. For Debian/Ubuntu and PHP 5.x, use `php5-memcached`. + +## Dependencies + + - geerlingguy.php + +## Example Playbook + + - hosts: webservers + roles: + - { role: geerlingguy.php-memcached } + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.php-memcached/defaults/main.yml b/provisioning/roles/geerlingguy.php-memcached/defaults/main.yml new file mode 100644 index 000000000..f6a43ca96 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/defaults/main.yml @@ -0,0 +1,3 @@ +--- +# Pass in a comma-separated list of repos to use (e.g. "remi,epel"). +php_enablerepo: "" diff --git a/provisioning/roles/geerlingguy.php-memcached/meta/main.yml b/provisioning/roles/geerlingguy.php-memcached/meta/main.yml new file mode 100644 index 000000000..8178ccadf --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/meta/main.yml @@ -0,0 +1,28 @@ +--- +dependencies: + - geerlingguy.php + +galaxy_info: + author: geerlingguy + description: PHP Memcached support for Linux + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 1.8 + platforms: + - name: EL + versions: + - 6 + - 7 + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + galaxy_tags: + - database + - web + - php + - memcached + - cache + - performance diff --git a/provisioning/roles/geerlingguy.php-memcached/molecule/default/memcached-test.php b/provisioning/roles/geerlingguy.php-memcached/molecule/default/memcached-test.php new file mode 100644 index 000000000..4d16d96ca --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/molecule/default/memcached-test.php @@ -0,0 +1,35 @@ +<?php + +/** + * @file + * Test if Memcached is available and working. + * + * Note that if you run this script more than once per second, the add() call + * will fail. Why would you run this more than once per second?! + */ + +$success = FALSE; +$key = 'test'; +$value = 'Success'; + +if (class_exists('Memcached')) { + $memcached = new Memcached; + $memcached->addServer('127.0.0.1', 11211); + + // Test adding a value to memcached. + if ($memcached->add($key, $value, 1)) { + $result = $memcached->get($key); + + // If we get the expected result, it was a success. + if ($result == $value) { + $success = TRUE; + print "Memcached connection successful.\r\n"; + exit(0); + } + } +} + +if (!$success) { + print "Memcached not working properly.\r\n"; + exit(1); +} diff --git a/provisioning/roles/geerlingguy.php-memcached/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.php-memcached/molecule/default/molecule.yml new file mode 100644 index 000000000..033970241 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/molecule/default/molecule.yml @@ -0,0 +1,27 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-file: molecule/default/yaml-lint.yml +platforms: + - name: instance + image: geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible + command: ${MOLECULE_DOCKER_COMMAND:-"sleep infinity"} + privileged: true + pre_build_image: true +provisioner: + name: ansible + lint: + name: ansible-lint + playbooks: + converge: ${MOLECULE_PLAYBOOK:-playbook.yml} +scenario: + name: default +verifier: + name: testinfra + lint: + name: flake8 diff --git a/provisioning/roles/geerlingguy.php-memcached/molecule/default/playbook.yml b/provisioning/roles/geerlingguy.php-memcached/molecule/default/playbook.yml new file mode 100644 index 000000000..b449f2fd0 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/molecule/default/playbook.yml @@ -0,0 +1,19 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + + roles: + - role: geerlingguy.memcached + - role: geerlingguy.php + - role: geerlingguy.php-memcached + + post_tasks: + - name: Run test script to confirm Memcached is reachable via PHP. + script: memcached-test.php + args: + executable: php + changed_when: false diff --git a/provisioning/roles/geerlingguy.php-memcached/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.php-memcached/molecule/default/requirements.yml new file mode 100644 index 000000000..5793141c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/molecule/default/requirements.yml @@ -0,0 +1,3 @@ +--- +- src: geerlingguy.memcached +- src: geerlingguy.php diff --git a/provisioning/roles/geerlingguy.php-memcached/molecule/default/tests/test_default.py b/provisioning/roles/geerlingguy.php-memcached/molecule/default/tests/test_default.py new file mode 100644 index 000000000..eedd64a1d --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/molecule/default/tests/test_default.py @@ -0,0 +1,14 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') + + +def test_hosts_file(host): + f = host.file('/etc/hosts') + + assert f.exists + assert f.user == 'root' + assert f.group == 'root' diff --git a/provisioning/roles/geerlingguy.php-memcached/molecule/default/yaml-lint.yml b/provisioning/roles/geerlingguy.php-memcached/molecule/default/yaml-lint.yml new file mode 100644 index 000000000..a3dbc38ee --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/molecule/default/yaml-lint.yml @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 120 + level: warning diff --git a/provisioning/roles/geerlingguy.php-memcached/tasks/main.yml b/provisioning/roles/geerlingguy.php-memcached/tasks/main.yml new file mode 100644 index 000000000..ec9dd36ef --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/tasks/main.yml @@ -0,0 +1,28 @@ +--- +# Include variables and define needed variables. +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define php_memcached_package. + set_fact: + php_memcached_package: "{{ __php_memcached_package }}" + when: php_memcached_package is not defined + +- name: Install PHP Memcached extension (RedHat). + yum: + name: "{{ php_memcached_package }}" + state: present + enablerepo: "{{ php_enablerepo | default(omit, true) }}" + notify: + - restart webserver + - restart php-fpm + when: ansible_os_family == 'RedHat' + +- name: Install PHP Memcached extension (Debian). + apt: + name: "{{ php_memcached_package }}" + state: present + notify: + - restart webserver + - restart php-fpm + when: ansible_os_family == 'Debian' diff --git a/provisioning/roles/geerlingguy.php-memcached/vars/Debian.yml b/provisioning/roles/geerlingguy.php-memcached/vars/Debian.yml new file mode 100644 index 000000000..456072e2f --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/vars/Debian.yml @@ -0,0 +1,2 @@ +--- +__php_memcached_package: php-memcached diff --git a/provisioning/roles/geerlingguy.php-memcached/vars/RedHat.yml b/provisioning/roles/geerlingguy.php-memcached/vars/RedHat.yml new file mode 100644 index 000000000..73c7bf134 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-memcached/vars/RedHat.yml @@ -0,0 +1,2 @@ +--- +__php_memcached_package: php-pecl-memcached diff --git a/provisioning/roles/geerlingguy.php-mysql/.github/FUNDING.yml b/provisioning/roles/geerlingguy.php-mysql/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.php-mysql/.github/stale.yml b/provisioning/roles/geerlingguy.php-mysql/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.php-mysql/.gitignore b/provisioning/roles/geerlingguy.php-mysql/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.php-mysql/.travis.yml b/provisioning/roles/geerlingguy.php-mysql/.travis.yml new file mode 100644 index 000000000..1b9f5922a --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/.travis.yml @@ -0,0 +1,28 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: php-mysql + matrix: + - MOLECULE_DISTRO: centos7 + - MOLECULE_DISTRO: ubuntu2004 + - MOLECULE_DISTRO: debian10 + +install: + # Install test dependencies. + - pip install molecule yamllint ansible-lint docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.php-mysql/.yamllint b/provisioning/roles/geerlingguy.php-mysql/.yamllint new file mode 100644 index 000000000..a3dbc38ee --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/.yamllint @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 120 + level: warning diff --git a/provisioning/roles/geerlingguy.php-mysql/LICENSE b/provisioning/roles/geerlingguy.php-mysql/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.php-mysql/README.md b/provisioning/roles/geerlingguy.php-mysql/README.md new file mode 100644 index 000000000..85d9e271c --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/README.md @@ -0,0 +1,40 @@ +# Ansible Role: PHP-MySQL + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-php-mysql.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-php-mysql) + +Installs PHP [MySQL](https://www.mysql.com/) support on Linux. + +## Requirements + +None. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + php_enablerepo: "" + +(RedHat/CentOS only) If you have enabled any additional repositories (might I suggest geerlingguy.repo-epel or geerlingguy.repo-remi), those repositories can be listed under this variable (e.g. `remi,epel`). This can allow you to install later versions of PHP packages. + + php_mysql_package: php-mysql # RedHat + php_mysql_package: php5-mysql # Debian + +The PHP MySQL package to install via apt/yum. This should only be overridden if you need to install a unique/special package for MySQL support, as in the case of using software collections on Enterprise Linux. + +## Dependencies + + - geerlingguy.php + +## Example Playbook + + - hosts: webservers + roles: + - { role: geerlingguy.php-mysql } + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.php-mysql/defaults/main.yml b/provisioning/roles/geerlingguy.php-mysql/defaults/main.yml new file mode 100644 index 000000000..f6a43ca96 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/defaults/main.yml @@ -0,0 +1,3 @@ +--- +# Pass in a comma-separated list of repos to use (e.g. "remi,epel"). +php_enablerepo: "" diff --git a/provisioning/roles/geerlingguy.php-mysql/meta/main.yml b/provisioning/roles/geerlingguy.php-mysql/meta/main.yml new file mode 100644 index 000000000..528a9d601 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/meta/main.yml @@ -0,0 +1,27 @@ +--- +dependencies: + - geerlingguy.php + +galaxy_info: + # See: https://github.com/ansible/galaxy/issues/2393 + # role_name: php-mysql + author: geerlingguy + description: PHP MySQL support for Linux. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + galaxy_tags: + - database + - web + - mysql + - php diff --git a/provisioning/roles/geerlingguy.php-mysql/molecule/default/converge.yml b/provisioning/roles/geerlingguy.php-mysql/molecule/default/converge.yml new file mode 100644 index 000000000..cd6c0b3b9 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/molecule/default/converge.yml @@ -0,0 +1,25 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enablerepo: "remi,remi-php72" + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.apache + - role: geerlingguy.mysql + - role: geerlingguy.php + - role: geerlingguy.php-mysql + + post_tasks: + - name: Make sure the PHP MySQL extension is present. + command: "php -i | grep 'mysqlnd => enabled'" + changed_when: false diff --git a/provisioning/roles/geerlingguy.php-mysql/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.php-mysql/molecule/default/molecule.yml new file mode 100644 index 000000000..2da47dd1f --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/molecule/default/molecule.yml @@ -0,0 +1,21 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: | + set -e + yamllint . + ansible-lint +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.php-mysql/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.php-mysql/molecule/default/requirements.yml new file mode 100644 index 000000000..d11269582 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/molecule/default/requirements.yml @@ -0,0 +1,5 @@ +--- +- src: geerlingguy.repo-remi +- src: geerlingguy.apache +- src: geerlingguy.mysql +- src: geerlingguy.php diff --git a/provisioning/roles/geerlingguy.php-mysql/tasks/main.yml b/provisioning/roles/geerlingguy.php-mysql/tasks/main.yml new file mode 100644 index 000000000..a389d1122 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/tasks/main.yml @@ -0,0 +1,29 @@ +--- +# Variable setup. +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define php_mysql_package. + set_fact: + php_mysql_package: "{{ __php_mysql_package }}" + when: php_mysql_package is not defined + +# Installation. +- name: Install PHP MySQL dependencies (RedHat). + yum: + name: "{{ php_mysql_package }}" + state: present + enablerepo: "{{ php_enablerepo | default(omit, true) }}" + notify: + - restart webserver + - restart php-fpm + when: ansible_os_family == 'RedHat' + +- name: Install PHP MySQL dependencies (Debian). + apt: + name: "{{ php_mysql_package }}" + state: present + notify: + - restart webserver + - restart php-fpm + when: ansible_os_family == 'Debian' diff --git a/provisioning/roles/geerlingguy.php-mysql/vars/Debian.yml b/provisioning/roles/geerlingguy.php-mysql/vars/Debian.yml new file mode 100644 index 000000000..96da86175 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/vars/Debian.yml @@ -0,0 +1,2 @@ +--- +__php_mysql_package: php{{ php_default_version_debian | default("7.4") }}-mysql diff --git a/provisioning/roles/geerlingguy.php-mysql/vars/RedHat.yml b/provisioning/roles/geerlingguy.php-mysql/vars/RedHat.yml new file mode 100644 index 000000000..d10126b4c --- /dev/null +++ b/provisioning/roles/geerlingguy.php-mysql/vars/RedHat.yml @@ -0,0 +1,2 @@ +--- +__php_mysql_package: php-mysql diff --git a/provisioning/roles/geerlingguy.php-pecl/.ansible-lint b/provisioning/roles/geerlingguy.php-pecl/.ansible-lint new file mode 100644 index 000000000..477856412 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/.ansible-lint @@ -0,0 +1,2 @@ +skip_list: + - '306' diff --git a/provisioning/roles/geerlingguy.php-pecl/.github/FUNDING.yml b/provisioning/roles/geerlingguy.php-pecl/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.php-pecl/.gitignore b/provisioning/roles/geerlingguy.php-pecl/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.php-pecl/.travis.yml b/provisioning/roles/geerlingguy.php-pecl/.travis.yml new file mode 100644 index 000000000..dee7ff6da --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/.travis.yml @@ -0,0 +1,28 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: php-pecl + matrix: + - MOLECULE_DISTRO: centos8 + - MOLECULE_DISTRO: ubuntu1804 + - MOLECULE_DISTRO: debian10 + +install: + # Install test dependencies. + - pip install molecule yamllint ansible-lint docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.php-pecl/.yamllint b/provisioning/roles/geerlingguy.php-pecl/.yamllint new file mode 100644 index 000000000..a3dbc38ee --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/.yamllint @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 120 + level: warning diff --git a/provisioning/roles/geerlingguy.php-pecl/LICENSE b/provisioning/roles/geerlingguy.php-pecl/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.php-pecl/README.md b/provisioning/roles/geerlingguy.php-pecl/README.md new file mode 100644 index 000000000..baf34e213 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/README.md @@ -0,0 +1,57 @@ +# Ansible Role: PHP PECL extensions + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-php-pecl.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-php-pecl) + +Installs PHP PECL extensions (and optionally `pecl` itself) on servers with PHP already installed. + +## Requirements + +PHP must already be installed on the server. This role works great with and is tested alongside `geerlingguy.php`. + +Also, if you don't already have `php-pear` (RedHat) or `php-pecl` (Debian) installed, you should set `php_pecl_install_pecl: true` to force this role to install the proper package. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + php_pecl_install_pecl: false + +Whether to install `php-pecl` (Debian-based OSes) or `php-pear` (RedHat-based OSes). + + php_pecl_install_command: "pecl install" + +The command that will be run to install extensions. The default is generally correct, but if you're running Ubuntu 14.04 LTS and run into [this issue](https://github.com/geerlingguy/ansible-role-php-pecl/pull/7), you should override this default with `"pecl install -Z"` + + php_pecl_extensions: [] + +A list of extensions that should be installed via `pecl install`. If you'd like to have this role install extensions like XDebug, just add it in the list, like so: + + php_pecl_extensions: + - redis + - xdebug + +## Dependencies + + - geerlingguy.php + +## Example Playbook + + - hosts: webservers + vars_files: + - vars/main.yml + roles: + - geerlingguy.php-pecl + +*Inside `vars/main.yml`*: + + php_pecl_extensions: + - redis + - xdebug + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.php-pecl/defaults/main.yml b/provisioning/roles/geerlingguy.php-pecl/defaults/main.yml new file mode 100644 index 000000000..f22442736 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/defaults/main.yml @@ -0,0 +1,8 @@ +--- +php_pecl_install_pecl: false + +php_pecl_install_command: "pecl install" + +# Add extensions to this list to have them installed with this role. +php_pecl_extensions: [] +# - xdebug diff --git a/provisioning/roles/geerlingguy.php-pecl/meta/main.yml b/provisioning/roles/geerlingguy.php-pecl/meta/main.yml new file mode 100644 index 000000000..f55cf64bd --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/meta/main.yml @@ -0,0 +1,46 @@ +--- +dependencies: + - geerlingguy.php + +galaxy_info: + author: geerlingguy + description: PHP PECL extension installation. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + - name: GenericUNIX + versions: + - all + - name: Fedora + versions: + - all + - name: opensuse + versions: + - all + - name: GenericBSD + versions: + - all + - name: FreeBSD + versions: + - all + - name: Ubuntu + versions: + - all + - name: SLES + versions: + - all + - name: GenericLinux + versions: + - all + - name: Debian + versions: + - all + galaxy_tags: + - development + - web + - php + - pecl diff --git a/provisioning/roles/geerlingguy.php-pecl/molecule/default/converge.yml b/provisioning/roles/geerlingguy.php-pecl/molecule/default/converge.yml new file mode 100644 index 000000000..f6e38e2b2 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/molecule/default/converge.yml @@ -0,0 +1,38 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + php_default_version_debian: "7.3" + php_pecl_install_pecl: true + php_pecl_extensions: + - redis + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + - name: Install development tools (Debian). + apt: name=build-essential state=present + when: ansible_os_family == 'Debian' + + - name: Install development tools (RedHat). + yum: name="@Development tools" state=present + when: ansible_os_family == 'RedHat' + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.php-versions + - role: geerlingguy.php + - role: geerlingguy.php-pecl + + post_tasks: + - name: Run test script to confirm Redis extension is available to PHP. + script: pecl-test.php + args: + executable: php + changed_when: false diff --git a/provisioning/roles/geerlingguy.php-pecl/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.php-pecl/molecule/default/molecule.yml new file mode 100644 index 000000000..2da47dd1f --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/molecule/default/molecule.yml @@ -0,0 +1,21 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: | + set -e + yamllint . + ansible-lint +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.php-pecl/molecule/default/pecl-test.php b/provisioning/roles/geerlingguy.php-pecl/molecule/default/pecl-test.php new file mode 100644 index 000000000..9bd5bf819 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/molecule/default/pecl-test.php @@ -0,0 +1,19 @@ +<?php + +/** + * @file + * Test if pecl/pear is available and working. + */ + +require_once 'System.php'; + +$success = FALSE; + +if (class_exists('System', false)) { + $success = TRUE; +} + +if (!$success) { + print "pecl/pear not found.\r\n"; + exit(1); +} \ No newline at end of file diff --git a/provisioning/roles/geerlingguy.php-pecl/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.php-pecl/molecule/default/requirements.yml new file mode 100644 index 000000000..908335edd --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/molecule/default/requirements.yml @@ -0,0 +1,4 @@ +--- +- src: geerlingguy.repo-remi +- src: geerlingguy.php-versions +- src: geerlingguy.php diff --git a/provisioning/roles/geerlingguy.php-pecl/tasks/main.yml b/provisioning/roles/geerlingguy.php-pecl/tasks/main.yml new file mode 100644 index 000000000..890a115c3 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/tasks/main.yml @@ -0,0 +1,20 @@ +--- +- name: Include OS-Specific variables. + include_vars: "{{ item }}" + with_first_found: + - "{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml" + - "{{ ansible_distribution }}.yml" + - "{{ ansible_os_family }}.yml" + +- name: Ensure pecl is installed (if configured). + package: + name: "{{ php_pecl_package }}" + state: present + when: php_pecl_install_pecl + +- name: Install PECL libaries. + shell: "yes '' | {{ php_pecl_install_command }} {{ item }}" + register: pecl_result + changed_when: pecl_result is succeeded + failed_when: "not (('already installed' in pecl_result.stdout) or ('install ok:' in pecl_result.stdout))" + with_items: "{{ php_pecl_extensions }}" diff --git a/provisioning/roles/geerlingguy.php-pecl/vars/Debian-8.yml b/provisioning/roles/geerlingguy.php-pecl/vars/Debian-8.yml new file mode 100644 index 000000000..47c282c72 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/vars/Debian-8.yml @@ -0,0 +1,2 @@ +--- +php_pecl_package: php-pecl diff --git a/provisioning/roles/geerlingguy.php-pecl/vars/Debian.yml b/provisioning/roles/geerlingguy.php-pecl/vars/Debian.yml new file mode 100644 index 000000000..fd71295b9 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/vars/Debian.yml @@ -0,0 +1,2 @@ +--- +php_pecl_package: php-pear diff --git a/provisioning/roles/geerlingguy.php-pecl/vars/RedHat.yml b/provisioning/roles/geerlingguy.php-pecl/vars/RedHat.yml new file mode 100644 index 000000000..fd71295b9 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/vars/RedHat.yml @@ -0,0 +1,2 @@ +--- +php_pecl_package: php-pear diff --git a/provisioning/roles/geerlingguy.php-pecl/vars/Ubuntu.yml b/provisioning/roles/geerlingguy.php-pecl/vars/Ubuntu.yml new file mode 100644 index 000000000..fd71295b9 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pecl/vars/Ubuntu.yml @@ -0,0 +1,2 @@ +--- +php_pecl_package: php-pear diff --git a/provisioning/roles/geerlingguy.php-pgsql/.gitignore b/provisioning/roles/geerlingguy.php-pgsql/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pgsql/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.php-pgsql/.travis.yml b/provisioning/roles/geerlingguy.php-pgsql/.travis.yml new file mode 100644 index 000000000..87abca118 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pgsql/.travis.yml @@ -0,0 +1,28 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: php-pgsql + matrix: + - MOLECULE_DISTRO: centos7 + MOLECULE_DOCKER_COMMAND: /usr/lib/systemd/systemd + - MOLECULE_DISTRO: ubuntu1604 + +install: + # Install test dependencies. + - pip install molecule docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.php-pgsql/LICENSE b/provisioning/roles/geerlingguy.php-pgsql/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pgsql/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.php-pgsql/README.md b/provisioning/roles/geerlingguy.php-pgsql/README.md new file mode 100644 index 000000000..4a8772ec3 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pgsql/README.md @@ -0,0 +1,42 @@ +# Ansible Role: PHP-PostgreSQL + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-php-pgsql.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-php-pgsql) + +Installs PHP [PostgreSQL](https://www.postgresql.org/) support on Linux. + +## Requirements + +None. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + php_enablerepo: "" + +(RedHat/CentOS only) If you have enabled any additional repositories (might I suggest geerlingguy.repo-epel or geerlingguy.repo-remi), those repositories can be listed under this variable (e.g. `remi,epel`). This can allow you to install later versions of PHP packages. + + php_pgsql_package: php-pgsql # RedHat + php_pgsql_package: php7.0-pgsql # Debian + +The PHP PostgreSQL package to install via apt/yum. This should only be overridden if you need to install a unique/special package for PostgreSQL support, as in the case of using software collections on Enterprise Linux. + +## Dependencies + + - geerlingguy.php + +## Example Playbook + + - hosts: webservers + roles: + - geerlingguy.postgresql + - geerlingguy.php + - geerlingguy.php-pgsql + +## License + +MIT / BSD + +## Author Information + +This role was created in 2016 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.php-pgsql/defaults/main.yml b/provisioning/roles/geerlingguy.php-pgsql/defaults/main.yml new file mode 100644 index 000000000..f6a43ca96 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pgsql/defaults/main.yml @@ -0,0 +1,3 @@ +--- +# Pass in a comma-separated list of repos to use (e.g. "remi,epel"). +php_enablerepo: "" diff --git a/provisioning/roles/geerlingguy.php-pgsql/meta/main.yml b/provisioning/roles/geerlingguy.php-pgsql/meta/main.yml new file mode 100644 index 000000000..9be9a595d --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pgsql/meta/main.yml @@ -0,0 +1,26 @@ +--- +dependencies: + - geerlingguy.php + +galaxy_info: + author: geerlingguy + description: PHP PostgreSQL support for Linux. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.0 + platforms: + - name: EL + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + galaxy_tags: + - database + - web + - postgres + - php + - pgsql diff --git a/provisioning/roles/geerlingguy.php-pgsql/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.php-pgsql/molecule/default/molecule.yml new file mode 100644 index 000000000..033970241 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pgsql/molecule/default/molecule.yml @@ -0,0 +1,27 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-file: molecule/default/yaml-lint.yml +platforms: + - name: instance + image: geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible + command: ${MOLECULE_DOCKER_COMMAND:-"sleep infinity"} + privileged: true + pre_build_image: true +provisioner: + name: ansible + lint: + name: ansible-lint + playbooks: + converge: ${MOLECULE_PLAYBOOK:-playbook.yml} +scenario: + name: default +verifier: + name: testinfra + lint: + name: flake8 diff --git a/provisioning/roles/geerlingguy.php-pgsql/molecule/default/playbook.yml b/provisioning/roles/geerlingguy.php-pgsql/molecule/default/playbook.yml new file mode 100644 index 000000000..96058e536 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pgsql/molecule/default/playbook.yml @@ -0,0 +1,25 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enablerepo: "remi,remi-php70" + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.apache + - role: geerlingguy.postgresql + - role: geerlingguy.php + - role: geerlingguy.php-pgsql + + post_tasks: + - name: Make sure PHP pgsql driver is enabled. + command: "php -i | grep 'PostgreSQL Support => enabled'" + changed_when: false diff --git a/provisioning/roles/geerlingguy.php-pgsql/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.php-pgsql/molecule/default/requirements.yml new file mode 100644 index 000000000..66c00dfec --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pgsql/molecule/default/requirements.yml @@ -0,0 +1,5 @@ +--- +- src: geerlingguy.repo-remi +- src: geerlingguy.apache +- src: geerlingguy.postgresql +- src: geerlingguy.php diff --git a/provisioning/roles/geerlingguy.php-pgsql/molecule/default/tests/test_default.py b/provisioning/roles/geerlingguy.php-pgsql/molecule/default/tests/test_default.py new file mode 100644 index 000000000..eedd64a1d --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pgsql/molecule/default/tests/test_default.py @@ -0,0 +1,14 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') + + +def test_hosts_file(host): + f = host.file('/etc/hosts') + + assert f.exists + assert f.user == 'root' + assert f.group == 'root' diff --git a/provisioning/roles/geerlingguy.php-pgsql/molecule/default/yaml-lint.yml b/provisioning/roles/geerlingguy.php-pgsql/molecule/default/yaml-lint.yml new file mode 100644 index 000000000..a3dbc38ee --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pgsql/molecule/default/yaml-lint.yml @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 120 + level: warning diff --git a/provisioning/roles/geerlingguy.php-pgsql/tasks/main.yml b/provisioning/roles/geerlingguy.php-pgsql/tasks/main.yml new file mode 100644 index 000000000..e35de3398 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pgsql/tasks/main.yml @@ -0,0 +1,29 @@ +--- +# Variable setup. +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define php_pgsql_package. + set_fact: + php_pgsql_package: "{{ __php_pgsql_package }}" + when: php_pgsql_package is not defined + +# Installation. +- name: Install PHP PostgreSQL dependencies (RedHat). + yum: + name: "{{ php_pgsql_package }}" + state: present + enablerepo: "{{ php_enablerepo | default(omit, true) }}" + notify: + - restart webserver + - restart php-fpm + when: ansible_os_family == 'RedHat' + +- name: Install PHP PostgreSQL dependencies (Debian). + apt: + name: "{{ php_pgsql_package }}" + state: present + notify: + - restart webserver + - restart php-fpm + when: ansible_os_family == 'Debian' diff --git a/provisioning/roles/geerlingguy.php-pgsql/vars/Debian.yml b/provisioning/roles/geerlingguy.php-pgsql/vars/Debian.yml new file mode 100644 index 000000000..aad287dc3 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pgsql/vars/Debian.yml @@ -0,0 +1,2 @@ +--- +__php_pgsql_package: php7.0-pgsql diff --git a/provisioning/roles/geerlingguy.php-pgsql/vars/RedHat.yml b/provisioning/roles/geerlingguy.php-pgsql/vars/RedHat.yml new file mode 100644 index 000000000..87f5c1ee2 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-pgsql/vars/RedHat.yml @@ -0,0 +1,2 @@ +--- +__php_pgsql_package: php-pgsql diff --git a/provisioning/roles/geerlingguy.php-redis/.gitignore b/provisioning/roles/geerlingguy.php-redis/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.php-redis/.travis.yml b/provisioning/roles/geerlingguy.php-redis/.travis.yml new file mode 100644 index 000000000..0b1fec17e --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/.travis.yml @@ -0,0 +1,28 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: php-redis + matrix: + - MOLECULE_DISTRO: centos7 + MOLECULE_DOCKER_COMMAND: /usr/lib/systemd/systemd + - MOLECULE_DISTRO: ubuntu1604 + +install: + # Install test dependencies. + - pip install molecule docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.php-redis/LICENSE b/provisioning/roles/geerlingguy.php-redis/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.php-redis/README.md b/provisioning/roles/geerlingguy.php-redis/README.md new file mode 100644 index 000000000..7ba22f9bf --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/README.md @@ -0,0 +1,63 @@ +# Ansible Role: PhpRedis + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-php-redis.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-php-redis) + +Installs PhpRedis support on Linux. + +## Requirements + +This role doesn't *explicitly* require Redis to be installed, but if you don't have the daemon running somewhere (either on the same server, or somewhere else), this role won't be all that helpful. Check out `geerlingguy.redis` for a simple role to install and configure Redis (either on the same server, or separate servers). + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + php_enablerepo: "" + +(RedHat/CentOS only) If you have enabled any additional repositories (might I suggest geerlingguy.repo-epel or geerlingguy.repo-remi), those repositories can be listed under this variable (e.g. `remi,epel`). This can be handy, as an example, if you want to install the latest version of PHP from Remi's repository. + + php_redis_package: php-redis + +(Default for Debian/Ubuntu shown). If installing from apt or yum, which package to install which provides the PhpRedis extension. (For PHP 5.x on Debian, this should be `php5-redis`). + +### Install from source + +If you want to install PhpRedis directly from source (if you're on an OS that doesn't have it available as a package, or if you want a newer version than is available through your package manager), you can use the variables below to configure the source installation: + + php_redis_install_from_source: false + +Whether to install PhpRedis from source. If you'd like to install a specific version of PhpRedis not available via the system package manager, you can compile the extension from source. + + php_redis_source_repo: https://github.com/phpredis/phpredis.git + +The git repository for the PhpRedis extension. + + php_redis_source_version: develop + +The branch, tag, or commit hash to use when cloning the source repository. Can be a branch (e.g. `develop` or `php7`), a tag (e.g. `2.2.7`), or a commit hash (e.g. `5241a5c`). + + php_redis_source_clone_dir: ~/phpredis + +The location where the PhpRedis source code will be cloned locally. + + php_redis_source_configure_command: "./configure" + +The command to configure a PhpRedis source install. You can modify this command if you want to do something like add `--enable-redis-igbinary`. + +## Dependencies + + - geerlingguy.php + +## Example Playbook + + - hosts: webservers + roles: + - { role: geerlingguy.php-redis } + +## License + +MIT / BSD + +## Author Information + +This role was created in 2015 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.php-redis/defaults/main.yml b/provisioning/roles/geerlingguy.php-redis/defaults/main.yml new file mode 100644 index 000000000..a561b7971 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/defaults/main.yml @@ -0,0 +1,10 @@ +--- +# Pass in a comma-separated list of repos to use (e.g. "remi,epel"). +php_enablerepo: "" + +# Whether to install the extension from source or from an apt or yum repo. +php_redis_install_from_source: false +php_redis_source_repo: https://github.com/phpredis/phpredis.git +php_redis_source_version: develop +php_redis_source_clone_dir: ~/phpredis +php_redis_source_configure_command: "./configure" diff --git a/provisioning/roles/geerlingguy.php-redis/files/redis.ini b/provisioning/roles/geerlingguy.php-redis/files/redis.ini new file mode 100644 index 000000000..6aecae489 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/files/redis.ini @@ -0,0 +1 @@ +extension=redis.so diff --git a/provisioning/roles/geerlingguy.php-redis/meta/main.yml b/provisioning/roles/geerlingguy.php-redis/meta/main.yml new file mode 100644 index 000000000..64f6132d1 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/meta/main.yml @@ -0,0 +1,29 @@ +--- +dependencies: + - geerlingguy.php + +galaxy_info: + author: geerlingguy + description: PhpRedis support for Linux + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - 6 + - 7 + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + galaxy_tags: + - database + - web + - php + - redis + - cache + - performance + - kv diff --git a/provisioning/roles/geerlingguy.php-redis/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.php-redis/molecule/default/molecule.yml new file mode 100644 index 000000000..033970241 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/molecule/default/molecule.yml @@ -0,0 +1,27 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-file: molecule/default/yaml-lint.yml +platforms: + - name: instance + image: geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible + command: ${MOLECULE_DOCKER_COMMAND:-"sleep infinity"} + privileged: true + pre_build_image: true +provisioner: + name: ansible + lint: + name: ansible-lint + playbooks: + converge: ${MOLECULE_PLAYBOOK:-playbook.yml} +scenario: + name: default +verifier: + name: testinfra + lint: + name: flake8 diff --git a/provisioning/roles/geerlingguy.php-redis/molecule/default/playbook.yml b/provisioning/roles/geerlingguy.php-redis/molecule/default/playbook.yml new file mode 100644 index 000000000..8fb28ad08 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/molecule/default/playbook.yml @@ -0,0 +1,27 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + php_enablerepo: "remi,remi-php70" + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.redis + - role: geerlingguy.php + - role: geerlingguy.php-redis + + post_tasks: + - name: Run test script to confirm Redis is reachable via PHP. + script: redis-test.php + args: + executable: php + changed_when: false diff --git a/provisioning/roles/geerlingguy.php-redis/molecule/default/redis-test.php b/provisioning/roles/geerlingguy.php-redis/molecule/default/redis-test.php new file mode 100644 index 000000000..b86c65aa9 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/molecule/default/redis-test.php @@ -0,0 +1,32 @@ +<?php + +/** + * @file + * Test if Redis is available and working. + */ + +$success = FALSE; +$key = 'test'; +$value = 'Success'; + +if (class_exists('Redis')) { + $redis = new Redis; + $redis->connect('127.0.0.1', 6379); + + // Test adding a value to redis. + if ($redis->set($key, $value)) { + $result = $redis->get($key); + + // If we get the expected result, it was a success. + if ($result == $value) { + $success = TRUE; + print "Redis connection successful.\r\n"; + exit(0); + } + } +} + +if (!$success) { + print "Redis not working properly.\r\n"; + exit(1); +} diff --git a/provisioning/roles/geerlingguy.php-redis/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.php-redis/molecule/default/requirements.yml new file mode 100644 index 000000000..414cad3c6 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/molecule/default/requirements.yml @@ -0,0 +1,4 @@ +--- +- src: geerlingguy.repo-remi +- src: geerlingguy.redis +- src: geerlingguy.php diff --git a/provisioning/roles/geerlingguy.php-redis/molecule/default/yaml-lint.yml b/provisioning/roles/geerlingguy.php-redis/molecule/default/yaml-lint.yml new file mode 100644 index 000000000..a3dbc38ee --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/molecule/default/yaml-lint.yml @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 120 + level: warning diff --git a/provisioning/roles/geerlingguy.php-redis/tasks/install-from-source.yml b/provisioning/roles/geerlingguy.php-redis/tasks/install-from-source.yml new file mode 100644 index 000000000..6243d0a80 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/tasks/install-from-source.yml @@ -0,0 +1,36 @@ +--- +- name: Clone the PhpRedis repo. + git: + repo: "{{ php_redis_source_repo }}" + dest: "{{ php_redis_source_clone_dir }}" + version: "{{ php_redis_source_version }}" + accept_hostkey: true + depth: 1 + +- name: Run phpize. + shell: > + phpize + chdir={{ php_redis_source_clone_dir }} + creates={{ php_extension_conf_paths[0] }}/redis.ini + +- name: Run configure script. + shell: > + {{ php_redis_source_configure_command }} + chdir={{ php_redis_source_clone_dir }} + creates={{ php_extension_conf_paths[0] }}/redis.ini + +- name: Make and install PHP. + shell: > + {{ item }} + chdir={{ php_redis_source_clone_dir }} + creates={{ php_extension_conf_paths[0] }}/redis.ini + with_items: + - make + - make install + +- name: Ensure the Redis extension is present in PHP's configuration. + copy: + src: redis.ini + dest: "{{ php_extension_conf_paths[0] }}/redis.ini" + mode: 0644 + notify: restart webserver diff --git a/provisioning/roles/geerlingguy.php-redis/tasks/main.yml b/provisioning/roles/geerlingguy.php-redis/tasks/main.yml new file mode 100644 index 000000000..2237b3f35 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/tasks/main.yml @@ -0,0 +1,35 @@ +--- +# Include variables and define needed variables. +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define php_redis_package. + set_fact: + php_redis_package: "{{ __php_redis_package }}" + when: php_redis_package is not defined + +# Install PhpRedis from the system package manager. +- name: Install PhpRedis extension (RedHat). + yum: + name: "{{ php_redis_package }}" + state: present + enablerepo: "{{ php_enablerepo | default(omit, true) }}" + notify: + - restart webserver + - restart php-fpm + when: + - php_redis_install_from_source == false + - ansible_os_family == 'RedHat' + +- name: Install PhpRedis extension (Debian). + apt: "name={{ php_redis_package }} state=present" + notify: + - restart webserver + - restart php-fpm + when: + - php_redis_install_from_source == false + - ansible_os_family == 'Debian' + +# Install PhpRedis from source. +- include_tasks: install-from-source.yml + when: php_redis_install_from_source == true diff --git a/provisioning/roles/geerlingguy.php-redis/vars/Debian.yml b/provisioning/roles/geerlingguy.php-redis/vars/Debian.yml new file mode 100644 index 000000000..db5f96108 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/vars/Debian.yml @@ -0,0 +1,2 @@ +--- +__php_redis_package: php-redis diff --git a/provisioning/roles/geerlingguy.php-redis/vars/RedHat.yml b/provisioning/roles/geerlingguy.php-redis/vars/RedHat.yml new file mode 100644 index 000000000..11c6873d7 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-redis/vars/RedHat.yml @@ -0,0 +1,2 @@ +--- +__php_redis_package: php-pecl-redis diff --git a/provisioning/roles/geerlingguy.php-tideways/.gitignore b/provisioning/roles/geerlingguy.php-tideways/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.php-tideways/.travis.yml b/provisioning/roles/geerlingguy.php-tideways/.travis.yml new file mode 100644 index 000000000..08fc4bb87 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/.travis.yml @@ -0,0 +1,28 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: php-tideways + matrix: + - MOLECULE_DISTRO: centos7 + - MOLECULE_DISTRO: ubuntu1804 + - MOLECULE_DISTRO: debian9 + +install: + # Install test dependencies. + - pip install molecule docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.php-tideways/LICENSE b/provisioning/roles/geerlingguy.php-tideways/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.php-tideways/README.md b/provisioning/roles/geerlingguy.php-tideways/README.md new file mode 100644 index 000000000..9538b4dbe --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/README.md @@ -0,0 +1,65 @@ +# Ansible Role: PHP-Tideways + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-php-tideways.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-php-tideways) + +Installs the [Tideways PHP Profile Extension](https://github.com/tideways/php-xhprof-extension) on Linux servers. + +## Requirements + +None. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + workspace: /root + +Where Tideways setup files will be downloaded and built. + + tideways_download_url: https://github.com/tideways/php-xhprof-extension/archive/master.zip + tideways_download_folder_name: php-xhprof-extension-master + +The URL from which Tideways will be downloaded, and the resulting folder into which it is downloaded. + + tideways_extension_name: tideways_xhprof.so + +The extension name for the Tideways PHP extension. + + tideways_api_key: '' + +If you use the Tideways UI, set this variable to your API key. Otherwise the extension can be used along with the XHProf UI to view profiles. + + tideways_install_xhprof_ui: true + +Tideways data-format is 100% compatible with XHProf so you can use the XHProf UI to browse profiles reports and the `XHProfRuns_Default` class to write the profile data to disk. If you use the Tideways UI, set this variable to `no`. + + xhprof_download_url: https://github.com/phacility/xhprof/archive/master.tar.gz + xhprof_download_folder_name: xhprof-master + +The URL from which XHProf will be downloaded. + + php_xhprof_lib_dir: /usr/share/php/xhprof_lib + +Directory where the XHProf PHP library is stored. + + php_xhprof_html_dir: /usr/share/php/xhprof_html + +Directory where the XHProf UI is stored. + +## Dependencies + + - geerlingguy.php + +## Example Playbook + + - hosts: webservers + roles: + - geerlingguy.php-tideways + +## License + +MIT / BSD + +## Author Information + +This role was created in 2017 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.php-tideways/defaults/main.yml b/provisioning/roles/geerlingguy.php-tideways/defaults/main.yml new file mode 100644 index 000000000..48eb57dd5 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/defaults/main.yml @@ -0,0 +1,19 @@ +--- +workspace: /root + +tideways_download_url: https://github.com/tideways/php-xhprof-extension/archive/master.zip +tideways_download_folder_name: php-xhprof-extension-master +tideways_extension_name: tideways_xhprof.so + +# If you use the Tideways UI, set this variable to your API key. Otherwise the +# extension can be used along with the XHProf UI to view profiles. +tideways_api_key: '' + +# XHProf UI +tideways_install_xhprof_ui: true + +__tideways_xhprof_download_url: https://github.com/phacility/xhprof/archive/master.tar.gz +__tideways_xhprof_download_folder_name: xhprof-master + +__php_xhprof_lib_dir: /usr/share/php/xhprof_lib +__php_xhprof_html_dir: /usr/share/php/xhprof_html diff --git a/provisioning/roles/geerlingguy.php-tideways/meta/main.yml b/provisioning/roles/geerlingguy.php-tideways/meta/main.yml new file mode 100644 index 000000000..7b47be1fe --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/meta/main.yml @@ -0,0 +1,50 @@ +--- +dependencies: + - geerlingguy.php + +galaxy_info: + author: geerlingguy + description: Tideways PHP Profiler Extension for Linux + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + - name: GenericUNIX + versions: + - all + - name: Fedora + versions: + - all + - name: opensuse + versions: + - all + - name: GenericBSD + versions: + - all + - name: FreeBSD + versions: + - all + - name: Ubuntu + versions: + - all + - name: SLES + versions: + - all + - name: GenericLinux + versions: + - all + - name: Debian + versions: + - all + galaxy_tags: + - development + - web + - php + - xhprof + - tideways + - profiler + - performance + - debug diff --git a/provisioning/roles/geerlingguy.php-tideways/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.php-tideways/molecule/default/molecule.yml new file mode 100644 index 000000000..2ca6feaf9 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/molecule/default/molecule.yml @@ -0,0 +1,29 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-file: molecule/default/yaml-lint.yml +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + lint: + name: ansible-lint + playbooks: + converge: ${MOLECULE_PLAYBOOK:-playbook.yml} +scenario: + name: default +verifier: + name: testinfra + lint: + name: flake8 diff --git a/provisioning/roles/geerlingguy.php-tideways/molecule/default/playbook.yml b/provisioning/roles/geerlingguy.php-tideways/molecule/default/playbook.yml new file mode 100644 index 000000000..81235ba01 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/molecule/default/playbook.yml @@ -0,0 +1,26 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.php-versions + - role: geerlingguy.php + - role: geerlingguy.php-tideways + + post_tasks: + - name: Run test script to confirm Tideways is working. + script: tideways-test.php + args: + executable: php + changed_when: false diff --git a/provisioning/roles/geerlingguy.php-tideways/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.php-tideways/molecule/default/requirements.yml new file mode 100644 index 000000000..908335edd --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/molecule/default/requirements.yml @@ -0,0 +1,4 @@ +--- +- src: geerlingguy.repo-remi +- src: geerlingguy.php-versions +- src: geerlingguy.php diff --git a/provisioning/roles/geerlingguy.php-tideways/molecule/default/tests/test_default.py b/provisioning/roles/geerlingguy.php-tideways/molecule/default/tests/test_default.py new file mode 100644 index 000000000..eedd64a1d --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/molecule/default/tests/test_default.py @@ -0,0 +1,14 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') + + +def test_hosts_file(host): + f = host.file('/etc/hosts') + + assert f.exists + assert f.user == 'root' + assert f.group == 'root' diff --git a/provisioning/roles/geerlingguy.php-tideways/molecule/default/tideways-test.php b/provisioning/roles/geerlingguy.php-tideways/molecule/default/tideways-test.php new file mode 100644 index 000000000..bb07fd589 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/molecule/default/tideways-test.php @@ -0,0 +1,50 @@ +<?php + +/** + * @file + * Test if Tideways is available and working. + */ + +$tideways_root_dir = '/usr/share/php'; +$xhprof_root_dir = '/usr/share/php'; +$success = TRUE; + +tideways_xhprof_enable(); +$data = tideways_xhprof_disable(); + +if (isset($data['main()==>tideways_xhprof_disable'])) { + print "Tideways profiling working.\r\n"; +} +else { + print "Tideways profiling not working.\r\n"; + $success = FALSE; +} + +include $xhprof_root_dir . '/xhprof_lib/utils/xhprof_lib.php'; +include $xhprof_root_dir . '/xhprof_lib/utils/xhprof_runs.php'; + +$output_dir = sys_get_temp_dir(); +$xhprof_runs = new XHProfRuns_Default($output_dir); +$run_id = $xhprof_runs->save_run($data, 'xhprof_testing'); +$filename = "$output_dir/$run_id.xhprof_testing.xhprof"; +if (file_exists($filename)) { + print "XHProf PHP library writing to output directory.\r\n"; +} +else { + print "XHProf PHP library not working.\r\n"; + $success = FALSE; +} +ob_start(); +include $xhprof_root_dir . '/xhprof_html/index.php'; +$html = ob_get_clean(); +if (strpos($html, "?run=$run_id") !== FALSE) { + print "XHProf UI working.\r\n"; +} +else { + print "XHProf UI not working.\r\n"; + $success = FALSE; +} + +if (!$success) { + exit(1); +} diff --git a/provisioning/roles/geerlingguy.php-tideways/molecule/default/yaml-lint.yml b/provisioning/roles/geerlingguy.php-tideways/molecule/default/yaml-lint.yml new file mode 100644 index 000000000..a3dbc38ee --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/molecule/default/yaml-lint.yml @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 120 + level: warning diff --git a/provisioning/roles/geerlingguy.php-tideways/tasks/configure.yml b/provisioning/roles/geerlingguy.php-tideways/tasks/configure.yml new file mode 100644 index 000000000..2b8700efb --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/tasks/configure.yml @@ -0,0 +1,18 @@ +--- +- name: Ensure PHP configuration directories exist. + file: + path: "{{ item }}" + state: directory + mode: 0755 + follow: true + with_items: "{{ php_extension_conf_paths }}" + +- name: Copy Tideways INI into various other conf folders. + template: + src: tideways.ini.j2 + dest: "{{ item }}/{{ php_tideways_config_filename }}" + owner: root + group: root + mode: 0644 + with_items: "{{ php_extension_conf_paths }}" + notify: restart webserver diff --git a/provisioning/roles/geerlingguy.php-tideways/tasks/main.yml b/provisioning/roles/geerlingguy.php-tideways/tasks/main.yml new file mode 100644 index 000000000..562fb8019 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/tasks/main.yml @@ -0,0 +1,63 @@ +--- +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define php_tideways_module_path. + set_fact: + php_tideways_module_path: "{{ __php_tideways_module_path }}" + when: php_tideways_module_path is not defined + +- name: Define php_tideways_config_filename. + set_fact: + php_tideways_config_filename: "{{ __php_tideways_config_filename }}" + when: php_tideways_config_filename is not defined + +# Setup/install tasks. +- name: Ensure dependencies for installing Tideways are present. + package: "name={{ item }} state=present" + with_items: + - make + - gcc + - unzip + +- name: Download and untar Tideways. + unarchive: + src: "{{ tideways_download_url }}" + dest: "{{ workspace }}" + copy: false + creates: "{{ workspace }}/{{ tideways_download_folder_name }}" + +- name: Build Tideways. + command: > + {{ item }} + chdir={{ workspace }}/{{ tideways_download_folder_name }} + creates={{ workspace }}/{{ tideways_download_folder_name }}/modules/{{ tideways_extension_name }} + with_items: + - phpize + - ./configure + - make + - make install + notify: restart webserver + +- name: Ensure Tideways module path exists. + file: + path: "{{ php_tideways_module_path }}" + state: directory + owner: root + group: root + mode: 0755 + +- name: Move Tideways module into place. + command: > + cp {{ workspace }}/{{ tideways_download_folder_name }}/modules/{{ tideways_extension_name }} + {{ php_tideways_module_path }}/{{ tideways_extension_name }} + creates={{ php_tideways_module_path }}/{{ tideways_extension_name }} + notify: restart webserver + +# TODO - Install the Tideways.php file for UI? +# $ php -r 'echo ini_get("extension_dir")."\n";' +# $ cp Tideways.php /path/to/php/lib + +- include_tasks: configure.yml +- include_tasks: xhprof.yml + when: tideways_install_xhprof_ui diff --git a/provisioning/roles/geerlingguy.php-tideways/tasks/xhprof.yml b/provisioning/roles/geerlingguy.php-tideways/tasks/xhprof.yml new file mode 100644 index 000000000..c713dc220 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/tasks/xhprof.yml @@ -0,0 +1,44 @@ +--- +- name: Define xhprof_download_url. + set_fact: + xhprof_download_url: "{{ __tideways_xhprof_download_url }}" + when: xhprof_download_url is not defined + +- name: Define xhprof_download_folder_name. + set_fact: + xhprof_download_folder_name: "{{ __tideways_xhprof_download_folder_name }}" + when: xhprof_download_folder_name is not defined + +- name: Define php_xhprof_lib_dir. + set_fact: + php_xhprof_lib_dir: "{{ __php_xhprof_lib_dir }}" + when: php_xhprof_lib_dir is not defined + +- name: Define php_xhprof_html_dir. + set_fact: + php_xhprof_html_dir: "{{ __php_xhprof_html_dir }}" + when: php_xhprof_html_dir is not defined + +- name: Ensure dependencies for the XHProf UI are present. + package: "name={{ item }} state=present" + with_items: + - graphviz + +- name: Download and untar XHProf. + unarchive: + src: "{{ xhprof_download_url }}" + dest: "{{ workspace }}" + copy: false + creates: "{{ workspace }}/{{ xhprof_download_folder_name }}" + +- name: Move XHProf PHP library into place. + shell: > + cp -r {{ workspace }}/{{ xhprof_download_folder_name }}/xhprof_lib {{ php_xhprof_lib_dir }} + creates={{ php_xhprof_lib_dir }}/utils/xhprof_lib.php + +- name: Move XHProf UI into place. + shell: > + cp -r {{ workspace }}/{{ xhprof_download_folder_name }}/xhprof_html {{ php_xhprof_html_dir }} + creates={{ php_xhprof_html_dir }}/index.php + +- include_tasks: configure.yml diff --git a/provisioning/roles/geerlingguy.php-tideways/templates/tideways.ini.j2 b/provisioning/roles/geerlingguy.php-tideways/templates/tideways.ini.j2 new file mode 100644 index 000000000..4d6d23335 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/templates/tideways.ini.j2 @@ -0,0 +1,7 @@ +[tideways] +extension="{{ php_tideways_module_path }}/{{ tideways_extension_name }}" +{% if tideways_api_key %} +tideways.api_key={{ tideways_api_key }} +{% else %} +tideways.auto_prepend_library=0 +{% endif %} diff --git a/provisioning/roles/geerlingguy.php-tideways/vars/Debian.yml b/provisioning/roles/geerlingguy.php-tideways/vars/Debian.yml new file mode 100644 index 000000000..ce91a6ebb --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/vars/Debian.yml @@ -0,0 +1,3 @@ +--- +__php_tideways_module_path: /usr/lib/php7.0/modules +__php_tideways_config_filename: 20-tideways.ini diff --git a/provisioning/roles/geerlingguy.php-tideways/vars/RedHat.yml b/provisioning/roles/geerlingguy.php-tideways/vars/RedHat.yml new file mode 100644 index 000000000..8952e984c --- /dev/null +++ b/provisioning/roles/geerlingguy.php-tideways/vars/RedHat.yml @@ -0,0 +1,3 @@ +--- +__php_tideways_module_path: /usr/lib64/php/modules +__php_tideways_config_filename: tideways.ini diff --git a/provisioning/roles/geerlingguy.php-versions/.ansible-lint b/provisioning/roles/geerlingguy.php-versions/.ansible-lint new file mode 100644 index 000000000..8d58b475f --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/.ansible-lint @@ -0,0 +1,5 @@ +skip_list: + - 'yaml' + - 'risky-shell-pipe' + - 'no-handler' + - 'role-name' diff --git a/provisioning/roles/geerlingguy.php-versions/.github/FUNDING.yml b/provisioning/roles/geerlingguy.php-versions/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.php-versions/.github/stale.yml b/provisioning/roles/geerlingguy.php-versions/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.php-versions/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.php-versions/.github/workflows/ci.yml new file mode 100644 index 000000000..24f8d52db --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/.github/workflows/ci.yml @@ -0,0 +1,90 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "30 6 * * 4" + +defaults: + run: + working-directory: 'geerlingguy.php-versions' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.php-versions' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + include: + # Default PHP version (7.4). + - distro: centos8 + playbook: converge.yml + - distro: centos7 + playbook: converge.yml + - distro: ubuntu1804 + playbook: converge.yml + - distro: debian10 + playbook: converge.yml + + # PHP 8.0. + - distro: centos8 + playbook: 8.0.yml + - distro: ubuntu1804 + playbook: 8.0.yml + - distro: debian10 + playbook: 8.0.yml + + # PHP 7.3. + - distro: centos8 + playbook: 7.3.yml + - distro: ubuntu1804 + playbook: 7.3.yml + - distro: debian10 + playbook: 7.3.yml + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.php-versions' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} + MOLECULE_PLAYBOOK: ${{ matrix.playbook }} diff --git a/provisioning/roles/geerlingguy.php-versions/.github/workflows/release.yml b/provisioning/roles/geerlingguy.php-versions/.github/workflows/release.yml new file mode 100644 index 000000000..14cdf926e --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.php-versions' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.php-versions' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.php-versions/.gitignore b/provisioning/roles/geerlingguy.php-versions/.gitignore new file mode 100644 index 000000000..a8b42eb6e --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/.gitignore @@ -0,0 +1 @@ +*.retry diff --git a/provisioning/roles/geerlingguy.php-versions/.yamllint b/provisioning/roles/geerlingguy.php-versions/.yamllint new file mode 100644 index 000000000..76a383c6a --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/.yamllint @@ -0,0 +1,10 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml diff --git a/provisioning/roles/geerlingguy.php-versions/LICENSE b/provisioning/roles/geerlingguy.php-versions/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.php-versions/README.md b/provisioning/roles/geerlingguy.php-versions/README.md new file mode 100644 index 000000000..45274e4d1 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/README.md @@ -0,0 +1,48 @@ +# Ansible Role: PHP Versions + +[![CI](https://github.com/geerlingguy/ansible-role-php-versions/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-php-versions/actions?query=workflow%3ACI) + +Allows different PHP versions to be installed when using the `geerlingguy.php` role (or a similar role). This role was originally built for [Drupal VM](https://www.drupalvm.com) but was released more generically so others could use an easier mechanism for switching PHP versions. + +## Requirements + +N/A + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + php_version: '7.4' + +The PHP version to be installed. Any [currently-supported PHP major version](http://php.net/supported-versions.php) is a valid option (e.g. `7.3`, `7.4`, or `8.0`). + + php_versions_install_recommends: false + +(For Debian OSes only) Whether to install recommended packages. This is set to `no` by default because setting it to `yes` often leads to multiple PHP versions being installed (thus making a bit of a mess) when using repos like Ondrej's PHP PPA for Ubuntu. + +## Dependencies + + - geerlingguy.php is a soft dependency as the `php_version` variable is required to be set. + - geerlingguy.repo-remi, if you're using CentOS or a Red Hat derivative. + +## Example Playbook + + - hosts: webservers + become: true + + vars: + php_version: '7.4' + + roles: + - name: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - geerlingguy.php-versions + - geerlingguy.php + +## License + +MIT / BSD + +## Author Information + +This role was created in 2017 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.php-versions/defaults/main.yml b/provisioning/roles/geerlingguy.php-versions/defaults/main.yml new file mode 100644 index 000000000..14647c068 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/defaults/main.yml @@ -0,0 +1,6 @@ +--- +# The PHP version to be installed. +php_version: '7.4' + +# For Debian OSes only. +php_versions_install_recommends: false diff --git a/provisioning/roles/geerlingguy.php-versions/meta/main.yml b/provisioning/roles/geerlingguy.php-versions/meta/main.yml new file mode 100644 index 000000000..79132db29 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/meta/main.yml @@ -0,0 +1,30 @@ +--- +dependencies: [] + +galaxy_info: + role_name: php-versions + author: geerlingguy + description: Allows different PHP versions to be installed. + company: "Midwestern Mac, LLC" + license: "MIT" + issue_tracker_url: https://github.com/geerlingguy/ansible-role-php-versions/issues + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - trusty + - xenial + - bionic + galaxy_tags: + - php + - web + - drupal + - vm + - magento + - wordpress diff --git a/provisioning/roles/geerlingguy.php-versions/molecule/default/7.3.yml b/provisioning/roles/geerlingguy.php-versions/molecule/default/7.3.yml new file mode 100644 index 000000000..e6e55ca59 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/molecule/default/7.3.yml @@ -0,0 +1,24 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + php_version: '7.3' + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.php-versions + - role: geerlingguy.php + + post_tasks: + - name: Confirm PHP version is correct. + shell: php -v | grep -F '{{ php_version }}' + changed_when: false diff --git a/provisioning/roles/geerlingguy.php-versions/molecule/default/8.0.yml b/provisioning/roles/geerlingguy.php-versions/molecule/default/8.0.yml new file mode 100644 index 000000000..ca9c75551 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/molecule/default/8.0.yml @@ -0,0 +1,24 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + php_version: '8.0' + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.php-versions + - role: geerlingguy.php + + post_tasks: + - name: Confirm PHP version is correct. + shell: php -v | grep -F '{{ php_version }}' + changed_when: false diff --git a/provisioning/roles/geerlingguy.php-versions/molecule/default/converge.yml b/provisioning/roles/geerlingguy.php-versions/molecule/default/converge.yml new file mode 100644 index 000000000..ab338668e --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/molecule/default/converge.yml @@ -0,0 +1,23 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.php-versions + - role: geerlingguy.php + + post_tasks: + - name: Confirm PHP version is correct. + shell: php -v | grep -F '{{ php_version }}' + changed_when: false diff --git a/provisioning/roles/geerlingguy.php-versions/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.php-versions/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.php-versions/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.php-versions/molecule/default/requirements.yml new file mode 100644 index 000000000..80e765f13 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/molecule/default/requirements.yml @@ -0,0 +1,3 @@ +--- +- src: geerlingguy.repo-remi +- src: geerlingguy.php diff --git a/provisioning/roles/geerlingguy.php-versions/tasks/main.yml b/provisioning/roles/geerlingguy.php-versions/tasks/main.yml new file mode 100644 index 000000000..df5b84b0b --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/tasks/main.yml @@ -0,0 +1,41 @@ +--- +- name: Include OS-specific variables. + include_vars: "{{ item }}" + with_fileglob: + - "{{ role_path }}/vars/{{ ansible_os_family }}.yml" + - "{{ role_path }}/vars/{{ ansible_os_family }}-php{{ php_version }}.yml" + +- name: Remove missing JSON extension for PHP 8.0 (included by default) + set_fact: + __php_packages: "{{ __php_packages | reject('search','php' + php_version + '-json') | list }}" + when: + - __php_packages is defined + - php_version is version('8.0', '>=') + +- name: Define PHP variables. + set_fact: "{{ item.key }}={{ lookup('vars', item.value) }}" + when: + - vars[item.key] is undefined + - vars[item.value] is defined + with_dict: + php_conf_paths: __php_conf_paths + php_extension_conf_paths: __php_extension_conf_paths + php_fpm_daemon: __php_fpm_daemon + php_fpm_conf_path: __php_fpm_conf_path + php_fpm_pool_conf_path: __php_fpm_pool_conf_path + php_mysql_package: __php_mysql_package + php_redis_package: __php_redis_package + php_memcached_package: __php_memcached_package + php_pgsql_package: __php_pgsql_package + php_tideways_module_path: __php_tideways_module_path + php_uploadprogress_module_path: __php_uploadprogress_module_path + php_xdebug_module_path: __php_xdebug_module_path + php_xhprof_module_path: __php_xhprof_module_path + php_packages: __php_packages + +- name: Define php_install_recommends variable. + set_fact: + php_install_recommends: "{{ php_versions_install_recommends }}" + +# Setup tasks. +- include_tasks: "setup-{{ ansible_os_family }}.yml" diff --git a/provisioning/roles/geerlingguy.php-versions/tasks/setup-Debian.yml b/provisioning/roles/geerlingguy.php-versions/tasks/setup-Debian.yml new file mode 100644 index 000000000..cfd093eb6 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/tasks/setup-Debian.yml @@ -0,0 +1,59 @@ +--- +- name: Set the correct opcache filename (Ubuntu/Debian). + set_fact: + php_opcache_conf_filename: "10-opcache.ini" + +- name: Ensure dirmngr is installed (gnupg dependency). + apt: + name: dirmngr + state: present + +- name: Add repository for PHP versions (Ubuntu). + apt_repository: repo='ppa:ondrej/php' + when: ansible_distribution == "Ubuntu" + +# Debian-specific tasks. +- name: Add dependencies for PHP versions (Debian). + apt: + name: + - apt-transport-https + - ca-certificates + state: present + when: ansible_distribution == "Debian" + +- name: Add Ondrej Sury's apt key (Debian). + apt_key: + url: https://packages.sury.org/php/apt.gpg + id: 15058500A0235D97F5D10063B188E2B695BD4743 + state: present + when: ansible_distribution == "Debian" + +- name: Add Ondrej Sury's repo (Debian). + apt_repository: + repo: "deb https://packages.sury.org/php/ {{ ansible_distribution_release }} main" + state: present + register: php_ondrej_debian_repo + when: ansible_distribution == "Debian" + +- name: Update apt caches after repo is added (Debian). + apt: update_cache=true + when: + - php_ondrej_debian_repo.changed + - ansible_distribution == "Debian" + tags: ['skip_ansible_lint'] + +- name: Purge PHP version packages (besides the currently chosen php_version). + apt: + name: "{{ php_versions_debian | reject('search', 'php' ~ php_version) | list }}" + state: absent + purge: true + force: true + register: php_version_purge + +- name: Also purge php-common package if any versions were just purged. + apt: + name: php-common + state: absent + purge: true + force: true + when: php_version_purge.changed | bool diff --git a/provisioning/roles/geerlingguy.php-versions/tasks/setup-RedHat.yml b/provisioning/roles/geerlingguy.php-versions/tasks/setup-RedHat.yml new file mode 100644 index 000000000..c20f0025a --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/tasks/setup-RedHat.yml @@ -0,0 +1,39 @@ +--- +# TODO: PHP 7.2 support will be removed soon. This is only being left in here as +# a convenience for legacy PHP 7.2 users. +- name: Enable remi repo for PHP 7.2. + set_fact: php_enablerepo="remi,remi-php72" + when: php_version == "7.2" + +- name: Enable remi repo for PHP 7.3. + set_fact: php_enablerepo="remi,remi-php73" + when: php_version == "7.3" + +- name: Enable remi repo for PHP 7.4. + set_fact: php_enablerepo="remi,remi-php74" + when: php_version == "7.4" + +- name: Enable remi repo for PHP 8.0. + set_fact: php_enablerepo="remi,remi-php80" + when: php_version == "8.0" + +# See: https://github.com/ansible/ansible/issues/64852 +- block: + + - name: Ensure dnf-plugins are installed on CentOS 8+. + yum: + name: dnf-plugins-core + state: present + + - name: Enable DNF module for CentOS 8+. + shell: | + dnf config-manager --set-enabled powertools + dnf module enable -y php:remi-{{ php_version }} + args: + warn: false + register: dnf_module_enable + changed_when: "'Nothing to do' not in dnf_module_enable.stdout" + + when: + - ansible_os_family == 'RedHat' + - ansible_distribution_major_version | int >= 8 diff --git a/provisioning/roles/geerlingguy.php-versions/vars/Debian.yml b/provisioning/roles/geerlingguy.php-versions/vars/Debian.yml new file mode 100644 index 000000000..bcaee60a1 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/vars/Debian.yml @@ -0,0 +1,47 @@ +--- +# Configure PHP paths and packages. +__php_conf_paths: + - "/etc/php/{{ php_version }}/fpm" + - "/etc/php/{{ php_version }}/apache2" + - "/etc/php/{{ php_version }}/cli" +__php_extension_conf_paths: + - "/etc/php/{{ php_version }}/fpm/conf.d" + - "/etc/php/{{ php_version }}/apache2/conf.d" + - "/etc/php/{{ php_version }}/cli/conf.d" +__php_fpm_daemon: "php{{ php_version }}-fpm" +__php_fpm_conf_path: "/etc/php/{{ php_version }}/fpm" +__php_fpm_pool_conf_path: "{{ __php_fpm_conf_path }}/pool.d/www.conf" +__php_mysql_package: "php{{ php_version }}-mysql" +__php_redis_package: "php{{ php_version }}-redis" +__php_memcached_package: "php{{ php_version }}-memcached" +__php_pgsql_package: "php{{ php_version }}-pgsql" + +__php_tideways_module_path: "/usr/lib/php/{{ php_version }}/modules" +__php_uploadprogress_module_path: "/usr/lib/php/{{ php_version }}/modules" +__php_xdebug_module_path: "/usr/lib/php/{{ php_version }}/modules" +__php_xhprof_module_path: "/usr/lib/php/{{ php_version }}/modules" + +__php_packages: + - "php{{ php_version }}" + - "php{{ php_version }}-apcu" + - "php{{ php_version }}-cli" + - "php{{ php_version }}-common" + - "php{{ php_version }}-curl" + - "php{{ php_version }}-dev" + - "php{{ php_version }}-fpm" + - "php{{ php_version }}-gd" + - "php{{ php_version }}-imap" + - "php{{ php_version }}-json" + - "php{{ php_version }}-mbstring" + - "php{{ php_version }}-opcache" + - "php{{ php_version }}-sqlite3" + - "php{{ php_version }}-xml" + - "php{{ php_version }}-yaml" + +php_versions_debian: + # TODO: PHP 7.2 support will be removed soon. This is only being left in here as + # a convenience for legacy PHP 7.2 users. + - php7.2-common + - php7.3-common + - php7.4-common + - php8.0-common diff --git a/provisioning/roles/geerlingguy.php-versions/vars/RedHat.yml b/provisioning/roles/geerlingguy.php-versions/vars/RedHat.yml new file mode 100644 index 000000000..568eaf60f --- /dev/null +++ b/provisioning/roles/geerlingguy.php-versions/vars/RedHat.yml @@ -0,0 +1,5 @@ +--- +__php_tideways_module_path: "/usr/lib64/php{{ php_version }}/modules" +__php_uploadprogress_module_path: "/usr/lib64/php{{ php_version }}/modules" +__php_xdebug_module_path: "/usr/lib64/php{{ php_version }}/modules" +__php_xhprof_module_path: "/usr/lib64/php{{ php_version }}/modules" diff --git a/provisioning/roles/geerlingguy.php-xdebug/.gitignore b/provisioning/roles/geerlingguy.php-xdebug/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.php-xdebug/.travis.yml b/provisioning/roles/geerlingguy.php-xdebug/.travis.yml new file mode 100644 index 000000000..05a66571b --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/.travis.yml @@ -0,0 +1,28 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: php-xdebug + matrix: + - MOLECULE_DISTRO: centos8 + - MOLECULE_DISTRO: ubuntu1804 + - MOLECULE_DISTRO: debian10 + +install: + # Install test dependencies. + - pip install molecule docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.php-xdebug/LICENSE b/provisioning/roles/geerlingguy.php-xdebug/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.php-xdebug/README.md b/provisioning/roles/geerlingguy.php-xdebug/README.md new file mode 100644 index 000000000..735585baf --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/README.md @@ -0,0 +1,77 @@ +# Ansible Role: PHP-XDebug + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-php-xdebug.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-php-xdebug) + +Installs PHP [XDebug](http://xdebug.org/) on Linux servers. + +## Requirements + +Prior to running this role, make sure the `php-devel` and `@Development Tools` (for RHEL/CentOS) or `php5-dev` + `build-essential` packages (for Debian/Ubuntu) are present on the system, as they are required for the build of Xdebug. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + workspace: /root + +Where Xdebug setup files will be downloaded and built. + + php_xdebug_version: 2.9.0 + +The version of Xdebug to be installed (see [Updates](https://xdebug.org/updates.php) for a current listing). + + php_xdebug_default_enable: 1 + php_xdebug_coverage_enable: 1 + +Whether to enable XDebug coverage and default exception handling or not. Disable these for slightly improved PHP performance, enable these to use XDebug to the fullest extent. + + php_xdebug_module_path: /usr/lib64/php/modules + +The path where `xdebug.so` will be installed. + + php_xdebug_remote_enable: "false" + +Whether remote debugging is enabled. + + php_xdebug_remote_connect_back: "false" + +If this is set to true, Xdebug will respond to any request from any IP address; use only for local development on non-public installations! + + php_xdebug_remote_host: localhost + php_xdebug_remote_port: "9000" + +The host and port on which Xdebug will listen. + + php_xdebug_remote_log: /tmp/xdebug.log + +The location of the xdebug log (useful if you're having trouble connecting). + + php_xdebug_idekey: sublime.xdebug + +The IDE key to use in the URL when making Xdebug requests (e.g. `http://example.local/?XDEBUG_SESSION_START=sublime.xdebug`). + + php_xdebug_max_nesting_level: 256 + +The maximimum function nesting level before Xdebug bails and throws a fatal exception. + + php_xdebug_cli_disable: false + +(Debian/Ubuntu ONLY) Disable xdebug for the CLI SAPI. + +## Dependencies + + - geerlingguy.php + +## Example Playbook + + - hosts: webservers + roles: + - { role: geerlingguy.php-xdebug } + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](http://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.php-xdebug/defaults/main.yml b/provisioning/roles/geerlingguy.php-xdebug/defaults/main.yml new file mode 100644 index 000000000..0b7028551 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/defaults/main.yml @@ -0,0 +1,21 @@ +--- +workspace: /root + +php_xdebug_version: 2.9.0 + +php_xdebug_coverage_enable: 1 +php_xdebug_default_enable: 1 + +php_xdebug_remote_enable: "false" +php_xdebug_remote_connect_back: "false" +php_xdebug_remote_host: localhost +php_xdebug_remote_port: "9000" +php_xdebug_remote_log: /tmp/xdebug.log +php_xdebug_remote_autostart: "false" + +php_xdebug_idekey: sublime.xdebug + +php_xdebug_max_nesting_level: 256 + +# Only used on Debian/Ubuntu. +php_xdebug_cli_disable: false diff --git a/provisioning/roles/geerlingguy.php-xdebug/meta/main.yml b/provisioning/roles/geerlingguy.php-xdebug/meta/main.yml new file mode 100644 index 000000000..9b43d070f --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/meta/main.yml @@ -0,0 +1,48 @@ +--- +dependencies: + - geerlingguy.php + +galaxy_info: + author: geerlingguy + description: PHP XDebug for Linux + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + - name: GenericUNIX + versions: + - all + - name: Fedora + versions: + - all + - name: opensuse + versions: + - all + - name: GenericBSD + versions: + - all + - name: FreeBSD + versions: + - all + - name: Ubuntu + versions: + - all + - name: SLES + versions: + - all + - name: GenericLinux + versions: + - all + - name: Debian + versions: + - all + galaxy_tags: + - development + - web + - php + - xdebug + - debug + - profile diff --git a/provisioning/roles/geerlingguy.php-xdebug/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.php-xdebug/molecule/default/molecule.yml new file mode 100644 index 000000000..2ca6feaf9 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/molecule/default/molecule.yml @@ -0,0 +1,29 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-file: molecule/default/yaml-lint.yml +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + lint: + name: ansible-lint + playbooks: + converge: ${MOLECULE_PLAYBOOK:-playbook.yml} +scenario: + name: default +verifier: + name: testinfra + lint: + name: flake8 diff --git a/provisioning/roles/geerlingguy.php-xdebug/molecule/default/playbook.yml b/provisioning/roles/geerlingguy.php-xdebug/molecule/default/playbook.yml new file mode 100644 index 000000000..faf6b0152 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/molecule/default/playbook.yml @@ -0,0 +1,26 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.php-versions + - role: geerlingguy.php + - role: geerlingguy.php-xdebug + + post_tasks: + - name: Run test script to confirm XDebug is working. + script: xdebug-test.php + args: + executable: php + changed_when: false diff --git a/provisioning/roles/geerlingguy.php-xdebug/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.php-xdebug/molecule/default/requirements.yml new file mode 100644 index 000000000..908335edd --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/molecule/default/requirements.yml @@ -0,0 +1,4 @@ +--- +- src: geerlingguy.repo-remi +- src: geerlingguy.php-versions +- src: geerlingguy.php diff --git a/provisioning/roles/geerlingguy.php-xdebug/molecule/default/xdebug-test.php b/provisioning/roles/geerlingguy.php-xdebug/molecule/default/xdebug-test.php new file mode 100644 index 000000000..d5ff4f47a --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/molecule/default/xdebug-test.php @@ -0,0 +1,21 @@ +<?php + +/** + * @file + * Test if Xdebug is available and working. + */ + +$success = FALSE; + +// Simple check; this function should return an empty array. +$test = xdebug_get_code_coverage(); +if ($test === array()) { + $success = TRUE; + print "Xdebug working properly.\r\n"; + exit(0); +} + +if (!$success) { + print "Xdebug not working properly.\r\n"; + exit(1); +} diff --git a/provisioning/roles/geerlingguy.php-xdebug/molecule/default/yaml-lint.yml b/provisioning/roles/geerlingguy.php-xdebug/molecule/default/yaml-lint.yml new file mode 100644 index 000000000..a3dbc38ee --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/molecule/default/yaml-lint.yml @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 120 + level: warning diff --git a/provisioning/roles/geerlingguy.php-xdebug/tasks/configure.yml b/provisioning/roles/geerlingguy.php-xdebug/tasks/configure.yml new file mode 100644 index 000000000..b13be4930 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/tasks/configure.yml @@ -0,0 +1,22 @@ +--- +- name: Copy xdebug ini into main extension config folder. + template: + src: xdebug.ini.j2 + dest: "{{ item }}/{{ php_xdebug_config_filename }}" + owner: root + group: root + mode: 0644 + when: "'cli' not in item or ('cli' in item and not php_xdebug_cli_disable)" + with_items: "{{ php_extension_conf_paths }}" + notify: + - restart webserver + - restart php-fpm + +- name: Disable xdebug for PHP CLI. + file: + path: "/etc/php/{{ php_version }}/cli/conf.d/{{ php_xdebug_config_filename }}" + state: absent + when: ansible_os_family == 'Debian' and php_xdebug_cli_disable + notify: + - restart webserver + - restart php-fpm diff --git a/provisioning/roles/geerlingguy.php-xdebug/tasks/main.yml b/provisioning/roles/geerlingguy.php-xdebug/tasks/main.yml new file mode 100644 index 000000000..6db48bcb3 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/tasks/main.yml @@ -0,0 +1,59 @@ +--- +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define php_xdebug_module_path. + set_fact: + php_xdebug_module_path: "{{ __php_xdebug_module_path }}" + when: php_xdebug_module_path is not defined + +- name: Define php_xdebug_config_filename. + set_fact: + php_xdebug_config_filename: "{{ __php_xdebug_config_filename }}" + when: php_xdebug_config_filename is not defined + +- name: Ensure dependencies for building from source are installed (RedHat). + yum: + name: '@development' + state: present + when: ansible_os_family == 'RedHat' + +- name: Ensure dependencies for building from source are installed (Debian). + apt: + name: build-essential + state: present + when: ansible_os_family == 'Debian' + +- name: Untar Xdebug. + unarchive: + src: "https://xdebug.org/files/xdebug-{{ php_xdebug_version }}.tgz" + dest: "{{ workspace }}" + creates: "{{ workspace }}/xdebug-{{ php_xdebug_version }}" + copy: false + +- name: Build Xdebug. + command: > + {{ item }} + chdir={{ workspace }}/xdebug-{{ php_xdebug_version }} + creates={{ workspace }}/xdebug-{{ php_xdebug_version }}/modules/xdebug.so + with_items: + - phpize + - ./configure + - make + +- name: Ensure Xdebug module path exists. + file: + path: "{{ php_xdebug_module_path }}" + state: directory + owner: root + group: root + mode: 0755 + +- name: Move Xdebug module into place. + copy: + src: "{{ workspace }}/xdebug-{{ php_xdebug_version }}/modules/xdebug.so" + dest: "{{ php_xdebug_module_path }}/xdebug-{{ php_xdebug_version }}.so" + remote_src: true + notify: restart webserver + +- include_tasks: configure.yml diff --git a/provisioning/roles/geerlingguy.php-xdebug/templates/xdebug.ini.j2 b/provisioning/roles/geerlingguy.php-xdebug/templates/xdebug.ini.j2 new file mode 100644 index 000000000..805b67f67 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/templates/xdebug.ini.j2 @@ -0,0 +1,16 @@ +[XDebug] +zend_extension="{{ php_xdebug_module_path }}/xdebug-{{ php_xdebug_version }}.so" + +xdebug.coverage_enable={{ php_xdebug_coverage_enable }} +xdebug.default_enable={{ php_xdebug_default_enable }} + +xdebug.remote_enable={{ php_xdebug_remote_enable }} +xdebug.remote_connect_back={{ php_xdebug_remote_connect_back }} +xdebug.remote_host={{ php_xdebug_remote_host }} +xdebug.remote_port={{ php_xdebug_remote_port }} +xdebug.remote_log={{ php_xdebug_remote_log }} +xdebug.remote_autostart={{ php_xdebug_remote_autostart }} + +xdebug.idekey="{{ php_xdebug_idekey }}" + +xdebug.max_nesting_level={{ php_xdebug_max_nesting_level }} diff --git a/provisioning/roles/geerlingguy.php-xdebug/vars/Debian.yml b/provisioning/roles/geerlingguy.php-xdebug/vars/Debian.yml new file mode 100644 index 000000000..560abbde8 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/vars/Debian.yml @@ -0,0 +1,3 @@ +--- +__php_xdebug_module_path: /usr/lib/php5/modules +__php_xdebug_config_filename: 20-xdebug.ini diff --git a/provisioning/roles/geerlingguy.php-xdebug/vars/RedHat.yml b/provisioning/roles/geerlingguy.php-xdebug/vars/RedHat.yml new file mode 100644 index 000000000..7d7c7fbb0 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xdebug/vars/RedHat.yml @@ -0,0 +1,3 @@ +--- +__php_xdebug_module_path: /usr/lib64/php/modules +__php_xdebug_config_filename: xdebug.ini diff --git a/provisioning/roles/geerlingguy.php-xhprof/.gitignore b/provisioning/roles/geerlingguy.php-xhprof/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.php-xhprof/.travis.yml b/provisioning/roles/geerlingguy.php-xhprof/.travis.yml new file mode 100644 index 000000000..2f8688121 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/.travis.yml @@ -0,0 +1,28 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: php-xhprof + matrix: + - MOLECULE_DISTRO: centos7 + - MOLECULE_DISTRO: ubuntu1804 + - MOLECULE_DISTRO: debian9 + +install: + # Install test dependencies. + - pip install molecule docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.php-xhprof/LICENSE b/provisioning/roles/geerlingguy.php-xhprof/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.php-xhprof/README.md b/provisioning/roles/geerlingguy.php-xhprof/README.md new file mode 100644 index 000000000..67a4b24ac --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/README.md @@ -0,0 +1,58 @@ +# Ansible Role: PHP-XHProf + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-php-xhprof.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-php-xhprof) + +Installs PHP [XHProf](http://php.net/manual/en/book.xhprof.php) on Linux servers. + +> **Note**: The XHProf extension has been on life support since Facebook abandoned active development around 2015. There is a better-maintained fork that works on the latest PHP versions called Tideways, and there's an Ansible role for it—please check out [`geerlingguy.php-tideways`](https://github.com/geerlingguy/ansible-role-php-tideways) if you need to support modern PHP versions. + +## Requirements + +None. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + workspace: /root + +Where XHProf setup files will be downloaded and built. + + xhprof_version: "2.1.2" + +The version of XHProf to download. + + xhprof_download_url: https://github.com/longxinH/xhprof/archive/v{{ xhprof_version }}.zip + xhprof_download_folder_name: xhprof-{{ xhprof_version }} + +The URL from which XHProf will be downloaded. + + xhprof_output_dir: /tmp + +Directory where XHProf runs are stored. + + php_xhprof_lib_dir: /usr/share/php/xhprof_lib + +Directory where the XHProf PHP library is stored. + + php_xhprof_html_dir: /usr/share/php/xhprof_html + +Directory where the XHProf UI is stored. + +## Dependencies + + - geerlingguy.php + +## Example Playbook + + - hosts: webservers + roles: + - geerlingguy.php-xhprof + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.php-xhprof/defaults/main.yml b/provisioning/roles/geerlingguy.php-xhprof/defaults/main.yml new file mode 100644 index 000000000..e239f5209 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/defaults/main.yml @@ -0,0 +1,12 @@ +--- +workspace: /root + +xhprof_version: "2.1.2" + +xhprof_download_url: https://github.com/longxinH/xhprof/archive/v{{ xhprof_version }}.zip +xhprof_download_folder_name: xhprof-{{ xhprof_version }} + +xhprof_output_dir: /tmp + +php_xhprof_lib_dir: /usr/share/php/xhprof_lib +php_xhprof_html_dir: /usr/share/php/xhprof_html diff --git a/provisioning/roles/geerlingguy.php-xhprof/meta/main.yml b/provisioning/roles/geerlingguy.php-xhprof/meta/main.yml new file mode 100644 index 000000000..d6610e75b --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/meta/main.yml @@ -0,0 +1,48 @@ +--- +dependencies: + - geerlingguy.php + +galaxy_info: + author: geerlingguy + description: PHP XHProf for Linux + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + - name: GenericUNIX + versions: + - all + - name: Fedora + versions: + - all + - name: opensuse + versions: + - all + - name: GenericBSD + versions: + - all + - name: FreeBSD + versions: + - all + - name: Ubuntu + versions: + - all + - name: SLES + versions: + - all + - name: GenericLinux + versions: + - all + - name: Debian + versions: + - all + galaxy_tags: + - development + - web + - php + - xhprof + - profile + - debug diff --git a/provisioning/roles/geerlingguy.php-xhprof/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.php-xhprof/molecule/default/molecule.yml new file mode 100644 index 000000000..2ca6feaf9 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/molecule/default/molecule.yml @@ -0,0 +1,29 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-file: molecule/default/yaml-lint.yml +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + lint: + name: ansible-lint + playbooks: + converge: ${MOLECULE_PLAYBOOK:-playbook.yml} +scenario: + name: default +verifier: + name: testinfra + lint: + name: flake8 diff --git a/provisioning/roles/geerlingguy.php-xhprof/molecule/default/playbook.yml b/provisioning/roles/geerlingguy.php-xhprof/molecule/default/playbook.yml new file mode 100644 index 000000000..846ec56ea --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/molecule/default/playbook.yml @@ -0,0 +1,26 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.repo-remi + when: ansible_os_family == 'RedHat' + - role: geerlingguy.php-versions + - role: geerlingguy.php + - role: geerlingguy.php-xhprof + + post_tasks: + - name: Run test script to confirm XHProf is working. + script: xhprof-test.php + args: + executable: php + changed_when: false diff --git a/provisioning/roles/geerlingguy.php-xhprof/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.php-xhprof/molecule/default/requirements.yml new file mode 100644 index 000000000..908335edd --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/molecule/default/requirements.yml @@ -0,0 +1,4 @@ +--- +- src: geerlingguy.repo-remi +- src: geerlingguy.php-versions +- src: geerlingguy.php diff --git a/provisioning/roles/geerlingguy.php-xhprof/molecule/default/xhprof-test.php b/provisioning/roles/geerlingguy.php-xhprof/molecule/default/xhprof-test.php new file mode 100644 index 000000000..1dd28b956 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/molecule/default/xhprof-test.php @@ -0,0 +1,51 @@ +<?php + +/** + * @file + * Test if XHProf is available and working. + */ + +$xhprof_root_dir = '/usr/share/php'; +$success = TRUE; + +xhprof_enable(); +$data = xhprof_disable(); + +if (isset($data['main()==>xhprof_disable'])) { + print "XHProf profiling working.\r\n"; +} +else { + print "XHProf profiling not working.\r\n"; + $success = FALSE; +} + +include $xhprof_root_dir . '/xhprof_lib/utils/xhprof_lib.php'; +include $xhprof_root_dir . '/xhprof_lib/utils/xhprof_runs.php'; + +$xhprof_runs = new XHProfRuns_Default(); +$run_id = $xhprof_runs->save_run($data, "xhprof_testing"); +$output_dir = ini_get("xhprof.output_dir"); +$filename = "$output_dir/$run_id.xhprof_testing.xhprof"; + +if (file_exists($filename)) { + print "XHProf PHP library writing to output directory.\r\n"; +} +else { + print "XHProf PHP library not working.\r\n"; + $success = FALSE; +} + +ob_start(); +include $xhprof_root_dir . '/xhprof_html/index.php'; +$html = ob_get_clean(); +if (strpos($html, "?run=$run_id") !== FALSE) { + print "XHProf UI working.\r\n"; +} +else { + print "XHProf UI not working.\r\n"; + $success = FALSE; +} + +if (!$success) { + exit(1); +} diff --git a/provisioning/roles/geerlingguy.php-xhprof/molecule/default/yaml-lint.yml b/provisioning/roles/geerlingguy.php-xhprof/molecule/default/yaml-lint.yml new file mode 100644 index 000000000..a3dbc38ee --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/molecule/default/yaml-lint.yml @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 120 + level: warning diff --git a/provisioning/roles/geerlingguy.php-xhprof/tasks/configure.yml b/provisioning/roles/geerlingguy.php-xhprof/tasks/configure.yml new file mode 100644 index 000000000..67fcbfc2b --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/tasks/configure.yml @@ -0,0 +1,18 @@ +--- +- name: Ensure PHP configuration directories exist. + file: + path: "{{ item }}" + state: directory + mode: 0755 + follow: true + with_items: "{{ php_extension_conf_paths }}" + +- name: Copy XHProf INI into various other conf folders. + template: + src: xhprof.ini.j2 + dest: "{{ item }}/{{ php_xhprof_config_filename }}" + owner: root + group: root + mode: 0644 + with_items: "{{ php_extension_conf_paths }}" + notify: restart webserver diff --git a/provisioning/roles/geerlingguy.php-xhprof/tasks/main.yml b/provisioning/roles/geerlingguy.php-xhprof/tasks/main.yml new file mode 100644 index 000000000..eb8bc5553 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/tasks/main.yml @@ -0,0 +1,73 @@ +--- +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define php_xhprof_module_path. + set_fact: + php_xhprof_module_path: "{{ __php_xhprof_module_path }}" + when: php_xhprof_module_path is not defined + +- name: Define php_xhprof_config_filename. + set_fact: + php_xhprof_config_filename: "{{ __php_xhprof_config_filename }}" + when: php_xhprof_config_filename is not defined + +# Setup/install tasks. +- name: Ensure dependencies for installing XHProf are present. + package: "name={{ item }} state=present" + with_items: + - make + - gcc + - unzip + - graphviz + +- name: Download and untar XHProf. + unarchive: + src: "{{ xhprof_download_url }}" + dest: "{{ workspace }}" + copy: false + creates: "{{ workspace }}/{{ xhprof_download_folder_name }}" + +- name: Build XHProf. + command: > + {{ item }} + chdir={{ workspace }}/{{ xhprof_download_folder_name }}/extension + creates={{ workspace }}/{{ xhprof_download_folder_name }}/extension/modules/xhprof.so + with_items: + - phpize + - ./configure + - make + notify: restart webserver + +- name: Ensure XHProf module path exists. + file: + path: "{{ php_xhprof_module_path }}" + state: directory + owner: root + group: root + mode: 0755 + +- name: Move XHProf module into place. + command: > + cp {{ workspace }}/{{ xhprof_download_folder_name }}/extension/modules/xhprof.so + {{ php_xhprof_module_path }}/xhprof.so + creates={{ php_xhprof_module_path }}/xhprof.so + notify: restart webserver + +- name: Move XHProf PHP library into place. + command: > + cp -r {{ workspace }}/{{ xhprof_download_folder_name }}/xhprof_lib {{ php_xhprof_lib_dir }} + creates={{ php_xhprof_lib_dir }}/utils/xhprof_lib.php + +- name: Move XHProf UI into place. + command: > + cp -r {{ workspace }}/{{ xhprof_download_folder_name }}/xhprof_html {{ php_xhprof_html_dir }} + creates={{ php_xhprof_html_dir }}/index.php + +- include_tasks: configure.yml + +- name: Ensure XHProf output directory exists. + file: + path: "{{ xhprof_output_dir }}" + state: directory + mode: 0777 diff --git a/provisioning/roles/geerlingguy.php-xhprof/templates/xhprof.ini.j2 b/provisioning/roles/geerlingguy.php-xhprof/templates/xhprof.ini.j2 new file mode 100644 index 000000000..8caedae53 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/templates/xhprof.ini.j2 @@ -0,0 +1,3 @@ +[xhprof] +extension="{{ php_xhprof_module_path }}/xhprof.so" +xhprof.output_dir="{{ xhprof_output_dir }}" diff --git a/provisioning/roles/geerlingguy.php-xhprof/vars/Debian.yml b/provisioning/roles/geerlingguy.php-xhprof/vars/Debian.yml new file mode 100644 index 000000000..1b0a970b3 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/vars/Debian.yml @@ -0,0 +1,3 @@ +--- +__php_xhprof_module_path: /usr/lib/php5/modules +__php_xhprof_config_filename: 20-xhprof.ini diff --git a/provisioning/roles/geerlingguy.php-xhprof/vars/RedHat.yml b/provisioning/roles/geerlingguy.php-xhprof/vars/RedHat.yml new file mode 100644 index 000000000..b380b2b97 --- /dev/null +++ b/provisioning/roles/geerlingguy.php-xhprof/vars/RedHat.yml @@ -0,0 +1,3 @@ +--- +__php_xhprof_module_path: /usr/lib64/php/modules +__php_xhprof_config_filename: xhprof.ini diff --git a/provisioning/roles/geerlingguy.php/.ansible-lint b/provisioning/roles/geerlingguy.php/.ansible-lint new file mode 100644 index 000000000..8d58b475f --- /dev/null +++ b/provisioning/roles/geerlingguy.php/.ansible-lint @@ -0,0 +1,5 @@ +skip_list: + - 'yaml' + - 'risky-shell-pipe' + - 'no-handler' + - 'role-name' diff --git a/provisioning/roles/geerlingguy.php/.github/FUNDING.yml b/provisioning/roles/geerlingguy.php/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.php/.github/stale.yml b/provisioning/roles/geerlingguy.php/.github/stale.yml new file mode 100644 index 000000000..3cc6ec313 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/.github/stale.yml @@ -0,0 +1,57 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - bug + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.php/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.php/.github/workflows/ci.yml new file mode 100644 index 000000000..96a41a653 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/.github/workflows/ci.yml @@ -0,0 +1,82 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "0 4 * * 4" + +defaults: + run: + working-directory: 'geerlingguy.php' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.php' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + include: + - distro: centos8 + playbook: converge.yml + - distro: centos7 + playbook: converge.yml + - distro: ubuntu2004 + playbook: converge.yml + - distro: ubuntu1804 + playbook: converge.yml + - distro: debian11 + playbook: converge.yml + - distro: debian10 + playbook: converge.yml + - distro: debian9 + playbook: converge.yml + + - distro: centos7 + playbook: source-install.yml + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.php' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} + MOLECULE_PLAYBOOK: ${{ matrix.playbook }} diff --git a/provisioning/roles/geerlingguy.php/.github/workflows/release.yml b/provisioning/roles/geerlingguy.php/.github/workflows/release.yml new file mode 100644 index 000000000..8335b8b72 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.php' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.php' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.php/.gitignore b/provisioning/roles/geerlingguy.php/.gitignore new file mode 100644 index 000000000..8840c8f02 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/.gitignore @@ -0,0 +1,5 @@ +*.retry +*/__pycache__ +*.pyc +.cache + diff --git a/provisioning/roles/geerlingguy.php/.yamllint b/provisioning/roles/geerlingguy.php/.yamllint new file mode 100644 index 000000000..f2033dd21 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/provisioning/roles/geerlingguy.php/LICENSE b/provisioning/roles/geerlingguy.php/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.php/README.md b/provisioning/roles/geerlingguy.php/README.md new file mode 100644 index 000000000..7e7707efb --- /dev/null +++ b/provisioning/roles/geerlingguy.php/README.md @@ -0,0 +1,247 @@ +# Ansible Role: PHP + +[![CI](https://github.com/geerlingguy/ansible-role-php/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-php/actions?query=workflow%3ACI) + +Installs PHP on RedHat/CentOS and Debian/Ubuntu servers. + +## Requirements + +If you're using an older LTS release of Ubuntu or RHEL, with an old/outdated version of PHP, you need to use a repo or PPA with a maintained PHP version, as this role only works with [PHP versions that are currently supported](http://php.net/supported-versions.php) by the PHP community. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + php_packages: [] + +A list of the PHP packages to install (OS-specific by default). You'll likely want to install common packages like `php`, `php-cli`, `php-devel` and `php-pdo`, and you can add in whatever other packages you'd like (for example, `php-gd` for image manipulation, or `php-ldap` if you need to connect to an LDAP server for authentication). + +_Note: If you're using Debian/Ubuntu, you also need to install `libapache2-mod-fastcgi` (for cgi/PHP-FPM) or `libapache2-mod-php7.0` (or a similar package depending on PHP version) if you want to use `mod_php` with Apache._ + + php_packages_extra: [] + +A list of extra PHP packages to install without overriding the default list. + + php_enable_webserver: true + +If your usage of PHP is tied to a web server (e.g. Apache or Nginx), leave this default value. If you are using PHP server-side or to run some small application, set this value to `false` so this role doesn't attempt to interact with a web server. + + php_webserver_daemon: "httpd" + +The default values for the HTTP server deamon are `httpd` (used by Apache) for RedHat/CentOS, or `apache2` (also used by Apache) for Debian/Ubuntu. If you are running another webserver (for example, `nginx`), change this value to the name of the daemon under which the webserver runs. + + php_enablerepo: "" + +(RedHat/CentOS only) If you have enabled any additional repositories (might I suggest [geerlingguy.repo-epel](https://github.com/geerlingguy/ansible-role-repo-epel) or [geerlingguy.repo-remi](https://github.com/geerlingguy/ansible-role-repo-remi)), those repositories can be listed under this variable (e.g. `remi-php70,epel`). This can be handy, as an example, if you want to install the latest version of PHP 7.0, which is in the Remi repository. + + php_default_version_debian: "" + +(Debian/Ubuntu only) The default version of PHP in the given OS version repositories. The specific version is set per distro and per version, but you can override it by providing a value here, like `"7.4"`. + +**If you'd like to be able to switch PHP versions easily, or use a version that's not available in system packages**: You can use the [`geerlingguy.php-versions`](https://galaxy.ansible.com/geerlingguy/php-versions/) role to more easily switch between major PHP versions (e.g. 5.6, 7.1, 7.2). + + php_packages_state: "present" + +If you have enabled any additional repositories such as [geerlingguy.repo-epel](https://github.com/geerlingguy/ansible-role-repo-epel) or [geerlingguy.repo-remi](https://github.com/geerlingguy/ansible-role-repo-remi), you may want an easy way to swap PHP versions on the fly. By default, this is set to `"present"`. You can override this variable to `"latest"` to upgrade to the latest available version. Combined with `php_enablerepo`, a user now doesn't need to manually uninstall the existing PHP packages before installing them from a different repository. + + php_install_recommends: true + +(Debian/Ubuntu only) Whether to install recommended packages when installing `php_packages`; you might want to set this to `no` explicitly if you're installing a PPA that recommends certain packages you don't want (e.g. Ondrej's `php` PPA will install `php7.0-cli` if you install `php-pear` alongside `php5.6-cli`... which is often not desired!). + + php_executable: "php" + +The executable to run when calling PHP from the command line. You should only change this if running `php` on your server doesn't target the correct executable, or if you're using software collections on RHEL/CentOS and need to target a different version of PHP. + +### PHP-FPM + +PHP-FPM is a simple and robust FastCGI Process Manager for PHP. It can dramatically ease scaling of PHP apps and is the normal way of running PHP-based sites and apps when using a webserver like Nginx (though it can be used with other webservers just as easily). + +When using this role with PHP running as `php-fpm` instead of as a process inside a webserver (e.g. Apache's `mod_php`), you need to set the following variable to `true`: + + php_enable_php_fpm: false + +If you're using Apache, you can easily get it configured to work with PHP-FPM using the [geerlingguy.apache-php-fpm](https://github.com/geerlingguy/ansible-role-apache-php-fpm) role. + + php_fpm_state: started + php_fpm_enabled_on_boot: true + +Control over the fpm daemon's state; set these to `stopped` and `false` if you want FPM to be installed and configured, but not running (e.g. when installing in a container). + + php_fpm_handler_state: restarted + +The handler restarts PHP-FPM by default. Setting the value to `reloaded` will reload the service, intead of restarting it. + + + php_fpm_pools: + - pool_name: www + pool_template: www.conf.j2 + pool_listen: "127.0.0.1:9000" + pool_listen_allowed_clients: "127.0.0.1" + pool_pm: dynamic + pool_pm_max_children: 5 + pool_pm_start_servers: 2 + pool_pm_min_spare_servers: 1 + pool_pm_max_spare_servers: 3 + pool_pm_max_requests: 500 + +List of PHP-FPM pool to create. By default, www pool is created. To setup a new pool, add an item to php_fpm_pools list. + +Specific settings inside the default `www.conf.j2` PHP-FPM pool. If you'd like to manage additional settings, you can do so either by replacing the file with your own template using `pool_template`. + +### php.ini settings + + php_use_managed_ini: true + +By default, all the extra defaults below are applied through the php.ini included with this role. You can self-manage your php.ini file (if you need more flexility in its configuration) by setting this to `false` (in which case all the below variables will be ignored). + + php_fpm_pool_user: "[apache|nginx|other]" # default varies by OS + php_fpm_pool_group: "[apache|nginx|other]" # default varies by OS + php_memory_limit: "256M" + php_max_execution_time: "60" + php_max_input_time: "60" + php_max_input_vars: "1000" + php_realpath_cache_size: "32K" + php_file_uploads: "On" + php_upload_max_filesize: "64M" + php_max_file_uploads: "20" + php_post_max_size: "32M" + php_date_timezone: "America/Chicago" + php_allow_url_fopen: "On" + php_sendmail_path: "/usr/sbin/sendmail -t -i" + php_output_buffering: "4096" + php_short_open_tag: false + php_error_reporting: "E_ALL & ~E_DEPRECATED & ~E_STRICT" + php_display_errors: "Off" + php_display_startup_errors: "On" + php_expose_php: "On" + php_session_cookie_lifetime: 0 + php_session_gc_probability: 1 + php_session_gc_divisor: 1000 + php_session_gc_maxlifetime: 1440 + php_session_save_handler: files + php_session_save_path: '' + php_disable_functions: [] + php_precision: 14 + php_serialize_precision: "-1" + +Various defaults for PHP. Only used if `php_use_managed_ini` is set to `true`. + +### OpCache-related Variables + +The OpCache is included in PHP starting in version 5.5, and the following variables will only take effect if the version of PHP you have installed is 5.5 or greater. + + php_opcache_zend_extension: "opcache.so" + php_opcache_enable: "1" + php_opcache_enable_cli: "0" + php_opcache_memory_consumption: "96" + php_opcache_interned_strings_buffer: "16" + php_opcache_max_accelerated_files: "4096" + php_opcache_max_wasted_percentage: "5" + php_opcache_validate_timestamps: "1" + php_opcache_revalidate_path: "0" + php_opcache_revalidate_freq: "2" + php_opcache_max_file_size: "0" + +OpCache ini directives that are often customized on a system. Make sure you have enough memory and file slots allocated in the OpCache (`php_opcache_memory_consumption`, in MB, and `php_opcache_max_accelerated_files`) to contain all the PHP code you are running. If not, you may get less-than-optimal performance! + +For custom opcache.so location provide full path with `php_opcache_zend_extension`. + + php_opcache_conf_filename: [platform-specific] + +The platform-specific opcache configuration filename. Generally the default should work, but in some cases, you may need to override the filename. + +### APCu-related Variables + + php_enable_apc: true + +Whether to enable APCu. Other APCu variables will be ineffective if this is set to false. + + php_apc_shm_size: "96M" + php_apc_enable_cli: "0" + +APCu ini directives that are often customized on a system. Set the `php_apc_shm_size` so it will hold all cache entries in memory with a little overhead (fragmentation or APC running out of memory will slow down PHP *dramatically*). + + php_apc_conf_filename: [platform-specific] + +The platform-specific APC configuration filename. Generally the default should work, but in some cases, you may need to override the filename. + +#### Ensuring APC is installed + +If you use APC, you will need to make sure APC is installed (it is installed by default, but if you customize the `php_packages` list, you need to include APC in the list): + + - *On RHEL/CentOS systems*: Make sure `php-pecl-apcu` is in the list of `php_packages`. + - *On Debian/Ubuntu systems*: Make sure `php-apcu` is in the list of `php_packages`. + +### Installing from Source + +If you need a specific version of PHP, or would like to test the latest (e.g. master) version of PHP, there's a good chance there's no suitable package already available in your platform's package manager. In these cases, you may choose to install PHP from source by compiling it directly. + +Note that source compilation takes *much* longer than installing from packages (PHP HEAD takes 5+ minutes to compile on a modern quad-core computer, just as a point of reference). + + php_install_from_source: false + +Set this to `true` to install PHP from source instead of installing from packages. + + php_source_version: "master" + +The version of PHP to install from source (a git branch, tag, or commit hash). + + php_source_clone_dir: "~/php-src" + php_source_clone_depth: 1 + php_source_install_path: "/opt/php" + php_source_install_gmp_path: "/usr/include/x86_64-linux-gnu/gmp.h" + php_source_mysql_config: "/usr/bin/mysql_config" + +Location where source will be cloned and installed, and the location of the GMP header file (which can be platform/distribution specific), and `mysql_config` binary (this may be `mariadb_config` in newer operating system versions). + + php_source_make_command: "make" + +Set the `make` command to `make --jobs=X` where `X` is the number of cores present on the server where PHP is being compiled. Will speed up compilation times dramatically if you have multiple cores. + + php_source_configure_command: > + [...] + +The `./configure` command that will build the Makefile to be used for PHP compilation. Add in all the options you need for your particular environment. Using a folded scalar (`>`) allows you to define the variable over multiple lines, which is extremely helpful for legibility and source control! + +A few other notes/caveats for specific configurations: + + - **Apache with `mpm_prefork`**: If you're using Apache with prefork as a webserver for PHP, you will need to make sure `apxs2` is available on your system (e.g. by installing `apache2-prefork-dev` in Ubuntu), and you will need to make sure the option `--with-apxs2` is defined in `php_source_configure_command`. Finally, you will need to make sure the `mpm_prefork` module is loaded instead of `mpm_worker` or `mpm_event`, and likely add a `phpX.conf` (where `X` is the major version of PHP) configuration file to the Apache module config folder with contents like [`php7.conf`](https://gist.github.com/geerlingguy/5ae5445f28e71264e8c1). + - **Apache with `mpm_event` or `mpm_worker`**: If you're using Apache with event or worker as a webserver for PHP, you will need to compile PHP with FPM. Make sure the option `--enable-fpm` is defined in `php_source_configure_command`. You'll also need to make sure Apache's support for CGI and event is installed (e.g. by installing `apache2-mpm-event` and `libapache2-mod-fastcgi`) and the `mpm_event` module is loaded. + - **Nginx**: If you're using Nginx as a webserver for PHP, you will need to compile PHP with FPM. Make sure the option `--enable-fpm` is defined in `php_source_configure_command`. + +## Dependencies + +None. + +## Example Playbook + + - hosts: webservers + vars_files: + - vars/main.yml + roles: + - { role: geerlingguy.php } + +*Inside `vars/main.yml`*: + + php_memory_limit: "128M" + php_max_execution_time: "90" + php_upload_max_filesize: "256M" + php_packages: + - php + - php-cli + - php-common + - php-devel + - php-gd + - php-mbstring + - php-pdo + - php-pecl-apcu + - php-xml + ... + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.php/defaults/main.yml b/provisioning/roles/geerlingguy.php/defaults/main.yml new file mode 100644 index 000000000..92550eba9 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/defaults/main.yml @@ -0,0 +1,154 @@ +--- +# Pass in a comma-separated list of repos to use (e.g. "remi,epel"). Used only +# for RHEL/CentOS. +php_enablerepo: "" + +# Extra packages to install (in addition to distro-specific default lists). +php_packages_extra: [] + +# Default PHP version to install on Debian-based OSes (OS-specific). +# php_default_version_debian: "" + +# PHP package state; use 'present' to make sure it's installed, or 'latest' if +# you want to upgrade or switch versions using a new repo. +php_packages_state: present + +# Whether to install recommended packages. Used only for Debian/Ubuntu. +php_install_recommends: true + +# Set this to false if you're not using PHP with Apache/Nginx/etc. +php_enable_webserver: true + +# PHP-FPM configuration. +php_enable_php_fpm: false +php_fpm_state: started +php_fpm_handler_state: restarted +php_fpm_enabled_on_boot: true +php_fpm_listen: "127.0.0.1:9000" +php_fpm_listen_allowed_clients: "127.0.0.1" +php_fpm_pm_max_children: 50 +php_fpm_pm_start_servers: 5 +php_fpm_pm_min_spare_servers: 5 +php_fpm_pm_max_spare_servers: 5 +php_fpm_pm_max_requests: 0 + +# PHP-FPM pool configuration. +php_fpm_pools: + - pool_name: www + pool_template: www.conf.j2 + pool_listen: "{{ php_fpm_listen }}" + pool_listen_allowed_clients: "{{ php_fpm_listen_allowed_clients }}" + pool_pm: dynamic + pool_pm_max_children: "{{ php_fpm_pm_max_children }}" + pool_pm_start_servers: "{{ php_fpm_pm_start_servers }}" + pool_pm_min_spare_servers: "{{ php_fpm_pm_min_spare_servers }}" + pool_pm_max_spare_servers: "{{ php_fpm_pm_max_spare_servers }}" + pool_php_fpm_pm_max_requests: "{{ php_fpm_pm_max_requests }}" + +# The executable to run when calling PHP from the command line. +php_executable: "php" + +# OpCache settings. +php_opcache_zend_extension: "opcache.so" +php_opcache_enable: "1" +php_opcache_enable_cli: "0" +php_opcache_memory_consumption: "96" +php_opcache_interned_strings_buffer: "16" +php_opcache_max_accelerated_files: "4096" +php_opcache_max_wasted_percentage: "5" +php_opcache_validate_timestamps: "1" +php_opcache_revalidate_path: "0" +php_opcache_revalidate_freq: "2" +php_opcache_max_file_size: "0" +php_opcache_blacklist_filename: "" + +# APCu settings. +php_enable_apc: true +php_apc_shm_size: "96M" +php_apc_enable_cli: "0" + +# If this is set to false, none of the following options will have any effect. +# Any and all changes to /etc/php.ini will be your responsibility. +php_use_managed_ini: true + +php_expose_php: "On" +php_memory_limit: "256M" +php_max_execution_time: "60" +php_max_input_time: "60" +php_max_input_vars: "1000" +php_realpath_cache_size: "32K" + +php_file_uploads: "On" +php_upload_max_filesize: "64M" +php_max_file_uploads: "20" + +php_post_max_size: "32M" +php_date_timezone: "America/Chicago" +php_allow_url_fopen: "On" + +php_sendmail_path: "/usr/sbin/sendmail -t -i" +php_output_buffering: "4096" +php_short_open_tag: "Off" +php_disable_functions: [] +php_precision: 14 +php_serialize_precision: "-1" + +php_session_cookie_lifetime: 0 +php_session_gc_probability: 1 +php_session_gc_divisor: 1000 +php_session_gc_maxlifetime: 1440 +php_session_save_handler: files +php_session_save_path: '' + +php_error_reporting: "E_ALL & ~E_DEPRECATED & ~E_STRICT" +php_display_errors: "Off" +php_display_startup_errors: "Off" + +# Install PHP from source (instead of using a package manager) with these vars. +php_install_from_source: false +php_source_repo: "https://git.php.net/repository/php-src.git" +php_source_version: "master" +php_source_clone_dir: "~/php-src" +php_source_clone_depth: 1 +php_source_install_path: "/opt/php" +php_source_install_gmp_path: "/usr/include/x86_64-linux-gnu/gmp.h" +php_source_mysql_config: "/usr/bin/mysql_config" +# For faster compile time: "make --jobs=X" where X is # of cores present. +php_source_make_command: "make" +php_source_configure_command: > + ./configure + --prefix={{ php_source_install_path }} + --with-config-file-path={{ php_conf_paths | first }} + --enable-mbstring + --enable-zip + --enable-bcmath + --enable-pcntl + --enable-ftp + --enable-exif + --enable-calendar + --enable-opcache + --enable-pdo + --enable-sysvmsg + --enable-sysvsem + --enable-sysvshm + --enable-wddx + --with-curl + --with-mcrypt + --with-iconv + --with-gmp + --with-pspell + --with-gd + --with-jpeg-dir=/usr + --with-png-dir=/usr + --with-zlib-dir=/usr + --with-xpm-dir=/usr + --with-freetype-dir=/usr + --enable-gd-native-ttf + --enable-gd-jis-conv + --with-openssl + --with-pdo-mysql=/usr + --with-gettext=/usr + --with-zlib=/usr + --with-bz2=/usr + --with-recode=/usr + --with-mysqli={{ php_source_mysql_config }} diff --git a/provisioning/roles/geerlingguy.php/handlers/main.yml b/provisioning/roles/geerlingguy.php/handlers/main.yml new file mode 100644 index 000000000..e0d0a292c --- /dev/null +++ b/provisioning/roles/geerlingguy.php/handlers/main.yml @@ -0,0 +1,15 @@ +--- +- name: restart webserver + service: + name: "{{ php_webserver_daemon }}" + state: restarted + notify: restart php-fpm + when: php_enable_webserver + +- name: restart php-fpm + service: + name: "{{ php_fpm_daemon }}" + state: "{{ php_fpm_handler_state }}" + when: + - php_enable_php_fpm + - php_fpm_state == 'started' diff --git a/provisioning/roles/geerlingguy.php/meta/main.yml b/provisioning/roles/geerlingguy.php/meta/main.yml new file mode 100644 index 000000000..e3ade6fb4 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/meta/main.yml @@ -0,0 +1,36 @@ +--- +dependencies: [] + +galaxy_info: + role_name: php + author: geerlingguy + description: PHP for RedHat/CentOS/Fedora/Debian/Ubuntu. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.8 + platforms: + - name: EL + versions: + - 7 + - 8 + - name: Fedora + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - trusty + - xenial + - bionic + galaxy_tags: + - development + - web + - php + - language + - fpm + - drupal + - wordpress + - joomla + - magento diff --git a/provisioning/roles/geerlingguy.php/molecule/default/converge.yml b/provisioning/roles/geerlingguy.php/molecule/default/converge.yml new file mode 100644 index 000000000..41ae7c192 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/molecule/default/converge.yml @@ -0,0 +1,70 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + php_enable_php_fpm: true + php_memory_limit: "192M" + php_enablerepo: "remi,remi-php70" + php_install_recommends: false + + handlers: + - name: update apt cache + apt: update_cache=true + when: ansible_os_family == 'Debian' + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + # Ubuntu-specific tasks. + - name: Ensure dirmngr is installed (gnupg dependency). + apt: + name: dirmngr + state: present + when: ansible_os_family == 'Debian' + + - name: Add repository for PHP 7. + apt_repository: repo='ppa:ondrej/php' + when: ansible_distribution == 'Ubuntu' + + # Debian-specific tasks. + - name: Add dependencies for PHP versions (Debian). + apt: + name: + - apt-transport-https + - ca-certificates + - gnupg2 + state: present + when: ansible_distribution == "Debian" + + - name: Add Ondrej Sury's apt key (Debian). + apt_key: + url: https://packages.sury.org/php/apt.gpg + state: present + when: ansible_distribution == "Debian" + + - name: Add Ondrej Sury's repo (Debian). + apt_repository: + repo: "deb https://packages.sury.org/php/ {{ ansible_distribution_release }} main" + state: present + when: ansible_distribution == "Debian" + notify: update apt cache + + - meta: flush_handlers + + roles: + - role: geerlingguy.repo-remi + when: + - ansible_os_family == 'RedHat' + - ansible_distribution != 'Fedora' + - role: geerlingguy.php + + post_tasks: + - name: Confirm PHP configuration is correct. + shell: php -i | grep 'memory_limit.*192' + changed_when: false diff --git a/provisioning/roles/geerlingguy.php/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.php/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.php/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.php/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.php/molecule/default/requirements.yml new file mode 100644 index 000000000..809b89be8 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/molecule/default/requirements.yml @@ -0,0 +1,3 @@ +--- +- src: geerlingguy.repo-remi +- src: geerlingguy.git diff --git a/provisioning/roles/geerlingguy.php/molecule/default/source-install.yml b/provisioning/roles/geerlingguy.php/molecule/default/source-install.yml new file mode 100644 index 000000000..d9ad0f95d --- /dev/null +++ b/provisioning/roles/geerlingguy.php/molecule/default/source-install.yml @@ -0,0 +1,32 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + php_install_from_source: true + php_source_clone_dir: /root/php-src + php_source_make_command: "make --jobs=2" + php_version: "7.4.8" + php_source_version: "php-{{ php_version }}" + php_memory_limit: "192M" + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + roles: + - role: geerlingguy.git + - role: geerlingguy.php + + post_tasks: + - name: Confirm PHP configuration is correct. + shell: php -i | grep 'memory_limit.*192' + changed_when: false + + - name: Check the installed PHP version. + shell: '/usr/bin/php --version | grep -qF "PHP {{ php_version }}"' + changed_when: false diff --git a/provisioning/roles/geerlingguy.php/tasks/configure-apcu.yml b/provisioning/roles/geerlingguy.php/tasks/configure-apcu.yml new file mode 100644 index 000000000..a29f8d634 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/tasks/configure-apcu.yml @@ -0,0 +1,37 @@ +--- +- name: Check for existing APCu config files. + find: + paths: "{{ item }}" + contains: 'extension(\s+)?=(\s+)?apc[u]?\.so' + register: php_installed_apc_confs + with_items: "{{ php_extension_conf_paths }}" + +- name: Remove any non-role-supplied APCu config files. + file: + path: "{{ item.1.path }}" + state: absent + when: php_apc_conf_filename != (item.1.path.split('/') | last) + with_subelements: + - "{{ php_installed_apc_confs.results }}" + - files + notify: restart webserver + +- name: Ensure APCu config file is present. + template: + src: apc.ini.j2 + dest: "{{ item }}/{{ php_apc_conf_filename }}" + owner: root + group: root + force: true + mode: 0644 + with_items: "{{ php_extension_conf_paths }}" + when: php_enable_apc + notify: restart webserver + +- name: Remove APCu config file if APC is disabled. + file: + path: "{{ item }}/{{ php_apc_conf_filename }}" + state: absent + with_items: "{{ php_extension_conf_paths }}" + when: not php_enable_apc + notify: restart webserver diff --git a/provisioning/roles/geerlingguy.php/tasks/configure-fpm.yml b/provisioning/roles/geerlingguy.php/tasks/configure-fpm.yml new file mode 100644 index 000000000..28135208f --- /dev/null +++ b/provisioning/roles/geerlingguy.php/tasks/configure-fpm.yml @@ -0,0 +1,53 @@ +--- +- name: Define php_fpm_daemon. + set_fact: + php_fpm_daemon: "{{ __php_fpm_daemon }}" + when: php_fpm_daemon is not defined + +- name: Define php_fpm_pool_conf_path. + set_fact: + php_fpm_pool_conf_path: "{{ __php_fpm_pool_conf_path }}" + when: php_fpm_pool_conf_path is not defined + +- name: Define php_fpm_pool_user. + set_fact: + php_fpm_pool_user: "{{ __php_fpm_pool_user }}" + when: php_fpm_pool_user is not defined + +- name: Define php_fpm_pool_group. + set_fact: + php_fpm_pool_group: "{{ __php_fpm_pool_group }}" + when: php_fpm_pool_group is not defined + +- name: Stat php_fpm_pool_conf_path + stat: + path: "{{ php_fpm_pool_conf_path | dirname }}" + register: php_fpm_pool_conf_path_dir_stat + +- name: Ensure the default pool directory exists. + file: + path: "{{ php_fpm_pool_conf_path | dirname }}" + state: directory + owner: root + group: root + mode: 0755 + when: php_fpm_pool_conf_path_dir_stat.stat.islnk is not defined + +- name: Create fpm pools. + template: + src: "{{ item.pool_template | default('www.conf.j2', true) }}" + dest: "{{ php_fpm_pool_conf_path | dirname }}/{{ item.pool_name }}.conf" + owner: root + group: root + mode: 0644 + force: true + loop: "{{ php_fpm_pools | default([], true) }}" + when: php_enable_php_fpm + notify: restart php-fpm + +- name: Ensure php-fpm is started and enabled at boot (if configured). + service: + name: "{{ php_fpm_daemon }}" + state: "{{ php_fpm_state }}" + enabled: "{{ php_fpm_enabled_on_boot }}" + when: php_enable_php_fpm and ansible_distribution != "Debian" diff --git a/provisioning/roles/geerlingguy.php/tasks/configure-opcache.yml b/provisioning/roles/geerlingguy.php/tasks/configure-opcache.yml new file mode 100644 index 000000000..fc043d0c6 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/tasks/configure-opcache.yml @@ -0,0 +1,37 @@ +--- +- name: Check for existing OpCache config files. + find: + paths: "{{ item }}" + contains: 'zend_extension(\s+)?=(\s+)?opcache\.so' + register: php_installed_opcache_confs + with_items: "{{ php_extension_conf_paths }}" + +- name: Remove any non-role-supplied OpCache config files. + file: + path: "{{ item.1.path }}" + state: absent + when: php_opcache_conf_filename != (item.1.path.split('/') | last) + with_subelements: + - "{{ php_installed_opcache_confs.results }}" + - files + notify: restart webserver + +- name: Ensure OpCache config file is present. + template: + src: opcache.ini.j2 + dest: "{{ item }}/{{ php_opcache_conf_filename }}" + owner: root + group: root + force: true + mode: 0644 + with_items: "{{ php_extension_conf_paths }}" + when: php_opcache_enable | bool + notify: restart webserver + +- name: Remove OpCache config file if OpCache is disabled. + file: + path: "{{ item }}/{{ php_opcache_conf_filename }}" + state: absent + with_items: "{{ php_extension_conf_paths }}" + when: not php_opcache_enable | bool + notify: restart webserver diff --git a/provisioning/roles/geerlingguy.php/tasks/configure.yml b/provisioning/roles/geerlingguy.php/tasks/configure.yml new file mode 100644 index 000000000..e0e1434bc --- /dev/null +++ b/provisioning/roles/geerlingguy.php/tasks/configure.yml @@ -0,0 +1,21 @@ +--- +- name: Ensure configuration directories exist. + file: + path: "{{ item }}" + state: directory + follow: true + mode: 0755 + with_flattened: + - "{{ php_conf_paths }}" + - "{{ php_extension_conf_paths }}" + +- name: Place PHP configuration file in place. + template: + src: php.ini.j2 + dest: "{{ item }}/php.ini" + owner: root + group: root + mode: 0644 + with_items: "{{ php_conf_paths }}" + notify: restart webserver + when: php_use_managed_ini diff --git a/provisioning/roles/geerlingguy.php/tasks/install-from-source.yml b/provisioning/roles/geerlingguy.php/tasks/install-from-source.yml new file mode 100644 index 000000000..cd18daacf --- /dev/null +++ b/provisioning/roles/geerlingguy.php/tasks/install-from-source.yml @@ -0,0 +1,158 @@ +--- +- name: Ensure dependencies for building from source are installed (RedHat). + package: + name: + - autoconf + - automake + - libtool + - bison + - make + - re2c + - sqlite-devel + - oniguruma-devel + - curl-devel + - recode-devel + - aspell-devel + - libxml2-devel + - pkgconfig + - libmcrypt-devel + - t1lib-devel + - libXpm-devel + - libpng-devel + - libjpeg-turbo-devel + - bzip2-devel + - openssl-devel + - freetype-devel + - libicu-devel + - mariadb-devel + - gmp-devel + state: present + when: ansible_os_family == 'RedHat' + +- name: Update apt cache (Debian). + apt: update_cache=yes cache_valid_time=86400 + when: ansible_os_family == 'Debian' + +- name: Ensure dependencies for building from source are installed (Debian). + apt: + name: + - build-essential + - autoconf + - automake + - libtool + - bison + - pkg-config + - re2c + - libsqlite3-dev + - libonig-dev + - libxml2-dev + - libcurl4-openssl-dev + - libbz2-dev + - libjpeg-dev + - libpng-dev + - libxpm-dev + - libfreetype6-dev + - libgmp3-dev + - libmcrypt-dev + - libmariadbclient-dev + - libpspell-dev + - librecode-dev + - libssl-dev + state: present + when: ansible_os_family == 'Debian' + +- name: Define php_fpm_daemon (if not defined already). + set_fact: + php_fpm_daemon: "php-fpm" + when: php_fpm_daemon is not defined + +- name: Check if gmp.h is already in a location accessible to gcc. + stat: path=/usr/include/gmp.h + register: gmp_file + +- name: Ensure gmp.h is symlinked into a location accessible to gcc. + file: # noqa 208 + src: "{{ php_source_install_gmp_path }}" + dest: /usr/include/gmp.h + state: link + when: not gmp_file.stat.exists + +- name: Check if PHP is installed. + command: which php + changed_when: false + failed_when: false + register: php_installed + +- name: Clone the PHP repository. + git: + repo: "{{ php_source_repo }}" + dest: "{{ php_source_clone_dir }}" + version: "{{ php_source_version }}" + accept_hostkey: true + depth: "{{ php_source_clone_depth }}" + when: php_installed.rc != 0 + +- name: Ensure PHP installation path exists. + file: + path: "{{ php_source_install_path }}" + state: directory + mode: 0755 + when: php_installed.rc != 0 + +- name: Build configure script. + command: > + ./buildconf --force + chdir={{ php_source_clone_dir }} + when: php_installed.rc != 0 + +- name: Run configure script. + command: > + {{ php_source_configure_command }} + chdir={{ php_source_clone_dir }} + when: php_installed.rc != 0 + +- name: Make and install PHP. + command: > + {{ item }} + chdir={{ php_source_clone_dir }} + with_items: + - "{{ php_source_make_command }}" + - make install + when: php_installed.rc != 0 + +- name: Ensure php executable is symlinked into a standard path. + file: # noqa 208 + src: "{{ php_source_install_path }}/bin/php" + dest: /usr/bin/php + state: link + +# PHP FPM configuration. +- name: Ensure php-fpm executable is symlinked into a standard path. + file: # noqa 208 + src: "{{ php_source_install_path }}/sbin/php-fpm" + dest: "/usr/sbin/{{ php_fpm_daemon }}" + state: link + when: "'--enable-fpm' in php_source_configure_command" + +- name: Ensure php-fpm init script is installed. + template: + src: fpm-init.j2 + dest: "/etc/init.d/{{ php_fpm_daemon }}" + mode: 0755 + when: "'--enable-fpm' in php_source_configure_command" + notify: restart php-fpm + +- name: Ensure php-fpm config directory exists. + file: + path: "{{ php_fpm_conf_path }}" + state: directory + mode: 0755 + when: "'--enable-fpm' in php_source_configure_command" + +- name: Ensure php-fpm config file is installed. + template: + src: php-fpm.conf.j2 + dest: "{{ php_fpm_conf_path }}/php-fpm.conf" + mode: 0644 + when: "'--enable-fpm' in php_source_configure_command" + notify: restart php-fpm diff --git a/provisioning/roles/geerlingguy.php/tasks/main.yml b/provisioning/roles/geerlingguy.php/tasks/main.yml new file mode 100644 index 000000000..dbad76595 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/tasks/main.yml @@ -0,0 +1,77 @@ +--- +# Variable setup. +- name: Include distribution and version-specific vars. + include_vars: "{{ item }}" + with_first_found: + - files: + - "{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml" + skip: true + +- name: Set the default PHP version for Debian-based OSes. + set_fact: + php_default_version_debian: "{{ __php_default_version_debian }}" + when: php_default_version_debian is not defined and ansible_os_family == 'Debian' + +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define php_packages. + set_fact: + php_packages: "{{ __php_packages | list }}" + when: php_packages is not defined + +- name: Define php_webserver_daemon. + set_fact: + php_webserver_daemon: "{{ __php_webserver_daemon }}" + when: php_webserver_daemon is not defined + +- name: Define php_conf_paths. + set_fact: + php_conf_paths: "{{ __php_conf_paths }}" + when: php_conf_paths is not defined + +- name: Define php_extension_conf_paths. + set_fact: + php_extension_conf_paths: "{{ __php_extension_conf_paths }}" + when: php_extension_conf_paths is not defined + +- name: Define php_apc_conf_filename. + set_fact: + php_apc_conf_filename: "{{ __php_apc_conf_filename }}" + when: php_apc_conf_filename is not defined + +- name: Define php_opcache_conf_filename (Ubuntu 16.04). + set_fact: + php_opcache_conf_filename: "10-opcache.ini" + when: php_opcache_conf_filename is not defined and ansible_distribution_version == "16.04" + +- name: Define php_opcache_conf_filename. + set_fact: + php_opcache_conf_filename: "{{ __php_opcache_conf_filename }}" + when: php_opcache_conf_filename is not defined + +- name: Define php_fpm_conf_path. + set_fact: + php_fpm_conf_path: "{{ __php_fpm_conf_path }}" + when: php_fpm_conf_path is not defined + +# Setup/install tasks. +- include_tasks: setup-RedHat.yml + when: + - not php_install_from_source + - ansible_os_family == 'RedHat' + +- include_tasks: setup-Debian.yml + when: + - not php_install_from_source + - ansible_os_family == 'Debian' + +# Install PHP from source when php_install_from_source is true. +- include_tasks: install-from-source.yml + when: php_install_from_source + +# Configure PHP. +- include_tasks: configure.yml +- include_tasks: configure-apcu.yml +- include_tasks: configure-opcache.yml +- include_tasks: configure-fpm.yml diff --git a/provisioning/roles/geerlingguy.php/tasks/setup-Debian.yml b/provisioning/roles/geerlingguy.php/tasks/setup-Debian.yml new file mode 100644 index 000000000..a6657be28 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/tasks/setup-Debian.yml @@ -0,0 +1,27 @@ +--- +- name: Update apt cache. + apt: update_cache=yes cache_valid_time=86400 + +- name: Ensure PHP packages are installed. + apt: + name: "{{ php_packages + php_packages_extra }}" + state: "{{ php_packages_state }}" + install_recommends: "{{ php_install_recommends }}" + register: php_package_install + notify: restart webserver + +- name: Delete APCu configuration file if this role will provide one. + file: + path: "{{ item }}/{{ php_apc_conf_filename }}" + state: absent + with_items: "{{ php_extension_conf_paths }}" + when: php_enable_apc and php_package_install.changed + notify: restart webserver + +- name: Delete OpCache configuration file if this role will provide one. + file: + path: "{{ item }}/{{ php_opcache_conf_filename }}" + state: absent + with_items: "{{ php_extension_conf_paths }}" + when: php_opcache_enable | bool and php_package_install.changed + notify: restart webserver diff --git a/provisioning/roles/geerlingguy.php/tasks/setup-RedHat.yml b/provisioning/roles/geerlingguy.php/tasks/setup-RedHat.yml new file mode 100644 index 000000000..1d76b331b --- /dev/null +++ b/provisioning/roles/geerlingguy.php/tasks/setup-RedHat.yml @@ -0,0 +1,7 @@ +--- +- name: Ensure PHP packages are installed. + package: + name: "{{ php_packages + php_packages_extra }}" + state: "{{ php_packages_state }}" + enablerepo: "{{ php_enablerepo | default(omit, true) }}" + notify: restart webserver diff --git a/provisioning/roles/geerlingguy.php/templates/apc.ini.j2 b/provisioning/roles/geerlingguy.php/templates/apc.ini.j2 new file mode 100644 index 000000000..bfd570646 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/templates/apc.ini.j2 @@ -0,0 +1,4 @@ +extension=apcu.so +apc.shm_size={{ php_apc_shm_size }} +apc.enable_cli={{ php_apc_enable_cli }} +apc.rfc1867=1 diff --git a/provisioning/roles/geerlingguy.php/templates/fpm-init.j2 b/provisioning/roles/geerlingguy.php/templates/fpm-init.j2 new file mode 100644 index 000000000..4d6a6d5dc --- /dev/null +++ b/provisioning/roles/geerlingguy.php/templates/fpm-init.j2 @@ -0,0 +1,170 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: php-fpm {{ php_fpm_daemon }} +# Required-Start: $remote_fs $network +# Required-Stop: $remote_fs $network +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: starts {{ php_fpm_daemon }} +# Description: Starts The PHP FastCGI Process Manager Daemon +### END INIT INFO + +# Author: Ondrej Sury <ondrej@debian.org> + +PATH=/sbin:/usr/sbin:/bin:/usr/bin +DESC="PHP FastCGI Process Manager" +NAME={{ php_fpm_daemon }} +DAEMON=/usr/sbin/$NAME +DAEMON_ARGS="--daemonize --fpm-config {{ php_fpm_conf_path }}/php-fpm.conf" +PIDFILE=/var/run/{{ php_fpm_daemon }}.pid +TIMEOUT=2 +SCRIPTNAME=/etc/init.d/$NAME + +# Exit if the package is not installed +[ -x "$DAEMON" ] || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# Don't run if we are running upstart +if init_is_upstart; then + exit 1 +fi + +# +# Function to check the correctness of the config file +# +do_check() +{ + /usr/lib/php5/php5-fpm-checkconf || return 1 + return 0 +} + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ + $DAEMON_ARGS 2>/dev/null \ + || return 2 + # Add code here, if necessary, that waits for the process to be ready + # to handle requests from services started subsequently which depend + # on this one. As a last resort, sleep for some time. +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=QUIT/$TIMEOUT/TERM/5/KILL/5 --pidfile $PIDFILE --name $NAME + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + # Wait for children to finish too if this is a daemon that forks + # and if the daemon is only ever run from this initscript. + # If the above conditions are not satisfied then add some other code + # that waits for the process to drop all resources that could be + # needed by services started subsequently. A last resort is to + # sleep for some time. + start-stop-daemon --stop --quiet --oknodo --retry=0/$TIMEOUT/TERM/5/KILL/5 --exec $DAEMON + [ "$?" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + rm -f $PIDFILE + return "$RETVAL" +} + +# +# Function that sends a SIGHUP to the daemon/service +# +do_reload() { + # + # If the daemon can reload its configuration without + # restarting (for example, when it is sent a SIGHUP), + # then implement that here. + # + start-stop-daemon --stop --signal USR2 --quiet --pidfile $PIDFILE --name $NAME + return 0 +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + status) + status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? + ;; + check) + do_check yes + ;; + reload|force-reload) + log_daemon_msg "Reloading $DESC" "$NAME" + do_reload + log_end_msg $? + ;; + reopen-logs) + log_daemon_msg "Reopening $DESC logs" $NAME + if start-stop-daemon --stop --signal USR1 --oknodo --quiet \ + --pidfile $PIDFILE --exec $DAEMON + then + log_end_msg 0 + else + log_end_msg 1 + fi + ;; + restart) + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload|force-reload}" >&2 + exit 1 + ;; +esac + +: diff --git a/provisioning/roles/geerlingguy.php/templates/opcache.ini.j2 b/provisioning/roles/geerlingguy.php/templates/opcache.ini.j2 new file mode 100644 index 000000000..61464539f --- /dev/null +++ b/provisioning/roles/geerlingguy.php/templates/opcache.ini.j2 @@ -0,0 +1,14 @@ +zend_extension={{ php_opcache_zend_extension }} +opcache.enable={{ php_opcache_enable }} +opcache.enable_cli={{ php_opcache_enable_cli }} +opcache.memory_consumption={{ php_opcache_memory_consumption }} +opcache.interned_strings_buffer={{ php_opcache_interned_strings_buffer }} +opcache.max_accelerated_files={{ php_opcache_max_accelerated_files }} +opcache.max_wasted_percentage={{ php_opcache_max_wasted_percentage }} +opcache.validate_timestamps={{ php_opcache_validate_timestamps }} +opcache.revalidate_path={{ php_opcache_revalidate_path }} +opcache.revalidate_freq={{ php_opcache_revalidate_freq }} +opcache.max_file_size={{ php_opcache_max_file_size }} +{% if php_opcache_blacklist_filename != '' %} +opcache.blacklist_filename={{ php_opcache_blacklist_filename }} +{% endif %} diff --git a/provisioning/roles/geerlingguy.php/templates/php-fpm.conf.j2 b/provisioning/roles/geerlingguy.php/templates/php-fpm.conf.j2 new file mode 100644 index 000000000..12b277fbe --- /dev/null +++ b/provisioning/roles/geerlingguy.php/templates/php-fpm.conf.j2 @@ -0,0 +1,12 @@ +;;;;;;;;;;;;;;;;;;;;; +; FPM Configuration ; +;;;;;;;;;;;;;;;;;;;;; + +include={{ php_fpm_conf_path }}/pool.d/*.conf + +;;;;;;;;;;;;;;;;;; +; Global Options ; +;;;;;;;;;;;;;;;;;; + +[global] +error_log = /var/log/php-fpm.log diff --git a/provisioning/roles/geerlingguy.php/templates/php.ini.j2 b/provisioning/roles/geerlingguy.php/templates/php.ini.j2 new file mode 100644 index 000000000..14b7eeb32 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/templates/php.ini.j2 @@ -0,0 +1,221 @@ +[PHP] + +;;;;;;;;;;;;;;;;;;;; +; Language Options ; +;;;;;;;;;;;;;;;;;;;; + +engine = On +short_open_tag = {{ php_short_open_tag }} +precision = {{ php_precision }} +output_buffering = {{ php_output_buffering }} + +zlib.output_compression = Off + +implicit_flush = Off +unserialize_callback_func = +serialize_precision = {{ php_serialize_precision }} +disable_functions = {{ php_disable_functions|join(",") }} +disable_classes = + +zend.enable_gc = On + +;;;;;;;;;;;;;;;;; +; Miscellaneous ; +;;;;;;;;;;;;;;;;; + +expose_php = {{ php_expose_php }} + +;;;;;;;;;;;;;;;;;;; +; Resource Limits ; +;;;;;;;;;;;;;;;;;;; + +max_execution_time = {{ php_max_execution_time }} +max_input_time = {{ php_max_input_time }} +max_input_vars = {{ php_max_input_vars }} +memory_limit = {{ php_memory_limit }} + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Error handling and logging ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +error_reporting = {{ php_error_reporting }} +display_errors = {{ php_display_errors }} +display_startup_errors = {{ php_display_startup_errors }} +log_errors = On +log_errors_max_len = 1024 +ignore_repeated_errors = Off +ignore_repeated_source = Off +report_memleaks = On +track_errors = Off +html_errors = On + +;;;;;;;;;;;;;;;;; +; Data Handling ; +;;;;;;;;;;;;;;;;; + +variables_order = "GPCS" +request_order = "GP" +register_argc_argv = Off +auto_globals_jit = On + +post_max_size = {{ php_post_max_size }} +auto_prepend_file = +auto_append_file = + +default_mimetype = "text/html" + +;;;;;;;;;;;;;;;;;;;;;;;;; +; Paths and Directories ; +;;;;;;;;;;;;;;;;;;;;;;;;; + +doc_root = +user_dir = + +enable_dl = Off + +realpath_cache_size = {{ php_realpath_cache_size }} + +;;;;;;;;;;;;;;;; +; File Uploads ; +;;;;;;;;;;;;;;;; + +file_uploads = {{ php_file_uploads }} +upload_max_filesize = {{ php_upload_max_filesize }} +max_file_uploads = {{ php_max_file_uploads }} + +;;;;;;;;;;;;;;;;;; +; Fopen wrappers ; +;;;;;;;;;;;;;;;;;; + +allow_url_fopen = {{ php_allow_url_fopen }} +allow_url_include = Off + +default_socket_timeout = 60 + +;;;;;;;;;;;;;;;;;;; +; Module Settings ; +;;;;;;;;;;;;;;;;;;; + +[CLI Server] +cli_server.color = On + +[Date] +date.timezone = {{ php_date_timezone }} + +[Pdo_mysql] +pdo_mysql.cache_size = 2000 +pdo_mysql.default_socket= + +[mail function] +; For Win32 only. +SMTP = localhost +smtp_port = 25 + +; For Unix only. You may supply arguments as well (default: "sendmail -t -i"). +sendmail_path = {{ php_sendmail_path }} + +mail.add_x_header = On + +[SQL] +sql.safe_mode = Off + +[ODBC] +odbc.allow_persistent = On +odbc.check_persistent = On +odbc.max_persistent = -1 +odbc.max_links = -1 +odbc.defaultlrl = 4096 +odbc.defaultbinmode = 1 + +[MySQL] +mysql.allow_local_infile = On +mysql.allow_persistent = On +mysql.cache_size = 2000 +mysql.max_persistent = -1 +mysql.max_links = -1 +mysql.default_port = +mysql.default_socket = +mysql.default_host = +mysql.default_user = +mysql.default_password = +mysql.connect_timeout = 60 +mysql.trace_mode = Off + +[MySQLi] +mysqli.max_persistent = -1 +mysqli.allow_persistent = On +mysqli.max_links = -1 +mysqli.cache_size = 2000 +mysqli.default_port = 3306 +mysqli.default_socket = +mysqli.default_host = +mysqli.default_user = +mysqli.default_pw = +mysqli.reconnect = Off + +[mysqlnd] +mysqlnd.collect_statistics = On +mysqlnd.collect_memory_statistics = Off + +[PostgreSQL] +pgsql.allow_persistent = On +pgsql.auto_reset_persistent = Off +pgsql.max_persistent = -1 +pgsql.max_links = -1 +pgsql.ignore_notice = 0 +pgsql.log_notice = 0 + +[bcmath] +bcmath.scale = 0 + +[Session] +session.save_handler = {{ php_session_save_handler }} +session.save_path = {{ php_session_save_path }} +session.use_cookies = 1 +session.use_only_cookies = 1 +session.name = PHPSESSID +session.auto_start = 0 + +session.cookie_lifetime = {{ php_session_cookie_lifetime }} +session.cookie_path = / +session.cookie_domain = +session.cookie_httponly = + +session.serialize_handler = php + +session.gc_probability = {{ php_session_gc_probability }} +session.gc_divisor = {{ php_session_gc_divisor }} +session.gc_maxlifetime = {{ php_session_gc_maxlifetime }} + +session.referer_check = + +session.cache_limiter = nocache +session.cache_expire = 180 + +session.use_trans_sid = 0 + +session.hash_function = 0 +session.hash_bits_per_character = 5 + +url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" + +[MSSQL] +mssql.allow_persistent = On +mssql.max_persistent = -1 +mssql.max_links = -1 +mssql.min_error_severity = 10 +mssql.min_message_severity = 10 +mssql.compatability_mode = Off +mssql.secure_connection = Off + +[Tidy] +tidy.clean_output = Off + +[soap] +soap.wsdl_cache_enabled=1 +soap.wsdl_cache_dir="/tmp" +soap.wsdl_cache_ttl=86400 +soap.wsdl_cache_limit = 5 + +[ldap] +ldap.max_links = -1 diff --git a/provisioning/roles/geerlingguy.php/templates/www.conf.j2 b/provisioning/roles/geerlingguy.php/templates/www.conf.j2 new file mode 100644 index 000000000..b206cce6f --- /dev/null +++ b/provisioning/roles/geerlingguy.php/templates/www.conf.j2 @@ -0,0 +1,17 @@ +; {{ ansible_managed }} + +[{{ item.pool_name | mandatory }}] +listen = {{ item.pool_listen | mandatory }} +listen.allowed_clients = {{ item.pool_listen_allowed_clients | default('127.0.0.1', true) }} +user = {{ php_fpm_pool_user }} +group = {{ php_fpm_pool_group }} + +listen.owner = {{ php_fpm_pool_user }} +listen.group = {{ php_fpm_pool_group }} + +pm = {{ item.pool_pm | default('dynamic', true) }} +pm.max_children = {{ item.pool_pm_max_children | default(50, true) }} +pm.start_servers = {{ item.pool_pm_start_servers | default(5, true) }} +pm.min_spare_servers = {{ item.pool_pm_min_spare_servers | default(5, true) }} +pm.max_spare_servers = {{ item.pool_pm_max_spare_servers | default(5, true) }} +pm.max_requests = {{ item.pool_pm_max_requests | default(500, true) }} diff --git a/provisioning/roles/geerlingguy.php/vars/Debian-10.yml b/provisioning/roles/geerlingguy.php/vars/Debian-10.yml new file mode 100644 index 000000000..ec895aec3 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/vars/Debian-10.yml @@ -0,0 +1,2 @@ +--- +__php_default_version_debian: "7.3" diff --git a/provisioning/roles/geerlingguy.php/vars/Debian-11.yml b/provisioning/roles/geerlingguy.php/vars/Debian-11.yml new file mode 100644 index 000000000..a16b99b15 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/vars/Debian-11.yml @@ -0,0 +1,2 @@ +--- +__php_default_version_debian: "7.4" diff --git a/provisioning/roles/geerlingguy.php/vars/Debian-9.yml b/provisioning/roles/geerlingguy.php/vars/Debian-9.yml new file mode 100644 index 000000000..eb23ce3a0 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/vars/Debian-9.yml @@ -0,0 +1,2 @@ +--- +__php_default_version_debian: "7.0" diff --git a/provisioning/roles/geerlingguy.php/vars/Debian.yml b/provisioning/roles/geerlingguy.php/vars/Debian.yml new file mode 100644 index 000000000..c487fd8a5 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/vars/Debian.yml @@ -0,0 +1,39 @@ +--- +__php_default_version_debian: "7.0" + +__php_packages: + - php{{ php_default_version_debian }}-common + - php{{ php_default_version_debian }}-cli + - php{{ php_default_version_debian }}-dev + - php{{ php_default_version_debian }}-fpm + - libpcre3-dev + - php{{ php_default_version_debian }}-gd + - php{{ php_default_version_debian }}-curl + - php{{ php_default_version_debian }}-imap + - php{{ php_default_version_debian }}-json + - php{{ php_default_version_debian }}-opcache + - php{{ php_default_version_debian }}-xml + - php{{ php_default_version_debian }}-mbstring + - php-sqlite3 + - php-apcu +__php_webserver_daemon: "apache2" + +# Vendor-specific configuration paths on Debian/Ubuntu make my brain asplode. +__php_conf_paths: + - /etc/php/{{ php_default_version_debian }}/fpm + - /etc/php/{{ php_default_version_debian }}/apache2 + - /etc/php/{{ php_default_version_debian }}/cli + +__php_extension_conf_paths: + - /etc/php/{{ php_default_version_debian }}/fpm/conf.d + - /etc/php/{{ php_default_version_debian }}/apache2/conf.d + - /etc/php/{{ php_default_version_debian }}/cli/conf.d + +__php_apc_conf_filename: 20-apcu.ini +__php_opcache_conf_filename: 10-opcache.ini +__php_fpm_daemon: php{{ php_default_version_debian }}-fpm +__php_fpm_conf_path: "/etc/php/{{ php_default_version_debian }}/fpm" +__php_fpm_pool_conf_path: "{{ __php_fpm_conf_path }}/pool.d/www.conf" + +__php_fpm_pool_user: www-data +__php_fpm_pool_group: www-data diff --git a/provisioning/roles/geerlingguy.php/vars/RedHat.yml b/provisioning/roles/geerlingguy.php/vars/RedHat.yml new file mode 100644 index 000000000..e1e4458d7 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/vars/RedHat.yml @@ -0,0 +1,32 @@ +--- +__php_packages: + - php + - php-cli + - php-common + - php-devel + - php-fpm + - php-gd + - php-ldap + - php-mbstring + - php-opcache + - php-pdo + - php-pear + - php-pecl-apcu + - php-xml + - php-xmlrpc +__php_webserver_daemon: "httpd" + +__php_conf_paths: + - /etc + +__php_extension_conf_paths: + - /etc/php.d + +__php_apc_conf_filename: 50-apc.ini +__php_opcache_conf_filename: 10-opcache.ini +__php_fpm_daemon: php-fpm +__php_fpm_conf_path: "/etc/fpm" +__php_fpm_pool_conf_path: "/etc/php-fpm.d/www.conf" + +__php_fpm_pool_user: apache +__php_fpm_pool_group: apache diff --git a/provisioning/roles/geerlingguy.php/vars/Ubuntu-16.yml b/provisioning/roles/geerlingguy.php/vars/Ubuntu-16.yml new file mode 100644 index 000000000..eb23ce3a0 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/vars/Ubuntu-16.yml @@ -0,0 +1,2 @@ +--- +__php_default_version_debian: "7.0" diff --git a/provisioning/roles/geerlingguy.php/vars/Ubuntu-18.yml b/provisioning/roles/geerlingguy.php/vars/Ubuntu-18.yml new file mode 100644 index 000000000..82230bcd7 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/vars/Ubuntu-18.yml @@ -0,0 +1,2 @@ +--- +__php_default_version_debian: "7.2" diff --git a/provisioning/roles/geerlingguy.php/vars/Ubuntu-20.yml b/provisioning/roles/geerlingguy.php/vars/Ubuntu-20.yml new file mode 100644 index 000000000..a16b99b15 --- /dev/null +++ b/provisioning/roles/geerlingguy.php/vars/Ubuntu-20.yml @@ -0,0 +1,2 @@ +--- +__php_default_version_debian: "7.4" diff --git a/provisioning/roles/geerlingguy.postfix/.gitignore b/provisioning/roles/geerlingguy.postfix/.gitignore new file mode 100644 index 000000000..c9b2377e3 --- /dev/null +++ b/provisioning/roles/geerlingguy.postfix/.gitignore @@ -0,0 +1,2 @@ +*.retry +tests/test.sh diff --git a/provisioning/roles/geerlingguy.postfix/.travis.yml b/provisioning/roles/geerlingguy.postfix/.travis.yml new file mode 100644 index 000000000..e4a7f31a7 --- /dev/null +++ b/provisioning/roles/geerlingguy.postfix/.travis.yml @@ -0,0 +1,18 @@ +--- +services: docker + +env: + - distro: centos7 + - distro: ubuntu1604 + - distro: debian9 + +script: + # Download test shim. + - wget -O ${PWD}/tests/test.sh https://gist.githubusercontent.com/geerlingguy/73ef1e5ee45d8694570f334be385e181/raw/ + - chmod +x ${PWD}/tests/test.sh + + # Run tests. + - ${PWD}/tests/test.sh + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.postfix/LICENSE b/provisioning/roles/geerlingguy.postfix/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.postfix/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.postfix/README.md b/provisioning/roles/geerlingguy.postfix/README.md new file mode 100644 index 000000000..8e71655d1 --- /dev/null +++ b/provisioning/roles/geerlingguy.postfix/README.md @@ -0,0 +1,45 @@ +# Ansible Role: Postfix + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-postfix.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-postfix) + +Installs postfix on RedHat/CentOS or Debian/Ubuntu. + +## Requirements + +If you're using this as an SMTP relay server, you will need to do that on your own, and open TCP port 25 in your server firewall. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + postfix_config_file: /etc/postfix/main.cf + +The path to the Postfix `main.cf` configuration file. + + postfix_service_state: started + postfix_service_enabled: yes + +The state in which the Postfix service should be after this role runs, and whether to enable the service on startup. + + postfix_inet_interfaces: localhost + postfix_inet_protocols: all + +Options for values `inet_interfaces` and `inet_protocols` in the `main.cf` file. + +## Dependencies + +None. + +## Example Playbook + + - hosts: all + roles: + - geerlingguy.postfix + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.postfix/defaults/main.yml b/provisioning/roles/geerlingguy.postfix/defaults/main.yml new file mode 100644 index 000000000..73d244012 --- /dev/null +++ b/provisioning/roles/geerlingguy.postfix/defaults/main.yml @@ -0,0 +1,8 @@ +--- +postfix_config_file: /etc/postfix/main.cf + +postfix_service_state: started +postfix_service_enabled: yes + +postfix_inet_interfaces: localhost +postfix_inet_protocols: all diff --git a/provisioning/roles/geerlingguy.postfix/handlers/main.yml b/provisioning/roles/geerlingguy.postfix/handlers/main.yml new file mode 100644 index 000000000..ec7fb0508 --- /dev/null +++ b/provisioning/roles/geerlingguy.postfix/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: restart postfix + service: name=postfix state=restarted diff --git a/provisioning/roles/geerlingguy.postfix/meta/main.yml b/provisioning/roles/geerlingguy.postfix/meta/main.yml new file mode 100644 index 000000000..1f034f178 --- /dev/null +++ b/provisioning/roles/geerlingguy.postfix/meta/main.yml @@ -0,0 +1,23 @@ +--- +dependencies: [] + +galaxy_info: + author: geerlingguy + description: Postfix for RedHat/CentOS or Debian/Ubuntu. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 1.8 + platforms: + - name: EL + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + galaxy_tags: + - networking + - system + - mail diff --git a/provisioning/roles/geerlingguy.postfix/tasks/main.yml b/provisioning/roles/geerlingguy.postfix/tasks/main.yml new file mode 100644 index 000000000..af245a8f0 --- /dev/null +++ b/provisioning/roles/geerlingguy.postfix/tasks/main.yml @@ -0,0 +1,23 @@ +--- +- name: Ensure postfix is installed. + package: + name: postfix + state: present + +- name: Update Postfix configuration. + lineinfile: + dest: "{{ postfix_config_file }}" + line: "{{ item.name }} = {{ item.value }}" + regexp: "^{{ item.name }} =" + with_items: + - name: inet_interfaces + value: "{{ postfix_inet_interfaces }}" + - name: inet_protocols + value: "{{ postfix_inet_protocols }}" + notify: restart postfix + +- name: Ensure postfix is started and enabled at boot. + service: + name: postfix + state: "{{ postfix_service_state }}" + enabled: "{{ postfix_service_enabled }}" diff --git a/provisioning/roles/geerlingguy.postfix/tests/README.md b/provisioning/roles/geerlingguy.postfix/tests/README.md new file mode 100644 index 000000000..6fb211721 --- /dev/null +++ b/provisioning/roles/geerlingguy.postfix/tests/README.md @@ -0,0 +1,11 @@ +# Ansible Role tests + +To run the test playbook(s) in this directory: + + 1. Install and start Docker. + 1. Download the test shim (see .travis.yml file for the URL) into `tests/test.sh`: + - `wget -O tests/test.sh https://gist.githubusercontent.com/geerlingguy/73ef1e5ee45d8694570f334be385e181/raw/` + 1. Make the test shim executable: `chmod +x tests/test.sh`. + 1. Run (from the role root directory) `distro=[distro] playbook=[playbook] ./tests/test.sh` + +If you don't want the container to be automatically deleted after the test playbook is run, add the following environment variables: `cleanup=false container_id=$(date +%s)` diff --git a/provisioning/roles/geerlingguy.postfix/tests/test.yml b/provisioning/roles/geerlingguy.postfix/tests/test.yml new file mode 100644 index 000000000..2505c1d66 --- /dev/null +++ b/provisioning/roles/geerlingguy.postfix/tests/test.yml @@ -0,0 +1,15 @@ +--- +- hosts: all + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + + - name: Override postfix_inet_protocols (RHEL). + set_fact: + postfix_inet_protocols: ipv4 + when: ansible_os_family == 'RedHat' + + roles: + - role_under_test diff --git a/provisioning/roles/geerlingguy.postgresql/.ansible-lint b/provisioning/roles/geerlingguy.postgresql/.ansible-lint new file mode 100644 index 000000000..4b5e4fde5 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/.ansible-lint @@ -0,0 +1,4 @@ +skip_list: + - 'yaml' + - 'no-handler' + - 'role-name' diff --git a/provisioning/roles/geerlingguy.postgresql/.github/FUNDING.yml b/provisioning/roles/geerlingguy.postgresql/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.postgresql/.github/stale.yml b/provisioning/roles/geerlingguy.postgresql/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.postgresql/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.postgresql/.github/workflows/ci.yml new file mode 100644 index 000000000..254f61f9c --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/.github/workflows/ci.yml @@ -0,0 +1,70 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "0 3 * * 5" + +defaults: + run: + working-directory: 'geerlingguy.postgresql' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.postgresql' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + distro: + - centos8 + - centos7 + - fedora32 + - ubuntu2004 + - ubuntu1804 + - debian10 + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.postgresql' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} diff --git a/provisioning/roles/geerlingguy.postgresql/.github/workflows/release.yml b/provisioning/roles/geerlingguy.postgresql/.github/workflows/release.yml new file mode 100644 index 000000000..e1f8ae623 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.postgresql' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.postgresql' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.postgresql/.gitignore b/provisioning/roles/geerlingguy.postgresql/.gitignore new file mode 100644 index 000000000..8840c8f02 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/.gitignore @@ -0,0 +1,5 @@ +*.retry +*/__pycache__ +*.pyc +.cache + diff --git a/provisioning/roles/geerlingguy.postgresql/.yamllint b/provisioning/roles/geerlingguy.postgresql/.yamllint new file mode 100644 index 000000000..f2033dd21 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/provisioning/roles/geerlingguy.postgresql/LICENSE b/provisioning/roles/geerlingguy.postgresql/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.postgresql/README.md b/provisioning/roles/geerlingguy.postgresql/README.md new file mode 100644 index 000000000..a30ec2227 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/README.md @@ -0,0 +1,149 @@ +# Ansible Role: PostgreSQL + +[![CI](https://github.com/geerlingguy/ansible-role-postgresql/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-postgresql/actions?query=workflow%3ACI) + +Installs and configures PostgreSQL server on RHEL/CentOS or Debian/Ubuntu servers. + +## Requirements + +No special requirements; note that this role requires root access, so either run it in a playbook with a global `become: yes`, or invoke the role in your playbook like: + + - hosts: database + roles: + - role: geerlingguy.postgresql + become: yes + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + postgresql_enablerepo: "" + +(RHEL/CentOS only) You can set a repo to use for the PostgreSQL installation by passing it in here. + + postgresql_restarted_state: "restarted" + +Set the state of the service when configuration changes are made. Recommended values are `restarted` or `reloaded`. + + postgresql_python_library: python-psycopg2 + +Library used by Ansible to communicate with PostgreSQL. If you are using Python 3 (e.g. set via `ansible_python_interpreter`), you should change this to `python3-psycopg2`. + + postgresql_user: postgres + postgresql_group: postgres + +The user and group under which PostgreSQL will run. + + postgresql_unix_socket_directories: + - /var/run/postgresql + +The directories (usually one, but can be multiple) where PostgreSQL's socket will be created. + + postgresql_service_state: started + postgresql_service_enabled: true + +Control the state of the postgresql service and whether it should start at boot time. + + postgresql_global_config_options: + - option: unix_socket_directories + value: '{{ postgresql_unix_socket_directories | join(",") }}' + +Global configuration options that will be set in `postgresql.conf`. Note that for RHEL/CentOS 6 (or very old versions of PostgreSQL), you need to at least override this variable and set the `option` to `unix_socket_directory`. + + postgresql_hba_entries: + - { type: local, database: all, user: postgres, auth_method: peer } + - { type: local, database: all, user: all, auth_method: peer } + - { type: host, database: all, user: all, address: '127.0.0.1/32', auth_method: md5 } + - { type: host, database: all, user: all, address: '::1/128', auth_method: md5 } + +Configure [host based authentication](https://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html) entries to be set in the `pg_hba.conf`. Options for entries include: + + - `type` (required) + - `database` (required) + - `user` (required) + - `address` (one of this or the following two are required) + - `ip_address` + - `ip_mask` + - `auth_method` (required) + - `auth_options` (optional) + +If overriding, make sure you copy all of the existing entries from `defaults/main.yml` if you need to preserve existing entries. + + postgresql_locales: + - 'en_US.UTF-8' + +(Debian/Ubuntu only) Used to generate the locales used by PostgreSQL databases. + + postgresql_databases: + - name: exampledb # required; the rest are optional + lc_collate: # defaults to 'en_US.UTF-8' + lc_ctype: # defaults to 'en_US.UTF-8' + encoding: # defaults to 'UTF-8' + template: # defaults to 'template0' + login_host: # defaults to 'localhost' + login_password: # defaults to not set + login_user: # defaults to 'postgresql_user' + login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories + port: # defaults to not set + owner: # defaults to postgresql_user + state: # defaults to 'present' + +A list of databases to ensure exist on the server. Only the `name` is required; all other properties are optional. + + postgresql_users: + - name: jdoe #required; the rest are optional + password: # defaults to not set + encrypted: # defaults to not set + priv: # defaults to not set + role_attr_flags: # defaults to not set + db: # defaults to not set + login_host: # defaults to 'localhost' + login_password: # defaults to not set + login_user: # defaults to '{{ postgresql_user }}' + login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories + port: # defaults to not set + state: # defaults to 'present' + +A list of users to ensure exist on the server. Only the `name` is required; all other properties are optional. + + postgres_users_no_log: true + +Whether to output user data (which may contain sensitive information, like passwords) when managing users. + + postgresql_version: [OS-specific] + postgresql_data_dir: [OS-specific] + postgresql_bin_path: [OS-specific] + postgresql_config_path: [OS-specific] + postgresql_daemon: [OS-specific] + postgresql_packages: [OS-specific] + +OS-specific variables that are set by include files in this role's `vars` directory. These shouldn't be overridden unless you're using a version of PostgreSQL that wasn't installed using system packages. + +## Dependencies + +None. + +## Example Playbook + + - hosts: database + become: yes + vars_files: + - vars/main.yml + roles: + - geerlingguy.postgresql + +*Inside `vars/main.yml`*: + + postgresql_databases: + - name: example_db + postgresql_users: + - name: example_user + password: supersecure + +## License + +MIT / BSD + +## Author Information + +This role was created in 2016 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.postgresql/defaults/main.yml b/provisioning/roles/geerlingguy.postgresql/defaults/main.yml new file mode 100644 index 000000000..4e1677969 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/defaults/main.yml @@ -0,0 +1,70 @@ +--- +# RHEL/CentOS only. Set a repository to use for PostgreSQL installation. +postgresql_enablerepo: "" + +# Set postgresql state when configuration changes are made. Recommended values: +# `restarted` or `reloaded` +postgresql_restarted_state: "restarted" + +postgresql_python_library: python-psycopg2 +postgresql_user: postgres +postgresql_group: postgres + +# `md5` or `scram-sha-256` (https://www.postgresql.org/docs/10/auth-methods.html) +postgresql_auth_method: "{{ ansible_fips | ternary('scram-sha-256', 'md5') }}" + +postgresql_unix_socket_directories: + - /var/run/postgresql + +postgresql_service_state: started +postgresql_service_enabled: true + +# Global configuration options that will be set in postgresql.conf. +postgresql_global_config_options: + - option: unix_socket_directories + value: '{{ postgresql_unix_socket_directories | join(",") }}' + +# Host based authentication (hba) entries to be added to the pg_hba.conf. This +# variable's defaults reflect the defaults that come with a fresh installation. +postgresql_hba_entries: + - {type: local, database: all, user: postgres, auth_method: peer} + - {type: local, database: all, user: all, auth_method: peer} + - {type: host, database: all, user: all, address: '127.0.0.1/32', auth_method: "{{ postgresql_auth_method }}"} + - {type: host, database: all, user: all, address: '::1/128', auth_method: "{{ postgresql_auth_method }}"} + +# Debian only. Used to generate the locales used by PostgreSQL databases. +postgresql_locales: + - 'en_US.UTF-8' + +# Databases to ensure exist. +postgresql_databases: [] +# - name: exampledb # required; the rest are optional +# lc_collate: # defaults to 'en_US.UTF-8' +# lc_ctype: # defaults to 'en_US.UTF-8' +# encoding: # defaults to 'UTF-8' +# template: # defaults to 'template0' +# login_host: # defaults to 'localhost' +# login_password: # defaults to not set +# login_user: # defaults to '{{ postgresql_user }}' +# login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories +# port: # defaults to not set +# owner: # defaults to postgresql_user +# state: # defaults to 'present' + +# Users to ensure exist. +postgresql_users: [] +# - name: jdoe #required; the rest are optional +# password: # defaults to not set +# encrypted: # defaults to not set +# priv: # defaults to not set +# role_attr_flags: # defaults to not set +# db: # defaults to not set +# login_host: # defaults to 'localhost' +# login_password: # defaults to not set +# login_user: # defaults to '{{ postgresql_user }}' +# login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories +# port: # defaults to not set +# state: # defaults to 'present' + +# Whether to output user data when managing users. +postgres_users_no_log: true diff --git a/provisioning/roles/geerlingguy.postgresql/handlers/main.yml b/provisioning/roles/geerlingguy.postgresql/handlers/main.yml new file mode 100644 index 000000000..cce42b722 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: restart postgresql + service: + name: "{{ postgresql_daemon }}" + state: "{{ postgresql_restarted_state }}" + sleep: 5 diff --git a/provisioning/roles/geerlingguy.postgresql/meta/main.yml b/provisioning/roles/geerlingguy.postgresql/meta/main.yml new file mode 100644 index 000000000..411689b51 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/meta/main.yml @@ -0,0 +1,37 @@ +--- +dependencies: [] + +galaxy_info: + role_name: postgresql + author: geerlingguy + description: PostgreSQL server for Linux. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.8 + platforms: + - name: EL + versions: + - 7 + - 8 + - name: Fedora + versions: + - 30 + - 31 + - 32 + - 33 + - name: Ubuntu + versions: + - xenial + - bionic + - focal + - name: Debian + versions: + - wheezy + - jessie + - stretch + - buster + galaxy_tags: + - database + - postgresql + - postgres + - rdbms diff --git a/provisioning/roles/geerlingguy.postgresql/molecule/default/converge.yml b/provisioning/roles/geerlingguy.postgresql/molecule/default/converge.yml new file mode 100644 index 000000000..8def2ca8b --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/molecule/default/converge.yml @@ -0,0 +1,37 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + postgresql_databases: + - name: example + postgresql_users: + - name: jdoe + + pre_tasks: + # The Fedora 30+ container images have only C.UTF-8 installed + - name: Set database locale if using Fedora 30+ or RedHat 8+ + set_fact: + postgresql_databases: + - name: example + lc_collate: 'C.UTF-8' + lc_ctype: 'C.UTF-8' + when: + - ( ansible_distribution == 'Fedora' and ansible_distribution_major_version >= '30') or + ( ansible_os_family == 'RedHat' and ansible_distribution_major_version == '8') + + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + changed_when: false + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.postgresql + + post_tasks: + - name: Verify postgres is running. + command: "{{ postgresql_bin_path }}/pg_ctl -D {{ postgresql_data_dir }} status" + changed_when: false + become: true + become_user: postgres diff --git a/provisioning/roles/geerlingguy.postgresql/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.postgresql/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.postgresql/tasks/configure.yml b/provisioning/roles/geerlingguy.postgresql/tasks/configure.yml new file mode 100644 index 000000000..df4346450 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/tasks/configure.yml @@ -0,0 +1,29 @@ +--- +- name: Configure global settings. + lineinfile: + dest: "{{ postgresql_config_path }}/postgresql.conf" + regexp: "^#?{{ item.option }}.+$" + line: "{{ item.option }} = '{{ item.value }}'" + state: "{{ item.state | default('present') }}" + mode: 0644 + with_items: "{{ postgresql_global_config_options }}" + notify: restart postgresql + +- name: Configure host based authentication (if entries are configured). + template: + src: "pg_hba.conf.j2" + dest: "{{ postgresql_config_path }}/pg_hba.conf" + owner: "{{ postgresql_user }}" + group: "{{ postgresql_group }}" + mode: 0600 + notify: restart postgresql + when: postgresql_hba_entries | length > 0 + +- name: Ensure PostgreSQL unix socket dirs exist. + file: + path: "{{ item }}" + state: directory + owner: "{{ postgresql_user }}" + group: "{{ postgresql_group }}" + mode: "{{ postgresql_unix_socket_directories_mode }}" + with_items: "{{ postgresql_unix_socket_directories }}" diff --git a/provisioning/roles/geerlingguy.postgresql/tasks/databases.yml b/provisioning/roles/geerlingguy.postgresql/tasks/databases.yml new file mode 100644 index 000000000..e01d804d4 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/tasks/databases.yml @@ -0,0 +1,21 @@ +--- +- name: Ensure PostgreSQL databases are present. + postgresql_db: + name: "{{ item.name }}" + lc_collate: "{{ item.lc_collate | default('en_US.UTF-8') }}" + lc_ctype: "{{ item.lc_ctype | default('en_US.UTF-8') }}" + encoding: "{{ item.encoding | default('UTF-8') }}" + template: "{{ item.template | default('template0') }}" + login_host: "{{ item.login_host | default('localhost') }}" + login_password: "{{ item.login_password | default(omit) }}" + login_user: "{{ item.login_user | default(postgresql_user) }}" + login_unix_socket: "{{ item.login_unix_socket | default(postgresql_unix_socket_directories[0]) }}" + port: "{{ item.port | default(omit) }}" + owner: "{{ item.owner | default(postgresql_user) }}" + state: "{{ item.state | default('present') }}" + with_items: "{{ postgresql_databases }}" + become: true + become_user: "{{ postgresql_user }}" + # See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509 + vars: + ansible_ssh_pipelining: true diff --git a/provisioning/roles/geerlingguy.postgresql/tasks/initialize.yml b/provisioning/roles/geerlingguy.postgresql/tasks/initialize.yml new file mode 100644 index 000000000..018312114 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/tasks/initialize.yml @@ -0,0 +1,29 @@ +--- +- name: Set PostgreSQL environment variables. + template: + src: postgres.sh.j2 + dest: /etc/profile.d/postgres.sh + mode: 0644 + notify: restart postgresql + +- name: Ensure PostgreSQL data directory exists. + file: + path: "{{ postgresql_data_dir }}" + owner: "{{ postgresql_user }}" + group: "{{ postgresql_group }}" + state: directory + mode: 0700 + +- name: Check if PostgreSQL database is initialized. + stat: + path: "{{ postgresql_data_dir }}/PG_VERSION" + register: pgdata_dir_version + +- name: Ensure PostgreSQL database is initialized. + command: "{{ postgresql_bin_path }}/initdb -D {{ postgresql_data_dir }}" + when: not pgdata_dir_version.stat.exists + become: true + become_user: "{{ postgresql_user }}" + # See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509 + vars: + ansible_ssh_pipelining: true diff --git a/provisioning/roles/geerlingguy.postgresql/tasks/main.yml b/provisioning/roles/geerlingguy.postgresql/tasks/main.yml new file mode 100644 index 000000000..308f38e38 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/tasks/main.yml @@ -0,0 +1,24 @@ +--- +# Variable configuration. +- include_tasks: variables.yml + +# Setup/install tasks. +- include_tasks: setup-RedHat.yml + when: ansible_os_family == 'RedHat' + +- include_tasks: setup-Debian.yml + when: ansible_os_family == 'Debian' + +- include_tasks: initialize.yml +- include_tasks: configure.yml + +- name: Ensure PostgreSQL is started and enabled on boot. + service: + name: "{{ postgresql_daemon }}" + state: "{{ postgresql_service_state }}" + enabled: "{{ postgresql_service_enabled }}" + +# Configure PostgreSQL. +- import_tasks: users.yml +- import_tasks: databases.yml +- import_tasks: users_props.yml diff --git a/provisioning/roles/geerlingguy.postgresql/tasks/setup-Debian.yml b/provisioning/roles/geerlingguy.postgresql/tasks/setup-Debian.yml new file mode 100644 index 000000000..1b540196f --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/tasks/setup-Debian.yml @@ -0,0 +1,21 @@ +--- +- name: Ensure PostgreSQL Python libraries are installed. + apt: + name: "{{ postgresql_python_library }}" + state: present + +- name: Ensure PostgreSQL packages are installed. + apt: + name: "{{ postgresql_packages }}" + state: present + +- name: Ensure all configured locales are present. + locale_gen: "name={{ item }} state=present" + with_items: "{{ postgresql_locales }}" + register: locale_gen_result + +- name: Force-restart PostgreSQL after new locales are generated. + service: + name: "{{ postgresql_daemon }}" + state: restarted + when: locale_gen_result.changed diff --git a/provisioning/roles/geerlingguy.postgresql/tasks/setup-RedHat.yml b/provisioning/roles/geerlingguy.postgresql/tasks/setup-RedHat.yml new file mode 100644 index 000000000..d536bcb01 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/tasks/setup-RedHat.yml @@ -0,0 +1,16 @@ +--- +- name: Ensure PostgreSQL packages are installed. + yum: + name: "{{ postgresql_packages }}" + state: present + enablerepo: "{{ postgresql_enablerepo | default(omit, true) }}" + # Don't let postgresql-contrib cause the /usr/bin/python symlink + # to be installed, which breaks later Ansible runs on Fedora 30, + # and affects system behavior in multiple ways. + exclude: python-unversioned-command + +- name: Ensure PostgreSQL Python libraries are installed. + yum: + name: "{{ postgresql_python_library }}" + state: present + enablerepo: "{{ postgresql_enablerepo | default(omit, true) }}" diff --git a/provisioning/roles/geerlingguy.postgresql/tasks/users.yml b/provisioning/roles/geerlingguy.postgresql/tasks/users.yml new file mode 100644 index 000000000..6cbae0150 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/tasks/users.yml @@ -0,0 +1,19 @@ +--- +- name: Ensure PostgreSQL users are present. + postgresql_user: + name: "{{ item.name }}" + password: "{{ item.password | default(omit) }}" + login_host: "{{ item.login_host | default('localhost') }}" + login_password: "{{ item.login_password | default(omit) }}" + login_user: "{{ item.login_user | default(postgresql_user) }}" + login_unix_socket: "{{ item.login_unix_socket | default(postgresql_unix_socket_directories[0]) }}" + port: "{{ item.port | default(omit) }}" + with_items: "{{ postgresql_users }}" + no_log: "{{ postgres_users_no_log }}" + become: true + become_user: "{{ postgresql_user }}" + # See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509 + vars: + ansible_ssh_pipelining: true + environment: + PGOPTIONS: "{{ (postgresql_auth_method == 'scram-sha-256') | ternary('-c password_encryption=scram-sha-256', '') }}" diff --git a/provisioning/roles/geerlingguy.postgresql/tasks/users_props.yml b/provisioning/roles/geerlingguy.postgresql/tasks/users_props.yml new file mode 100644 index 000000000..992ccf5c9 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/tasks/users_props.yml @@ -0,0 +1,24 @@ +--- +- name: Ensure PostgreSQL users are configured correctly. + postgresql_user: + name: "{{ item.name }}" + password: "{{ item.password | default(omit) }}" + encrypted: "{{ item.encrypted | default(omit) }}" + priv: "{{ item.priv | default(omit) }}" + role_attr_flags: "{{ item.role_attr_flags | default(omit) }}" + db: "{{ item.db | default(omit) }}" + login_host: "{{ item.login_host | default('localhost') }}" + login_password: "{{ item.login_password | default(omit) }}" + login_user: "{{ item.login_user | default(postgresql_user) }}" + login_unix_socket: "{{ item.login_unix_socket | default(postgresql_unix_socket_directories[0]) }}" + port: "{{ item.port | default(omit) }}" + state: "{{ item.state | default('present') }}" + with_items: "{{ postgresql_users }}" + no_log: "{{ postgres_users_no_log }}" + become: true + become_user: "{{ postgresql_user }}" + # See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509 + vars: + ansible_ssh_pipelining: true + environment: + PGOPTIONS: "{{ (postgresql_auth_method == 'scram-sha-256') | ternary('-c password_encryption=scram-sha-256', '') }}" diff --git a/provisioning/roles/geerlingguy.postgresql/tasks/variables.yml b/provisioning/roles/geerlingguy.postgresql/tasks/variables.yml new file mode 100644 index 000000000..575897207 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/tasks/variables.yml @@ -0,0 +1,51 @@ +--- +# Variable configuration. +- name: Include OS-specific variables (Debian). + include_vars: "{{ ansible_distribution }}-{{ ansible_distribution_version.split('.')[0] }}.yml" + when: ansible_os_family == 'Debian' + +- name: Include OS-specific variables (RedHat). + include_vars: "{{ ansible_os_family }}-{{ ansible_distribution_version.split('.')[0] }}.yml" + when: + - ansible_os_family == 'RedHat' + - ansible_distribution != 'Fedora' + +- name: Include OS-specific variables (Fedora). + include_vars: "{{ ansible_distribution }}-{{ ansible_distribution_version.split('.')[0] }}.yml" + when: ansible_distribution == 'Fedora' + +- name: Define postgresql_packages. + set_fact: + postgresql_packages: "{{ __postgresql_packages | list }}" + when: postgresql_packages is not defined + +- name: Define postgresql_version. + set_fact: + postgresql_version: "{{ __postgresql_version }}" + when: postgresql_version is not defined + +- name: Define postgresql_daemon. + set_fact: + postgresql_daemon: "{{ __postgresql_daemon }}" + when: postgresql_daemon is not defined + +- name: Define postgresql_data_dir. + set_fact: + postgresql_data_dir: "{{ __postgresql_data_dir }}" + when: postgresql_data_dir is not defined + +- name: Define postgresql_bin_path. + set_fact: + postgresql_bin_path: "{{ __postgresql_bin_path }}" + when: postgresql_bin_path is not defined + +- name: Define postgresql_config_path. + set_fact: + postgresql_config_path: "{{ __postgresql_config_path }}" + when: postgresql_config_path is not defined + +- name: Define postgresql_unix_socket_directories_mode. + set_fact: + postgresql_unix_socket_directories_mode: >- + {{ __postgresql_unix_socket_directories_mode | default('02775') }} + when: postgresql_unix_socket_directories_mode is not defined diff --git a/provisioning/roles/geerlingguy.postgresql/templates/pg_hba.conf.j2 b/provisioning/roles/geerlingguy.postgresql/templates/pg_hba.conf.j2 new file mode 100644 index 000000000..05cc8a0ab --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/templates/pg_hba.conf.j2 @@ -0,0 +1,9 @@ +{{ ansible_managed | comment }} +# PostgreSQL Client Authentication Configuration File +# =================================================== +# +# See: https://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html + +{% for client in postgresql_hba_entries %} +{{ client.type }} {{ client.database }} {{ client.user }} {{ client.address|default('') }} {{ client.ip_address|default('') }} {{ client.ip_mask|default('') }} {{ client.auth_method }} {{ client.auth_options|default("") }} +{% endfor %} diff --git a/provisioning/roles/geerlingguy.postgresql/templates/postgres.sh.j2 b/provisioning/roles/geerlingguy.postgresql/templates/postgres.sh.j2 new file mode 100644 index 000000000..72640647d --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/templates/postgres.sh.j2 @@ -0,0 +1,2 @@ +export PGDATA={{ postgresql_data_dir }} +export PATH=$PATH:{{ postgresql_bin_path }} diff --git a/provisioning/roles/geerlingguy.postgresql/vars/Debian-10.yml b/provisioning/roles/geerlingguy.postgresql/vars/Debian-10.yml new file mode 100644 index 000000000..d8b5103b6 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/vars/Debian-10.yml @@ -0,0 +1,12 @@ +--- +__postgresql_version: "11" +__postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" +__postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" +__postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" +__postgresql_daemon: "postgresql@{{ postgresql_version }}-main" +__postgresql_packages: + - postgresql + - postgresql-contrib + - libpq-dev +# Debian 10 uses Python 3 by default. +postgresql_python_library: python3-psycopg2 diff --git a/provisioning/roles/geerlingguy.postgresql/vars/Debian-7.yml b/provisioning/roles/geerlingguy.postgresql/vars/Debian-7.yml new file mode 100644 index 000000000..6b933bbc0 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/vars/Debian-7.yml @@ -0,0 +1,10 @@ +--- +__postgresql_version: "9.1" +__postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" +__postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" +__postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" +__postgresql_daemon: postgresql +__postgresql_packages: + - postgresql + - postgresql-contrib + - libpq-dev diff --git a/provisioning/roles/geerlingguy.postgresql/vars/Debian-8.yml b/provisioning/roles/geerlingguy.postgresql/vars/Debian-8.yml new file mode 100644 index 000000000..ec86f938f --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/vars/Debian-8.yml @@ -0,0 +1,10 @@ +--- +__postgresql_version: "9.4" +__postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" +__postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" +__postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" +__postgresql_daemon: "postgresql@{{ postgresql_version }}-main" +__postgresql_packages: + - postgresql + - postgresql-contrib + - libpq-dev diff --git a/provisioning/roles/geerlingguy.postgresql/vars/Debian-9.yml b/provisioning/roles/geerlingguy.postgresql/vars/Debian-9.yml new file mode 100644 index 000000000..2afb9f42f --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/vars/Debian-9.yml @@ -0,0 +1,10 @@ +--- +__postgresql_version: "9.6" +__postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" +__postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" +__postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" +__postgresql_daemon: "postgresql@{{ postgresql_version }}-main" +__postgresql_packages: + - postgresql + - postgresql-contrib + - libpq-dev diff --git a/provisioning/roles/geerlingguy.postgresql/vars/Fedora-29.yml b/provisioning/roles/geerlingguy.postgresql/vars/Fedora-29.yml new file mode 100644 index 000000000..4e099324b --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/vars/Fedora-29.yml @@ -0,0 +1,12 @@ +--- +__postgresql_version: "10.5" +__postgresql_data_dir: "/var/lib/pgsql/data" +__postgresql_bin_path: "/usr/bin" +__postgresql_config_path: "/var/lib/pgsql/data" +__postgresql_daemon: postgresql +__postgresql_packages: + - postgresql + - postgresql-server + - postgresql-contrib + - postgresql-libs +postgresql_python_library: python2-psycopg2 diff --git a/provisioning/roles/geerlingguy.postgresql/vars/Fedora-30.yml b/provisioning/roles/geerlingguy.postgresql/vars/Fedora-30.yml new file mode 100644 index 000000000..d07f14b7b --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/vars/Fedora-30.yml @@ -0,0 +1,13 @@ +--- +__postgresql_version: "11.2" +__postgresql_data_dir: "/var/lib/pgsql/data" +__postgresql_bin_path: "/usr/bin" +__postgresql_config_path: "/var/lib/pgsql/data" +__postgresql_daemon: postgresql +__postgresql_packages: + - postgresql + - postgresql-server + - postgresql-contrib + - postgresql-libs +# Fedora 30 containers only have python3 by default +postgresql_python_library: python3-psycopg2 diff --git a/provisioning/roles/geerlingguy.postgresql/vars/Fedora-31.yml b/provisioning/roles/geerlingguy.postgresql/vars/Fedora-31.yml new file mode 100644 index 000000000..27a023ecc --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/vars/Fedora-31.yml @@ -0,0 +1,14 @@ +--- +__postgresql_version: "11.5" +__postgresql_data_dir: "/var/lib/pgsql/data" +__postgresql_bin_path: "/usr/bin" +__postgresql_config_path: "/var/lib/pgsql/data" +__postgresql_daemon: postgresql +__postgresql_packages: + - postgresql + - postgresql-server + - postgresql-contrib + - postgresql-libs +__postgresql_unix_socket_directories_mode: '0755' +# Fedora 31 containers only have python3 by default +postgresql_python_library: python3-psycopg2 diff --git a/provisioning/roles/geerlingguy.postgresql/vars/Fedora-32.yml b/provisioning/roles/geerlingguy.postgresql/vars/Fedora-32.yml new file mode 100644 index 000000000..6ce9d9bfe --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/vars/Fedora-32.yml @@ -0,0 +1,14 @@ +--- +__postgresql_version: "12.2" +__postgresql_data_dir: "/var/lib/pgsql/data" +__postgresql_bin_path: "/usr/bin" +__postgresql_config_path: "/var/lib/pgsql/data" +__postgresql_daemon: postgresql +__postgresql_packages: + - postgresql + - postgresql-server + - postgresql-contrib + - postgresql-libs +__postgresql_unix_socket_directories_mode: '0755' +# Fedora 32 containers only have python3 by default +postgresql_python_library: python3-psycopg2 diff --git a/provisioning/roles/geerlingguy.postgresql/vars/RedHat-7.yml b/provisioning/roles/geerlingguy.postgresql/vars/RedHat-7.yml new file mode 100644 index 000000000..1d5c517df --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/vars/RedHat-7.yml @@ -0,0 +1,11 @@ +--- +__postgresql_version: "9.2" +__postgresql_data_dir: "/var/lib/pgsql/data" +__postgresql_bin_path: "/usr/bin" +__postgresql_config_path: "/var/lib/pgsql/data" +__postgresql_daemon: postgresql +__postgresql_packages: + - postgresql + - postgresql-server + - postgresql-contrib + - postgresql-libs diff --git a/provisioning/roles/geerlingguy.postgresql/vars/RedHat-8.yml b/provisioning/roles/geerlingguy.postgresql/vars/RedHat-8.yml new file mode 100644 index 000000000..e519ea9a0 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/vars/RedHat-8.yml @@ -0,0 +1,12 @@ +--- +__postgresql_version: "10" +__postgresql_data_dir: "/var/lib/pgsql/data" +__postgresql_bin_path: "/usr/bin" +__postgresql_config_path: "/var/lib/pgsql/data" +__postgresql_daemon: postgresql +__postgresql_packages: + - postgresql + - postgresql-server + - postgresql-contrib +__postgresql_unix_socket_directories_mode: '0755' +postgresql_python_library: python3-psycopg2 diff --git a/provisioning/roles/geerlingguy.postgresql/vars/Ubuntu-16.yml b/provisioning/roles/geerlingguy.postgresql/vars/Ubuntu-16.yml new file mode 100644 index 000000000..cf2ebb8dd --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/vars/Ubuntu-16.yml @@ -0,0 +1,10 @@ +--- +__postgresql_version: "9.5" +__postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" +__postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" +__postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" +__postgresql_daemon: postgresql +__postgresql_packages: + - postgresql + - postgresql-contrib + - libpq-dev diff --git a/provisioning/roles/geerlingguy.postgresql/vars/Ubuntu-18.yml b/provisioning/roles/geerlingguy.postgresql/vars/Ubuntu-18.yml new file mode 100644 index 000000000..8136224f2 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/vars/Ubuntu-18.yml @@ -0,0 +1,11 @@ +--- +__postgresql_version: "10" +__postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" +__postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" +__postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" +__postgresql_daemon: postgresql +__postgresql_packages: + - postgresql + - postgresql-contrib + - libpq-dev +postgresql_python_library: python3-psycopg2 diff --git a/provisioning/roles/geerlingguy.postgresql/vars/Ubuntu-20.yml b/provisioning/roles/geerlingguy.postgresql/vars/Ubuntu-20.yml new file mode 100644 index 000000000..9a9a065a2 --- /dev/null +++ b/provisioning/roles/geerlingguy.postgresql/vars/Ubuntu-20.yml @@ -0,0 +1,11 @@ +--- +__postgresql_version: "12" +__postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" +__postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" +__postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" +__postgresql_daemon: postgresql +__postgresql_packages: + - postgresql + - postgresql-contrib + - libpq-dev +postgresql_python_library: python3-psycopg2 diff --git a/provisioning/roles/geerlingguy.redis/.ansible-lint b/provisioning/roles/geerlingguy.redis/.ansible-lint new file mode 100644 index 000000000..555729425 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/.ansible-lint @@ -0,0 +1,2 @@ +skip_list: + - '106' diff --git a/provisioning/roles/geerlingguy.redis/.github/FUNDING.yml b/provisioning/roles/geerlingguy.redis/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.redis/.github/stale.yml b/provisioning/roles/geerlingguy.redis/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.redis/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.redis/.github/workflows/ci.yml new file mode 100644 index 000000000..60bf7de6c --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/.github/workflows/ci.yml @@ -0,0 +1,68 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "30 2 * * 5" + +defaults: + run: + working-directory: 'geerlingguy.redis' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.redis' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint ansible-lint + + - name: Lint code. + run: | + yamllint . + ansible-lint + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + distro: + - centos7 + - fedora32 + - ubuntu1804 + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.redis' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} diff --git a/provisioning/roles/geerlingguy.redis/.github/workflows/release.yml b/provisioning/roles/geerlingguy.redis/.github/workflows/release.yml new file mode 100644 index 000000000..1d9c179a1 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.redis' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.redis' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.redis/.gitignore b/provisioning/roles/geerlingguy.redis/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.redis/.yamllint b/provisioning/roles/geerlingguy.redis/.yamllint new file mode 100644 index 000000000..76a383c6a --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/.yamllint @@ -0,0 +1,10 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml diff --git a/provisioning/roles/geerlingguy.redis/LICENSE b/provisioning/roles/geerlingguy.redis/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.redis/README.md b/provisioning/roles/geerlingguy.redis/README.md new file mode 100644 index 000000000..31092fa90 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/README.md @@ -0,0 +1,119 @@ +# Ansible Role: Redis + +[![CI](https://github.com/geerlingguy/ansible-role-redis/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-redis/actions?query=workflow%3ACI) + +Installs [Redis](http://redis.io/) on Linux. + +## Requirements + +On RedHat-based distributions, requires the EPEL repository (you can simply add the role `geerlingguy.repo-epel` to install ensure EPEL is available). + +## Role Variables + + redis_enablerepo: epel + +(Used only on RHEL/CentOS) The repository to use for Redis installation. + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + redis_port: 6379 + redis_bind_interface: 127.0.0.1 + +Port and interface on which Redis will listen. Set the interface to `0.0.0.0` to listen on all interfaces. + + redis_unixsocket: '' + +If set, Redis will also listen on a local Unix socket. + + redis_timeout: 300 + +Close a connection after a client is idle `N` seconds. Set to `0` to disable timeout. + + redis_loglevel: "notice" + redis_logfile: /var/log/redis/redis-server.log + +Log level and log location (valid levels are `debug`, `verbose`, `notice`, and `warning`). + + redis_databases: 16 + +The number of Redis databases. + + # Set to an empty set to disable persistence (saving the DB to disk). + redis_save: + - 900 1 + - 300 10 + - 60 10000 + +Snapshotting configuration; setting values in this list will save the database to disk if the given number of seconds (e.g. `900`) and the given number of write operations (e.g. `1`) have occurred. + + redis_rdbcompression: "yes" + redis_dbfilename: dump.rdb + redis_dbdir: /var/lib/redis + +Database compression and location configuration. + + redis_maxmemory: 0 + +Limit memory usage to the specified amount of bytes. Leave at 0 for unlimited. + + redis_maxmemory_policy: "noeviction" + +The method to use to keep memory usage below the limit, if specified. See [Using Redis as an LRU cache](http://redis.io/topics/lru-cache). + + redis_maxmemory_samples: 5 + +Number of samples to use to approximate LRU. See [Using Redis as an LRU cache](http://redis.io/topics/lru-cache). + + redis_appendonly: "no" + +The appendonly option, if enabled, affords better data durability guarantees, at the cost of slightly slower performance. + + redis_appendfsync: "everysec" + +Valid values are `always` (slower, safest), `everysec` (happy medium), or `no` (let the filesystem flush data when it wants, most risky). + + # Add extra include files for local configuration/overrides. + redis_includes: [] + +Add extra include file paths to this list to include more/localized Redis configuration. + +The redis package name for installation via the system package manager. Defaults to `redis-server` on Debian and `redis` on RHEL. + + redis_package_name: "redis-server" + +(Default for RHEL shown) The redis package name for installation via the system package manager. Defaults to `redis-server` on Debian and `redis` on RHEL. + + redis_requirepass: "" + +Set a password to require authentication to Redis. You can generate a strong password using `echo "my_password_here" | sha256sum`. + + redis_disabled_commands: [] + +For extra security, you can disable certain Redis commands (this is especially important if Redis is publicly accessible). For example: + + redis_disabled_commands: + - FLUSHDB + - FLUSHALL + - KEYS + - PEXPIRE + - DEL + - CONFIG + - SHUTDOWN + +## Dependencies + +None. + +## Example Playbook + + - hosts: all + roles: + - role: geerlingguy.redis + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.redis/defaults/main.yml b/provisioning/roles/geerlingguy.redis/defaults/main.yml new file mode 100644 index 000000000..3c9965d68 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/defaults/main.yml @@ -0,0 +1,53 @@ +--- +# Used for RHEL/CentOS/Fedora only. Allows the use of different repos. +redis_enablerepo: epel + +redis_port: 6379 +redis_bind_interface: 127.0.0.1 +redis_unixsocket: '' +redis_timeout: 300 + +redis_loglevel: "notice" +redis_logfile: /var/log/redis/redis-server.log + +redis_databases: 16 + +# Set to an empty set to disable persistence (saving the DB to disk). +redis_save: + - 900 1 + - 300 10 + - 60 10000 + +redis_rdbcompression: "yes" +redis_dbfilename: dump.rdb +redis_dbdir: /var/lib/redis + +redis_maxmemory: 0 +redis_maxmemory_policy: "noeviction" +redis_maxmemory_samples: 5 + +redis_appendonly: "no" +redis_appendfsync: "everysec" + +# Add extra include files for local configuration/overrides. +redis_includes: [] + +# Require authentication to Redis with a password. +redis_requirepass: "" + +# Disable certain Redis commands for security reasons. +redis_disabled_commands: [] +# - FLUSHDB +# - FLUSHALL +# - KEYS +# - PEXPIRE +# - DEL +# - CONFIG +# - SHUTDOWN +# - BGREWRITEAOF +# - BGSAVE +# - SAVE +# - SPOP +# - SREM +# - RENAME +# - DEBUG diff --git a/provisioning/roles/geerlingguy.redis/handlers/main.yml b/provisioning/roles/geerlingguy.redis/handlers/main.yml new file mode 100644 index 000000000..9a212039f --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: restart redis + service: "name={{ redis_daemon }} state=restarted" diff --git a/provisioning/roles/geerlingguy.redis/meta/main.yml b/provisioning/roles/geerlingguy.redis/meta/main.yml new file mode 100644 index 000000000..882938cf7 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/meta/main.yml @@ -0,0 +1,35 @@ +--- +dependencies: [] + +galaxy_info: + role_name: redis + author: geerlingguy + description: Redis for Linux + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - 6 + - 7 + - 8 + - name: Fedora + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + - name: Archlinux + versions: + - all + galaxy_tags: + - database + - development + - web + - redis + - cache + - performance diff --git a/provisioning/roles/geerlingguy.redis/molecule/default/converge.yml b/provisioning/roles/geerlingguy.redis/molecule/default/converge.yml new file mode 100644 index 000000000..8259ab8dc --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/molecule/default/converge.yml @@ -0,0 +1,17 @@ +--- +- name: Converge + hosts: all + become: true + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + - name: Clear out repo for Fedora. + set_fact: + redis_enablerepo: "" + when: ansible_distribution == 'Fedora' + + roles: + - role: geerlingguy.redis diff --git a/provisioning/roles/geerlingguy.redis/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.redis/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.redis/tasks/main.yml b/provisioning/roles/geerlingguy.redis/tasks/main.yml new file mode 100644 index 000000000..0d57dc4d5 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/tasks/main.yml @@ -0,0 +1,35 @@ +--- +# Variable setup. +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define redis_package. + set_fact: + redis_package: "{{ __redis_package }}" + when: redis_package is not defined + +- name: Ensure Redis configuration dir exists. + file: + path: "{{ redis_conf_path | dirname }}" + state: directory + mode: 0755 + +- name: Ensure Redis is configured. + template: + src: redis.conf.j2 + dest: "{{ redis_conf_path }}" + mode: "{{ redis_conf_mode }}" + notify: restart redis + +# Setup/install tasks. +- include_tasks: setup-RedHat.yml + when: ansible_os_family == 'RedHat' + +- include_tasks: setup-Debian.yml + when: ansible_os_family == 'Debian' + +- include_tasks: setup-Archlinux.yml + when: ansible_os_family == 'Archlinux' + +- name: Ensure Redis is running and enabled on boot. + service: "name={{ redis_daemon }} state=started enabled=yes" diff --git a/provisioning/roles/geerlingguy.redis/tasks/setup-Archlinux.yml b/provisioning/roles/geerlingguy.redis/tasks/setup-Archlinux.yml new file mode 100644 index 000000000..d75d0e558 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/tasks/setup-Archlinux.yml @@ -0,0 +1,5 @@ +--- +- name: Ensure Redis is installed. + pacman: + name: "{{ redis_package }}" + state: present diff --git a/provisioning/roles/geerlingguy.redis/tasks/setup-Debian.yml b/provisioning/roles/geerlingguy.redis/tasks/setup-Debian.yml new file mode 100644 index 000000000..41f17f907 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/tasks/setup-Debian.yml @@ -0,0 +1,5 @@ +--- +- name: Ensure Redis is installed. + apt: + name: "{{ redis_package }}" + state: present diff --git a/provisioning/roles/geerlingguy.redis/tasks/setup-RedHat.yml b/provisioning/roles/geerlingguy.redis/tasks/setup-RedHat.yml new file mode 100644 index 000000000..ebb7e9e26 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/tasks/setup-RedHat.yml @@ -0,0 +1,6 @@ +--- +- name: Ensure Redis is installed. + package: + name: "{{ redis_package }}" + state: present + enablerepo: "{{ redis_enablerepo | default(omit, true) }}" diff --git a/provisioning/roles/geerlingguy.redis/templates/redis.conf.j2 b/provisioning/roles/geerlingguy.redis/templates/redis.conf.j2 new file mode 100644 index 000000000..9cec1c8a1 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/templates/redis.conf.j2 @@ -0,0 +1,55 @@ +# {{ ansible_managed }} + +daemonize yes +pidfile /var/run/redis/{{ redis_daemon }}.pid +port {{ redis_port }} +bind {{ redis_bind_interface }} + +{% if redis_unixsocket %} +unixsocket {{ redis_unixsocket }} +{% endif %} + +timeout {{ redis_timeout }} + +loglevel {{ redis_loglevel }} +logfile {{ redis_logfile }} + +# To enable logging to the system logger, just set 'syslog-enabled' to yes, +# and optionally update the other syslog parameters to suit your needs. +# syslog-enabled no +# syslog-ident redis +# syslog-facility local0 + +databases {{ redis_databases }} + +{% for save in redis_save %} +save {{ save }} +{% endfor %} + +rdbcompression {{ redis_rdbcompression }} +dbfilename {{ redis_dbfilename }} +dir {{ redis_dbdir }} + +# maxclients 128 + +{% if redis_maxmemory %} +maxmemory {{ redis_maxmemory }} +maxmemory-policy {{ redis_maxmemory_policy }} +maxmemory-samples {{ redis_maxmemory_samples }} +{% endif %} + +appendonly {{ redis_appendonly }} +appendfsync {{ redis_appendfsync }} +no-appendfsync-on-rewrite no + +{% for include in redis_includes %} +include {{ include }} +{% endfor %} + +{% if redis_requirepass %} +requirepass {{ redis_requirepass }} +{% endif %} + +{% for redis_disabled_command in redis_disabled_commands %} +rename-command {{ redis_disabled_command }} "" +{% endfor %} diff --git a/provisioning/roles/geerlingguy.redis/vars/Archlinux.yml b/provisioning/roles/geerlingguy.redis/vars/Archlinux.yml new file mode 100644 index 000000000..4aba21366 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/vars/Archlinux.yml @@ -0,0 +1,4 @@ +--- +__redis_package: redis +redis_daemon: redis +redis_conf_path: /etc/redis.conf diff --git a/provisioning/roles/geerlingguy.redis/vars/Debian.yml b/provisioning/roles/geerlingguy.redis/vars/Debian.yml new file mode 100644 index 000000000..47aaa0270 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/vars/Debian.yml @@ -0,0 +1,5 @@ +--- +__redis_package: redis-server +redis_daemon: redis-server +redis_conf_path: /etc/redis/redis.conf +redis_conf_mode: 0640 diff --git a/provisioning/roles/geerlingguy.redis/vars/RedHat.yml b/provisioning/roles/geerlingguy.redis/vars/RedHat.yml new file mode 100644 index 000000000..a64d953f5 --- /dev/null +++ b/provisioning/roles/geerlingguy.redis/vars/RedHat.yml @@ -0,0 +1,5 @@ +--- +__redis_package: redis +redis_daemon: redis +redis_conf_path: /etc/redis.conf +redis_conf_mode: 0644 diff --git a/provisioning/roles/geerlingguy.repo-epel/.ansible-lint b/provisioning/roles/geerlingguy.repo-epel/.ansible-lint new file mode 100644 index 000000000..acc82551f --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-epel/.ansible-lint @@ -0,0 +1,3 @@ +skip_list: + - 'yaml' + - 'role-name' diff --git a/provisioning/roles/geerlingguy.repo-epel/.github/FUNDING.yml b/provisioning/roles/geerlingguy.repo-epel/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-epel/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.repo-epel/.github/stale.yml b/provisioning/roles/geerlingguy.repo-epel/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-epel/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.repo-epel/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.repo-epel/.github/workflows/ci.yml new file mode 100644 index 000000000..64ebd7574 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-epel/.github/workflows/ci.yml @@ -0,0 +1,66 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "30 1 * * 5" + +defaults: + run: + working-directory: 'geerlingguy.repo-epel' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.repo-epel' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + distro: + - centos8 + - centos7 + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.repo-epel' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} diff --git a/provisioning/roles/geerlingguy.repo-epel/.github/workflows/release.yml b/provisioning/roles/geerlingguy.repo-epel/.github/workflows/release.yml new file mode 100644 index 000000000..82ad097ed --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-epel/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.repo-epel' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.repo-epel' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.repo-epel/.gitignore b/provisioning/roles/geerlingguy.repo-epel/.gitignore new file mode 100644 index 000000000..8840c8f02 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-epel/.gitignore @@ -0,0 +1,5 @@ +*.retry +*/__pycache__ +*.pyc +.cache + diff --git a/provisioning/roles/geerlingguy.repo-epel/.yamllint b/provisioning/roles/geerlingguy.repo-epel/.yamllint new file mode 100644 index 000000000..dc34c1953 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-epel/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 140 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/provisioning/roles/geerlingguy.repo-epel/LICENSE b/provisioning/roles/geerlingguy.repo-epel/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-epel/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.repo-epel/README.md b/provisioning/roles/geerlingguy.repo-epel/README.md new file mode 100644 index 000000000..db6da5cbb --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-epel/README.md @@ -0,0 +1,40 @@ +# Ansible Role: EPEL Repository + +[![CI](https://github.com/geerlingguy/ansible-role-repo-epel/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-repo-epel/actions?query=workflow%3ACI) + +Installs the [EPEL repository](https://fedoraproject.org/wiki/EPEL) (Extra Packages for Enterprise Linux) for RHEL/CentOS. + +## Requirements + +This role only is needed/runs on RHEL and its derivatives. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + epel_repo_url: "http://download.fedoraproject.org/pub/epel/{{ ansible_distribution_major_version }}/{{ ansible_userspace_architecture }}{{ '/' if ansible_distribution_major_version < '7' else '/e/' }}epel-release-{{ ansible_distribution_major_version }}-{{ epel_release[ansible_distribution_major_version] }}.noarch.rpm" + epel_repo_gpg_key_url: "/etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-{{ ansible_distribution_major_version }}" + +The EPEL repo URL and GPG key URL. Generally, these should not be changed, but if this role is out of date, or if you need a very specific version, these can both be overridden. + + epel_repo_disable: false + +Set to `true` to disable the EPEL repo (even if already installed). + +## Dependencies + +None. + +## Example Playbook + + - hosts: servers + roles: + - geerlingguy.repo-epel + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.repo-epel/defaults/main.yml b/provisioning/roles/geerlingguy.repo-epel/defaults/main.yml new file mode 100644 index 000000000..9e308c9e3 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-epel/defaults/main.yml @@ -0,0 +1,5 @@ +--- +epel_repo_url: "https://dl.fedoraproject.org/pub/epel/epel-release-latest-{{ ansible_distribution_major_version }}.noarch.rpm" +epel_repo_gpg_key_url: "https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-{{ ansible_distribution_major_version }}" +epel_repofile_path: "/etc/yum.repos.d/epel.repo" +epel_repo_disable: false diff --git a/provisioning/roles/geerlingguy.repo-epel/meta/main.yml b/provisioning/roles/geerlingguy.repo-epel/meta/main.yml new file mode 100644 index 000000000..af6766cd2 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-epel/meta/main.yml @@ -0,0 +1,23 @@ +--- +dependencies: [] + +galaxy_info: + role_name: repo-epel + author: geerlingguy + description: EPEL repository for RHEL/CentOS. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.5 + platforms: + - name: EL + versions: + - 7 + - 8 + galaxy_tags: + - packaging + - epel + - repository + - repo + - redhat + - centos + - rhel diff --git a/provisioning/roles/geerlingguy.repo-epel/molecule/default/converge.yml b/provisioning/roles/geerlingguy.repo-epel/molecule/default/converge.yml new file mode 100644 index 000000000..a1bc3193b --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-epel/molecule/default/converge.yml @@ -0,0 +1,7 @@ +--- +- name: Converge + hosts: all + become: true + + roles: + - role: geerlingguy.repo-epel diff --git a/provisioning/roles/geerlingguy.repo-epel/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.repo-epel/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-epel/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.repo-epel/tasks/main.yml b/provisioning/roles/geerlingguy.repo-epel/tasks/main.yml new file mode 100644 index 000000000..1c28825aa --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-epel/tasks/main.yml @@ -0,0 +1,34 @@ +--- +- name: Check if EPEL repo is already configured. + stat: + path: "{{ epel_repofile_path }}" + register: epel_repofile_result + +- name: Import EPEL GPG key. + rpm_key: + key: "{{ epel_repo_gpg_key_url }}" + state: present + register: result + until: result is succeeded + retries: 5 + delay: 10 + when: not epel_repofile_result.stat.exists + ignore_errors: "{{ ansible_check_mode }}" + +- name: Install EPEL repo. + yum: + name: "{{ epel_repo_url }}" + state: present + register: result + until: result is succeeded + retries: 5 + delay: 10 + when: not epel_repofile_result.stat.exists + +- name: Disable Main EPEL repo. + ini_file: + path: "/etc/yum.repos.d/epel.repo" + section: epel + option: enabled + value: "{{ epel_repo_disable | ternary(0, 1) }}" + mode: 0644 diff --git a/provisioning/roles/geerlingguy.repo-remi/.ansible-lint b/provisioning/roles/geerlingguy.repo-remi/.ansible-lint new file mode 100644 index 000000000..555729425 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-remi/.ansible-lint @@ -0,0 +1,2 @@ +skip_list: + - '106' diff --git a/provisioning/roles/geerlingguy.repo-remi/.github/FUNDING.yml b/provisioning/roles/geerlingguy.repo-remi/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-remi/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.repo-remi/.github/stale.yml b/provisioning/roles/geerlingguy.repo-remi/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-remi/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.repo-remi/.gitignore b/provisioning/roles/geerlingguy.repo-remi/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-remi/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.repo-remi/.travis.yml b/provisioning/roles/geerlingguy.repo-remi/.travis.yml new file mode 100644 index 000000000..a8d04d80c --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-remi/.travis.yml @@ -0,0 +1,33 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: repo-remi + matrix: + - MOLECULE_DISTRO: ubi8 + - MOLECULE_DISTRO: centos8 + - MOLECULE_DISTRO: centos7 + - MOLECULE_DISTRO: centos6 + +before_install: + # Upgrade Docker to work with docker-py. + - curl https://gist.githubusercontent.com/geerlingguy/ce883ad4aec6a5f1187ef93bd338511e/raw/36612d28981d92863f839c5aefe5b7dd7193d6c6/travis-ci-docker-upgrade.sh | sudo bash + +install: + # Install test dependencies. + - pip install molecule yamllint ansible-lint docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.repo-remi/.yamllint b/provisioning/roles/geerlingguy.repo-remi/.yamllint new file mode 100644 index 000000000..76a383c6a --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-remi/.yamllint @@ -0,0 +1,10 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml diff --git a/provisioning/roles/geerlingguy.repo-remi/LICENSE b/provisioning/roles/geerlingguy.repo-remi/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-remi/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.repo-remi/README.md b/provisioning/roles/geerlingguy.repo-remi/README.md new file mode 100644 index 000000000..739fe96ea --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-remi/README.md @@ -0,0 +1,39 @@ +# Ansible Role: Remi Repository + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-repo-remi.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-repo-remi) + +Installs [Remi's RPM repository](http://rpms.famillecollet.com/) for RHEL/CentOS. + +## Requirements + +On RHEL 8 or newer, you should make sure to install or enable the EPEL repository. I recommend using the `geerlingguy.repo-epel` repository. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + remi_repo_url: "https://rpms.remirepo.net/enterprise/remi-release-{{ ansible_distribution_major_version }}.rpm" + +The URL from which the Remi repo `.rpm` will be downloaded and installed. + + remi_repo_gpg_key_url: "https://rpms.remirepo.net/RPM-GPG-KEY-remi2018" + +Remi repo GPG key location. Can be set to a local file or to the URL from Remi's website. + +## Dependencies + +None. + +## Example Playbook + + - hosts: servers + roles: + - geerlingguy.repo-remi + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.repo-remi/defaults/main.yml b/provisioning/roles/geerlingguy.repo-remi/defaults/main.yml new file mode 100644 index 000000000..0dd05f17d --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-remi/defaults/main.yml @@ -0,0 +1,3 @@ +--- +remi_repo_url: "https://rpms.remirepo.net/enterprise/remi-release-{{ ansible_distribution_major_version }}.rpm" +remi_repo_gpg_key_url: "https://rpms.remirepo.net/RPM-GPG-KEY-remi2018" diff --git a/provisioning/roles/geerlingguy.repo-remi/meta/main.yml b/provisioning/roles/geerlingguy.repo-remi/meta/main.yml new file mode 100644 index 000000000..e3eb3b1d4 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-remi/meta/main.yml @@ -0,0 +1,25 @@ +--- +dependencies: [] + +galaxy_info: + # See: https://github.com/ansible/galaxy/issues/2393 + # role_name: repo-remi + author: geerlingguy + description: Remi's RPM repository for RHEL/CentOS. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + galaxy_tags: + - packaging + - epel + - repository + - repo + - remi + - php + - redhat + - rhel + - centos diff --git a/provisioning/roles/geerlingguy.repo-remi/molecule/default/converge.yml b/provisioning/roles/geerlingguy.repo-remi/molecule/default/converge.yml new file mode 100644 index 000000000..b07c6ec34 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-remi/molecule/default/converge.yml @@ -0,0 +1,8 @@ +--- +- name: Converge + hosts: all + become: true + + roles: + - role: geerlingguy.repo-epel + - role: geerlingguy.repo-remi diff --git a/provisioning/roles/geerlingguy.repo-remi/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.repo-remi/molecule/default/molecule.yml new file mode 100644 index 000000000..2da47dd1f --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-remi/molecule/default/molecule.yml @@ -0,0 +1,21 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: | + set -e + yamllint . + ansible-lint +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.repo-remi/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.repo-remi/molecule/default/requirements.yml new file mode 100644 index 000000000..1c344b344 --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-remi/molecule/default/requirements.yml @@ -0,0 +1,2 @@ +--- +- role: geerlingguy.repo-epel diff --git a/provisioning/roles/geerlingguy.repo-remi/tasks/main.yml b/provisioning/roles/geerlingguy.repo-remi/tasks/main.yml new file mode 100644 index 000000000..3adfb310b --- /dev/null +++ b/provisioning/roles/geerlingguy.repo-remi/tasks/main.yml @@ -0,0 +1,10 @@ +--- +- name: Import remi GPG key. + rpm_key: + key: "{{ remi_repo_gpg_key_url }}" + state: present + +- name: Install remi repo. + yum: + name: "{{ remi_repo_url }}" + state: present diff --git a/provisioning/roles/geerlingguy.ruby/.ansible-lint b/provisioning/roles/geerlingguy.ruby/.ansible-lint new file mode 100644 index 000000000..6632e614f --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/.ansible-lint @@ -0,0 +1,3 @@ +skip_list: + - '405' + - '106' diff --git a/provisioning/roles/geerlingguy.ruby/.github/FUNDING.yml b/provisioning/roles/geerlingguy.ruby/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.ruby/.github/stale.yml b/provisioning/roles/geerlingguy.ruby/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.ruby/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.ruby/.github/workflows/ci.yml new file mode 100644 index 000000000..255bac379 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/.github/workflows/ci.yml @@ -0,0 +1,77 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "0 3 * * 4" + +defaults: + run: + working-directory: 'geerlingguy.ruby' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.ruby' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint ansible-lint + + - name: Lint code. + run: | + yamllint . + ansible-lint + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + include: + - distro: centos7 + playbook: converge.yml + - distro: ubuntu1804 + playbook: converge.yml + - distro: debian9 + playbook: converge.yml + + - distro: centos7 + playbook: source-install.yml + - distro: ubuntu1804 + playbook: source-install.yml + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.ruby' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} + MOLECULE_PLAYBOOK: ${{ matrix.playbook }} diff --git a/provisioning/roles/geerlingguy.ruby/.github/workflows/release.yml b/provisioning/roles/geerlingguy.ruby/.github/workflows/release.yml new file mode 100644 index 000000000..0a2b99ae2 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.ruby' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.ruby' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.ruby/.gitignore b/provisioning/roles/geerlingguy.ruby/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.ruby/.yamllint b/provisioning/roles/geerlingguy.ruby/.yamllint new file mode 100644 index 000000000..f2033dd21 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/provisioning/roles/geerlingguy.ruby/LICENSE b/provisioning/roles/geerlingguy.ruby/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.ruby/README.md b/provisioning/roles/geerlingguy.ruby/README.md new file mode 100644 index 000000000..f436061c9 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/README.md @@ -0,0 +1,67 @@ +# Ansible Role: Ruby + +[![CI](https://github.com/geerlingguy/ansible-role-ruby/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-ruby/actions?query=workflow%3ACI) + +Installs Ruby and bundler gem on Linux. + +## Requirements + +None. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + workspace: /root + +The location where temporary files will be downloaded in preparation for Ruby installation. + + ruby_install_bundler: true + +Whether this role should install [Bundler](http://bundler.io/). + + ruby_install_gems: [] + +A list of Ruby gems to install (just the name of the gem to be installed). This is meant as a simple convenience, and will only install the latest version of the gem. If you need to install gems with more options or specificity, you can do so elsewhere in your playbook. + + ruby_install_gems_user: username + +The user account under which Ruby gems will be installed. Defaults to the `ansible_ssh_user` if not set. + + ruby_install_from_source: false + +By default, this role will install whatever version of ruby is available through your system's package manager (`apt` or `yum`). You can install whatever version you like (including the latest release) by setting this to `true` and/or updating the `ruby_download_url` and `ruby_version`. + + ruby_download_url: http://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0.tar.gz + +The URL from which Ruby will be downloaded (only used if `ruby_install_from_source` is `true`). + + ruby_version: 3.0.0 + +The version of ruby that will be installed (only used if `ruby_install_from_source` is `true`). + + ruby_source_configure_command: ./configure --enable-shared + +The `configure` command that will be run (only used if `ruby_install_from_source` is `true`). + + ruby_rubygems_package_name: rubygems + +The name of the `rubygems` package. Generally, the default should work; but it will be set to `rubygems-integration` automatically on Ubuntu Trusty (14.04). + +## Dependencies + +None. + +## Example Playbook + + - hosts: server + roles: + - role: geerlingguy.ruby + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.ruby/defaults/main.yml b/provisioning/roles/geerlingguy.ruby/defaults/main.yml new file mode 100644 index 000000000..bbed4cb40 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/defaults/main.yml @@ -0,0 +1,21 @@ +--- +workspace: /root + +# Whether this role should install Bundler. +ruby_install_bundler: true + +# A list of Ruby gems to install. +ruby_install_gems: [] + +# The user account under which Ruby gems will be installed. +ruby_install_gems_user: "{{ ansible_user }}" + +# If set to True, ruby will be installed from source, using the version set with +# the 'ruby_version' variable instead of using a package. +ruby_install_from_source: false +ruby_download_url: http://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0.tar.gz +ruby_version: 3.0.0 +ruby_source_configure_command: ./configure --enable-shared + +# Default should usually work, but this will be overridden on Ubuntu 14.04. +ruby_rubygems_package_name: rubygems diff --git a/provisioning/roles/geerlingguy.ruby/files/rubygems.sh b/provisioning/roles/geerlingguy.ruby/files/rubygems.sh new file mode 100644 index 000000000..755ecad29 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/files/rubygems.sh @@ -0,0 +1,3 @@ +if which ruby >/dev/null && which gem >/dev/null; then + PATH="$(ruby -e 'puts Gem.user_dir')/bin:$PATH" +fi diff --git a/provisioning/roles/geerlingguy.ruby/meta/main.yml b/provisioning/roles/geerlingguy.ruby/meta/main.yml new file mode 100644 index 000000000..ba48f9e4e --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/meta/main.yml @@ -0,0 +1,51 @@ +--- +dependencies: [] + +galaxy_info: + role_name: ruby + author: geerlingguy + description: Ruby installation for Linux. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + - name: GenericUNIX + versions: + - all + - name: Fedora + versions: + - all + - name: opensuse + versions: + - all + - name: GenericBSD + versions: + - all + - name: FreeBSD + versions: + - all + - name: Ubuntu + versions: + - lucid + - trusty + - precise + - bionic + - name: SLES + versions: + - all + - name: GenericLinux + versions: + - all + - name: Debian + versions: + - all + galaxy_tags: + - development + - web + - ruby + - rails + - gem + - bundler diff --git a/provisioning/roles/geerlingguy.ruby/molecule/default/converge.yml b/provisioning/roles/geerlingguy.ruby/molecule/default/converge.yml new file mode 100644 index 000000000..873ad8fd9 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/molecule/default/converge.yml @@ -0,0 +1,36 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + ruby_install_gems_user: root + ruby_install_gems: + - json + ruby_gems_bin_path: /root/.gem/ruby/bin + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + - name: Add rubygems bin dir to system-wide $PATH. + copy: + dest: /etc/profile.d/ruby.sh + content: 'PATH=$PATH:{{ ruby_gems_bin_path }}' + mode: 0644 + + - name: Don't install Bundler on CentOS 7 because of old Ruby version. + set_fact: + ruby_install_bundler: false + when: + - ansible_os_family == 'RedHat' + - ansible_distribution_major_version == '7' + + roles: + - role: geerlingguy.ruby + + post_tasks: + - name: Verify Ruby is installed. + command: ruby --version + changed_when: false diff --git a/provisioning/roles/geerlingguy.ruby/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.ruby/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.ruby/molecule/default/source-install.yml b/provisioning/roles/geerlingguy.ruby/molecule/default/source-install.yml new file mode 100644 index 000000000..bbd832b5a --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/molecule/default/source-install.yml @@ -0,0 +1,23 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + ruby_install_from_source: true + ruby_install_gems_user: root + ruby_install_gems: + - sass + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + + roles: + - role: geerlingguy.ruby + + post_tasks: + - name: Verify Ruby is installed. + command: ruby --version + changed_when: false diff --git a/provisioning/roles/geerlingguy.ruby/tasks/install-from-source.yml b/provisioning/roles/geerlingguy.ruby/tasks/install-from-source.yml new file mode 100644 index 000000000..d171c940e --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/tasks/install-from-source.yml @@ -0,0 +1,57 @@ +--- +- name: Define ruby_build_packages. + set_fact: + ruby_build_packages: "{{ __ruby_build_packages }}" + when: ruby_build_packages is not defined + +- name: Install packages required to build ruby. + yum: + name: "{{ ruby_build_packages }}" + state: present + when: ansible_os_family == 'RedHat' + +- name: Update apt cache (Debian). + apt: update_cache=true cache_valid_time=86400 + when: ansible_os_family == 'Debian' + +- name: Install packages required to build ruby (Debian). + apt: + name: "{{ ruby_build_packages }}" + state: present + when: ansible_os_family == 'Debian' + +- name: Download ruby. + get_url: + url: "{{ ruby_download_url }}" + dest: "{{ workspace }}/ruby-{{ ruby_version }}.tar.gz" + +- name: Extract ruby. + unarchive: + src: "{{ workspace }}/ruby-{{ ruby_version }}.tar.gz" + dest: "{{ workspace }}/" + copy: false + mode: 0755 + +- name: Build ruby. + command: > + {{ item }} + chdir={{ workspace }}/ruby-{{ ruby_version }} + creates=/usr/local/bin/ruby + with_items: + - "{{ ruby_source_configure_command }}" + - make + - make install + +- name: Add ruby symlinks. + file: # noqa 208 + src: "/usr/local/bin/{{ item }}" + dest: "/usr/bin/{{ item }}" + state: link + force: true + with_items: + - erb + - gem + - irb + - rake + - rdoc + - ruby diff --git a/provisioning/roles/geerlingguy.ruby/tasks/main.yml b/provisioning/roles/geerlingguy.ruby/tasks/main.yml new file mode 100644 index 000000000..4bd908a33 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/tasks/main.yml @@ -0,0 +1,42 @@ +--- +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define ruby_packages. + set_fact: + ruby_packages: "{{ __ruby_packages }}" + when: ruby_packages is not defined + +# Include OS-specific installation tasks. +- include_tasks: setup-RedHat.yml + when: + - not ruby_install_from_source + - ansible_os_family == 'RedHat' + +- include_tasks: setup-Debian.yml + when: + - not ruby_install_from_source + - ansible_os_family == 'Debian' + +# Install ruby from source when ruby_install_from_source is true. +- include_tasks: install-from-source.yml + when: ruby_install_from_source + +- name: Add user installed RubyGems bin directory to global $PATH. + copy: + src: rubygems.sh + dest: /etc/profile.d/rubygems.sh + mode: 0644 + +# Install Bundler and configured gems. +- name: Install Bundler. + gem: name=bundler state=present user_install=no + when: ruby_install_bundler + +- name: Install configured gems. + gem: + name: "{{ item }}" + state: present + become: true + become_user: "{{ ruby_install_gems_user }}" + with_items: "{{ ruby_install_gems }}" diff --git a/provisioning/roles/geerlingguy.ruby/tasks/setup-Debian.yml b/provisioning/roles/geerlingguy.ruby/tasks/setup-Debian.yml new file mode 100644 index 000000000..1b1cbac81 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/tasks/setup-Debian.yml @@ -0,0 +1,18 @@ +--- +- name: Update apt cache. + apt: update_cache=yes cache_valid_time=86400 + +- name: Set rubygems package name for Ubuntu 14.04. + set_fact: + ruby_rubygems_package_name: rubygems-integration + when: ansible_distribution == 'Ubuntu' and ansible_distribution_release == 'trusty' + +- name: Install ruby and other required dependencies. + apt: + name: "{{ ruby_packages }}" + state: present + +- name: Install rubygems. + apt: + name: "{{ ruby_rubygems_package_name }}" + state: present diff --git a/provisioning/roles/geerlingguy.ruby/tasks/setup-RedHat.yml b/provisioning/roles/geerlingguy.ruby/tasks/setup-RedHat.yml new file mode 100644 index 000000000..86f84aea6 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/tasks/setup-RedHat.yml @@ -0,0 +1,5 @@ +--- +- name: Install ruby, rubygems, and development tools. + yum: + name: "{{ ruby_packages }}" + state: present diff --git a/provisioning/roles/geerlingguy.ruby/vars/Debian.yml b/provisioning/roles/geerlingguy.ruby/vars/Debian.yml new file mode 100644 index 000000000..3549cb1d8 --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/vars/Debian.yml @@ -0,0 +1,17 @@ +--- +__ruby_packages: + - ruby-full + - ruby-dev + - build-essential + - autogen + - autoconf + - libtool +__ruby_build_packages: + - build-essential + - zlib1g-dev + - libssl-dev + - libyaml-dev + - libreadline6-dev + - libncurses5-dev + - libffi-dev + - libgdbm-dev diff --git a/provisioning/roles/geerlingguy.ruby/vars/RedHat.yml b/provisioning/roles/geerlingguy.ruby/vars/RedHat.yml new file mode 100644 index 000000000..47e9766ac --- /dev/null +++ b/provisioning/roles/geerlingguy.ruby/vars/RedHat.yml @@ -0,0 +1,10 @@ +--- +__ruby_packages: + - ruby + - ruby-devel + - "{{ ruby_rubygems_package_name }}" + - '@development' +__ruby_build_packages: + - '@development' + - zlib-devel + - openssl-static diff --git a/provisioning/roles/geerlingguy.security/.ansible-lint b/provisioning/roles/geerlingguy.security/.ansible-lint new file mode 100644 index 000000000..555729425 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/.ansible-lint @@ -0,0 +1,2 @@ +skip_list: + - '106' diff --git a/provisioning/roles/geerlingguy.security/.github/FUNDING.yml b/provisioning/roles/geerlingguy.security/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.security/.github/stale.yml b/provisioning/roles/geerlingguy.security/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.security/.gitignore b/provisioning/roles/geerlingguy.security/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.security/.travis.yml b/provisioning/roles/geerlingguy.security/.travis.yml new file mode 100644 index 000000000..ded62ac67 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/.travis.yml @@ -0,0 +1,33 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: security + matrix: + - MOLECULE_DISTRO: centos8 + - MOLECULE_DISTRO: centos7 + - MOLECULE_DISTRO: ubuntu1804 + - MOLECULE_DISTRO: debian10 + +before_install: + # Upgrade Docker to work with docker-py. + - curl https://gist.githubusercontent.com/geerlingguy/ce883ad4aec6a5f1187ef93bd338511e/raw/36612d28981d92863f839c5aefe5b7dd7193d6c6/travis-ci-docker-upgrade.sh | sudo bash + +install: + # Install test dependencies. + - pip install molecule yamllint ansible-lint docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.security/.yamllint b/provisioning/roles/geerlingguy.security/.yamllint new file mode 100644 index 000000000..f2033dd21 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/provisioning/roles/geerlingguy.security/LICENSE b/provisioning/roles/geerlingguy.security/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.security/README.md b/provisioning/roles/geerlingguy.security/README.md new file mode 100644 index 000000000..7fd432c12 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/README.md @@ -0,0 +1,113 @@ +# Ansible Role: Security (Basics) + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-security.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-security) + +**First, a major, MAJOR caveat**: the security of your servers is YOUR responsibility. If you think simply including this role and adding a firewall makes a server secure, then you're mistaken. Read up on Linux, network, and application security, and know that no matter how much you know, you can always make every part of your stack more secure. + +That being said, this role performs some basic security configuration on RedHat and Debian-based linux systems. It attempts to: + + - Install software to monitor bad SSH access (fail2ban) + - Configure SSH to be more secure (disabling root login, requiring key-based authentication, and allowing a custom SSH port to be set) + - Set up automatic updates (if configured to do so) + +There are a few other things you may or may not want to do (which are not included in this role) to make sure your servers are more secure, like: + + - Use logwatch or a centralized logging server to analyze and monitor log files + - Securely configure user accounts and SSH keys (this role assumes you're not using password authentication or logging in as root) + - Have a well-configured firewall (check out the `geerlingguy.firewall` role on Ansible Galaxy for a flexible example) + +Again: Your servers' security is *your* responsibility. + +## Requirements + +For obvious reasons, `sudo` must be installed if you want to manage the sudoers file with this role. + +On RedHat/CentOS systems, make sure you have the EPEL repository installed (you can include the `geerlingguy.repo-epel` role to get it installed). + +No special requirements for Debian/Ubuntu systems. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + security_ssh_port: 22 + +The port through which you'd like SSH to be accessible. The default is port 22, but if you're operating a server on the open internet, and have no firewall blocking access to port 22, you'll quickly find that thousands of login attempts per day are not uncommon. You can change the port to a nonstandard port (e.g. 2849) if you want to avoid these thousands of automated penetration attempts. + + security_ssh_password_authentication: "no" + security_ssh_permit_root_login: "no" + security_ssh_usedns: "no" + security_ssh_permit_empty_password: "no" + security_ssh_challenge_response_auth: "no" + security_ssh_gss_api_authentication: "no" + security_ssh_x11_forwarding: "no" + +Security settings for SSH authentication. It's best to leave these set to `"no"`, but there are times (especially during initial server configuration or when you don't have key-based authentication in place) when one or all may be safely set to `'yes'`. **NOTE: It is _very_ important that you quote the 'yes' or 'no' values. Failure to do so may lock you out of your server.** + + security_sshd_state: started + +The state of the SSH daemon. Typically this should remain `started`. + + security_ssh_restart_handler_state: restarted + +The state of the `restart ssh` handler. Typically this should remain `restarted`. + + security_sudoers_passwordless: [] + security_sudoers_passworded: [] + +A list of users who should be added to the sudoers file so they can run any command as root (via `sudo`) either without a password or requiring a password for each command, respectively. + + security_autoupdate_enabled: true + +Whether to install/enable `yum-cron` (RedHat-based systems) or `unattended-upgrades` (Debian-based systems). System restarts will not happen automatically in any case, and automatic upgrades are no excuse for sloppy patch and package management, but automatic updates can be helpful as yet another security measure. + + security_autoupdate_blacklist: [] + +(Debian/Ubuntu only) A listing of packages that should not be automatically updated. + + security_autoupdate_reboot: false + +(Debian/Ubuntu only) Whether to reboot when needed during unattended upgrades. + + security_autoupdate_reboot_time: "03:00" + +(Debian/Ubuntu only) The time to trigger a reboot, when needed, if `security_autoupdate_reboot` is set to `true`. In 24h "hh:mm" clock format. + + security_autoupdate_mail_to: "" + security_autoupdate_mail_on_error: true + +(Debian/Ubuntu only) If `security_autoupdate_mail_to` is set to an non empty value, unattended upgrades will send an e-mail to that address when some error occurs. You may either set this to a full email: `ops@example.com` or to something like `root`, which will use `/etc/aliases` to route the message. If you set `security_autoupdate_mail_on_error` to `false` you'll get an email after every package install. + + security_fail2ban_enabled: true + +Whether to install/enable `fail2ban`. You might not want to use fail2ban if you're already using some other service for login and intrusion detection (e.g. [ConfigServer](http://configserver.com/cp/csf.html)). + + security_fail2ban_custom_configuration_template: "jail.local.j2" + +The name of the template file used to generate `fail2ban`'s configuration. + +## Dependencies + +None. + +## Example Playbook + + - hosts: servers + vars_files: + - vars/main.yml + roles: + - geerlingguy.security + +*Inside `vars/main.yml`*: + + security_sudoers_passworded: + - johndoe + - deployacct + +## License + +MIT (Expat) / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.security/defaults/main.yml b/provisioning/roles/geerlingguy.security/defaults/main.yml new file mode 100644 index 000000000..74e30ae5f --- /dev/null +++ b/provisioning/roles/geerlingguy.security/defaults/main.yml @@ -0,0 +1,26 @@ +--- +security_ssh_port: 22 +security_ssh_password_authentication: "no" +security_ssh_permit_root_login: "no" +security_ssh_usedns: "no" +security_ssh_permit_empty_password: "no" +security_ssh_challenge_response_auth: "no" +security_ssh_gss_api_authentication: "no" +security_ssh_x11_forwarding: "no" +security_sshd_state: started +security_ssh_restart_handler_state: restarted + +security_sudoers_passwordless: [] +security_sudoers_passworded: [] + +security_autoupdate_enabled: true +security_autoupdate_blacklist: [] + +# Autoupdate mail settings used on Debian/Ubuntu only. +security_autoupdate_reboot: "false" +security_autoupdate_reboot_time: "03:00" +security_autoupdate_mail_to: "" +security_autoupdate_mail_on_error: true + +security_fail2ban_enabled: true +security_fail2ban_custom_configuration_template: "jail.local.j2" diff --git a/provisioning/roles/geerlingguy.security/handlers/main.yml b/provisioning/roles/geerlingguy.security/handlers/main.yml new file mode 100644 index 000000000..1ac640aa1 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: restart ssh + service: + name: "{{ security_sshd_name }}" + state: "{{ security_ssh_restart_handler_state }}" diff --git a/provisioning/roles/geerlingguy.security/meta/main.yml b/provisioning/roles/geerlingguy.security/meta/main.yml new file mode 100644 index 000000000..8d598d3c0 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/meta/main.yml @@ -0,0 +1,33 @@ +--- +dependencies: [] + +galaxy_info: + role_name: security + author: geerlingguy + description: Security software installation and configuration. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - all + - name: Fedora + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + galaxy_tags: + - system + - security + - fail2ban + - automatic + - updates + - yum + - apt + - dnf + - hardening diff --git a/provisioning/roles/geerlingguy.security/molecule/default/converge.yml b/provisioning/roles/geerlingguy.security/molecule/default/converge.yml new file mode 100644 index 000000000..1271dcfdc --- /dev/null +++ b/provisioning/roles/geerlingguy.security/molecule/default/converge.yml @@ -0,0 +1,44 @@ +--- +- name: Converge + hosts: all + become: true + + pre_tasks: + - name: Update apt cache. + package: + update_cache: true + cache_valid_time: 600 + when: ansible_os_family == 'Debian' + + - name: Ensure build dependencies are installed (RedHat). + package: + name: + - openssh-server + - openssh-clients + state: present + when: ansible_os_family == 'RedHat' + + - name: Ensure build dependencies are installed (Fedora). + package: + name: procps + state: present + when: ansible_distribution == 'Fedora' + + - name: Ensure build dependencies are installed (Debian). + package: + name: + - openssh-server + - openssh-client + state: present + when: ansible_os_family == 'Debian' + + - name: Ensure auth.log file is present. + copy: + dest: /var/log/auth.log + content: "" + force: false + mode: 0644 + when: ansible_distribution == 'Debian' + + roles: + - role: geerlingguy.security diff --git a/provisioning/roles/geerlingguy.security/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.security/molecule/default/molecule.yml new file mode 100644 index 000000000..2da47dd1f --- /dev/null +++ b/provisioning/roles/geerlingguy.security/molecule/default/molecule.yml @@ -0,0 +1,21 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: | + set -e + yamllint . + ansible-lint +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.security/tasks/autoupdate-Debian.yml b/provisioning/roles/geerlingguy.security/tasks/autoupdate-Debian.yml new file mode 100644 index 000000000..05aebb783 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/tasks/autoupdate-Debian.yml @@ -0,0 +1,16 @@ +--- +- name: Install unattended upgrades package. + package: + name: unattended-upgrades + state: present + +- name: Copy unattended-upgrades configuration files in place. + template: + src: "{{ item }}.j2" + dest: "/etc/apt/apt.conf.d/{{ item }}" + owner: root + group: root + mode: 0644 + with_items: + - 10periodic + - 50unattended-upgrades diff --git a/provisioning/roles/geerlingguy.security/tasks/autoupdate-RedHat.yml b/provisioning/roles/geerlingguy.security/tasks/autoupdate-RedHat.yml new file mode 100644 index 000000000..80aa12113 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/tasks/autoupdate-RedHat.yml @@ -0,0 +1,35 @@ +--- +- name: Set correct automatic update utility vars (RHEL 8). + set_fact: + update_utility: dnf-automatic + update_service: dnf-automatic-install.timer + update_conf_path: /etc/dnf/automatic.conf + when: ansible_distribution_major_version | int == 8 + +- name: Set correct automatic update utility vars (RHEL <= 7). + set_fact: + update_utility: yum-cron + update_service: yum-cron + update_conf_path: /etc/yum/yum-cron.conf + when: ansible_distribution_major_version | int <= 7 + +- name: Install automatic update utility. + package: + name: '{{ update_utility }}' + state: present + +- name: Ensure automatic update utility is running and enabled on boot. + service: + name: '{{ update_service }}' + state: started + enabled: true + +- name: Configure autoupdates. + lineinfile: + dest: '{{ update_conf_path }}' + regexp: '^apply_updates = .+' + line: 'apply_updates = yes' + mode: 0644 + when: + - security_autoupdate_enabled + - ansible_distribution_major_version | int in [7, 8] diff --git a/provisioning/roles/geerlingguy.security/tasks/fail2ban.yml b/provisioning/roles/geerlingguy.security/tasks/fail2ban.yml new file mode 100644 index 000000000..1fab2f456 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/tasks/fail2ban.yml @@ -0,0 +1,27 @@ +--- +- name: Install fail2ban (RedHat). + package: + name: fail2ban + state: present + enablerepo: epel + when: ansible_os_family == 'RedHat' + +- name: Install fail2ban (Debian). + package: + name: fail2ban + state: present + when: ansible_os_family == 'Debian' + +- name: Copy fail2ban custom configuration file into place. + template: + src: "{{ security_fail2ban_custom_configuration_template }}" + dest: /etc/fail2ban/jail.local + owner: root + group: root + mode: 0644 + +- name: Ensure fail2ban is running and enabled on boot. + service: + name: fail2ban + state: started + enabled: true diff --git a/provisioning/roles/geerlingguy.security/tasks/main.yml b/provisioning/roles/geerlingguy.security/tasks/main.yml new file mode 100644 index 000000000..24e586063 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/tasks/main.yml @@ -0,0 +1,21 @@ +--- +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +# Fail2Ban +- include_tasks: fail2ban.yml + when: security_fail2ban_enabled | bool + +# SSH +- include_tasks: ssh.yml + +# Autoupdate +- include_tasks: autoupdate-RedHat.yml + when: + - ansible_os_family == 'RedHat' + - security_autoupdate_enabled | bool + +- include_tasks: autoupdate-Debian.yml + when: + - ansible_os_family == 'Debian' + - security_autoupdate_enabled | bool diff --git a/provisioning/roles/geerlingguy.security/tasks/ssh.yml b/provisioning/roles/geerlingguy.security/tasks/ssh.yml new file mode 100644 index 000000000..27e42beb7 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/tasks/ssh.yml @@ -0,0 +1,54 @@ +--- +- name: Ensure SSH daemon is running. + service: + name: "{{ security_sshd_name }}" + state: "{{ security_sshd_state }}" + +- name: Update SSH configuration to be more secure. + lineinfile: + dest: "{{ security_ssh_config_path }}" + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + state: present + validate: 'sshd -T -f %s' + mode: 0644 + with_items: + - regexp: "^PasswordAuthentication" + line: "PasswordAuthentication {{ security_ssh_password_authentication }}" + - regexp: "^PermitRootLogin" + line: "PermitRootLogin {{ security_ssh_permit_root_login }}" + - regexp: "^Port" + line: "Port {{ security_ssh_port }}" + - regexp: "^UseDNS" + line: "UseDNS {{ security_ssh_usedns }}" + - regexp: "^PermitEmptyPasswords" + line: "PermitEmptyPasswords {{ security_ssh_permit_empty_password }}" + - regexp: "^ChallengeResponseAuthentication" + line: "ChallengeResponseAuthentication {{ security_ssh_challenge_response_auth }}" + - regexp: "^GSSAPIAuthentication" + line: "GSSAPIAuthentication {{ security_ssh_gss_api_authentication }}" + - regexp: "^X11Forwarding" + line: "X11Forwarding {{ security_ssh_x11_forwarding }}" + notify: restart ssh + +- name: Add configured user accounts to passwordless sudoers. + lineinfile: + dest: /etc/sudoers + regexp: '^{{ item }}' + line: '{{ item }} ALL=(ALL) NOPASSWD: ALL' + state: present + validate: 'visudo -cf %s' + mode: 0644 + with_items: "{{ security_sudoers_passwordless }}" + when: security_sudoers_passwordless | length > 0 + +- name: Add configured user accounts to passworded sudoers. + lineinfile: + dest: /etc/sudoers + regexp: '^{{ item }}' + line: '{{ item }} ALL=(ALL) ALL' + state: present + validate: 'visudo -cf %s' + mode: 0644 + with_items: "{{ security_sudoers_passworded }}" + when: security_sudoers_passworded | length > 0 diff --git a/provisioning/roles/geerlingguy.security/templates/10periodic.j2 b/provisioning/roles/geerlingguy.security/templates/10periodic.j2 new file mode 100644 index 000000000..5d37e9fc0 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/templates/10periodic.j2 @@ -0,0 +1,4 @@ +APT::Periodic::Update-Package-Lists "1"; +APT::Periodic::Download-Upgradeable-Packages "1"; +APT::Periodic::AutocleanInterval "7"; +APT::Periodic::Unattended-Upgrade "1"; diff --git a/provisioning/roles/geerlingguy.security/templates/50unattended-upgrades.j2 b/provisioning/roles/geerlingguy.security/templates/50unattended-upgrades.j2 new file mode 100644 index 000000000..297f6969b --- /dev/null +++ b/provisioning/roles/geerlingguy.security/templates/50unattended-upgrades.j2 @@ -0,0 +1,20 @@ +Unattended-Upgrade::Automatic-Reboot "{{ security_autoupdate_reboot }}"; +Unattended-Upgrade::Automatic-Reboot-Time "{{ security_autoupdate_reboot_time }}"; + +{% if security_autoupdate_mail_to %} +Unattended-Upgrade::Mail "{{ security_autoupdate_mail_to }}"; +{% if security_autoupdate_mail_on_error %} +Unattended-Upgrade::MailOnlyOnError "true"; +{% endif %} +{% endif %} + +Unattended-Upgrade::Allowed-Origins { + "${distro_id} ${distro_codename}-security"; +// "${distro_id} ${distro_codename}-updates"; +}; + +Unattended-Upgrade::Package-Blacklist{ +{% for package in security_autoupdate_blacklist %} + "{{package}}"; +{% endfor %} +} diff --git a/provisioning/roles/geerlingguy.security/templates/jail.local.j2 b/provisioning/roles/geerlingguy.security/templates/jail.local.j2 new file mode 100644 index 000000000..de9b947f6 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/templates/jail.local.j2 @@ -0,0 +1,4 @@ +[sshd] +enabled = true +port = {{ security_ssh_port }} +filter = sshd diff --git a/provisioning/roles/geerlingguy.security/vars/Debian.yml b/provisioning/roles/geerlingguy.security/vars/Debian.yml new file mode 100644 index 000000000..c66e186e8 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/vars/Debian.yml @@ -0,0 +1,3 @@ +--- +security_ssh_config_path: /etc/ssh/sshd_config +security_sshd_name: ssh diff --git a/provisioning/roles/geerlingguy.security/vars/RedHat.yml b/provisioning/roles/geerlingguy.security/vars/RedHat.yml new file mode 100644 index 000000000..d7b192126 --- /dev/null +++ b/provisioning/roles/geerlingguy.security/vars/RedHat.yml @@ -0,0 +1,3 @@ +--- +security_ssh_config_path: /etc/ssh/sshd_config +security_sshd_name: sshd diff --git a/provisioning/roles/geerlingguy.solr/.ansible-lint b/provisioning/roles/geerlingguy.solr/.ansible-lint new file mode 100644 index 000000000..acc82551f --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/.ansible-lint @@ -0,0 +1,3 @@ +skip_list: + - 'yaml' + - 'role-name' diff --git a/provisioning/roles/geerlingguy.solr/.github/FUNDING.yml b/provisioning/roles/geerlingguy.solr/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.solr/.github/stale.yml b/provisioning/roles/geerlingguy.solr/.github/stale.yml new file mode 100644 index 000000000..3cc6ec313 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/.github/stale.yml @@ -0,0 +1,57 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - bug + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.solr/.github/workflows/ci.yml b/provisioning/roles/geerlingguy.solr/.github/workflows/ci.yml new file mode 100644 index 000000000..0ea2ada86 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/.github/workflows/ci.yml @@ -0,0 +1,88 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "30 6 * * 2" + +defaults: + run: + working-directory: 'geerlingguy.solr' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.solr' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + include: + # Solr 8. + - distro: centos7 + playbook: converge.yml + - distro: ubuntu1804 + playbook: converge.yml + - distro: debian10 + playbook: converge.yml + + # Solr 7. + - distro: centos7 + playbook: solr-7.yml + - distro: debian10 + playbook: solr-7.yml + + # Older versions. + - distro: ubuntu1604 + playbook: solr-6.yml + - distro: ubuntu1604 + playbook: solr-5.yml + - distro: ubuntu1604 + playbook: solr-4.yml + - distro: ubuntu1604 + playbook: solr-3.yml + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.solr' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} + MOLECULE_PLAYBOOK: ${{ matrix.playbook }} diff --git a/provisioning/roles/geerlingguy.solr/.github/workflows/release.yml b/provisioning/roles/geerlingguy.solr/.github/workflows/release.yml new file mode 100644 index 000000000..4d280a521 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/.github/workflows/release.yml @@ -0,0 +1,38 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.solr' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.solr' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-base + + - name: Trigger a new import on Galaxy. + run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/provisioning/roles/geerlingguy.solr/.gitignore b/provisioning/roles/geerlingguy.solr/.gitignore new file mode 100644 index 000000000..8840c8f02 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/.gitignore @@ -0,0 +1,5 @@ +*.retry +*/__pycache__ +*.pyc +.cache + diff --git a/provisioning/roles/geerlingguy.solr/.yamllint b/provisioning/roles/geerlingguy.solr/.yamllint new file mode 100644 index 000000000..f2033dd21 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/provisioning/roles/geerlingguy.solr/LICENSE b/provisioning/roles/geerlingguy.solr/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.solr/README.md b/provisioning/roles/geerlingguy.solr/README.md new file mode 100644 index 000000000..6631c2c03 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/README.md @@ -0,0 +1,113 @@ +# Ansible Role: Apache Solr + +[![CI](https://github.com/geerlingguy/ansible-role-solr/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-solr/actions?query=workflow%3ACI) + +Installs [Apache Solr](http://lucene.apache.org/solr/) on Linux servers. + +## Requirements + +Java must be available on the server. You can easily install Java using the `geerlingguy.java` role. Make sure the Java version installed meets the minimum requirements of Solr (e.g. Java 8 for Solr 6+). + +This role is currently tested and working with Solr 3.x, 4.x, 5.x, 6.x, 7.x, and 8.x. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + solr_workspace: /root + +Files will be downloaded to this path on the remote server before being moved into place. + + solr_create_user: true + solr_user: solr + solr_group: "{{ solr_user }}" + +Solr will be run under the `solr_user`. Set `solr_create_user` to `false` if `solr_user` is created before this role runs, or if you're using Solr 5+ and want Solr's own installation script to set up the user. By default, `solr_group` equals `solr_user`, but it can be overwritten to fit your own configuration. + + solr_version: "8.11.1" + +The Apache Solr version to install. For a full list, see [available Apache Solr versions](http://archive.apache.org/dist/lucene/solr/). + + solr_mirror: "https://archive.apache.org/dist" + +The Apache Project mirror from which the Solr tarball will be downloaded. In case of slow download speed or timeouts it is useful to set the mirror to the one suggested by Apache's [mirror download site](https://www.apache.org/dyn/closer.cgi/lucene/solr/). + + solr_remove_cruft: false + +Whether to remove unneccessary documentation and examples from the solr directory. + + solr_service_manage: true + solr_service_name: solr + solr_service_state: started + +By default, this role will manage the `solr` service, ensuring it is enabled at system boot and is running. You can ensure Solr is stopped by setting `solr_service_state: stopped`, or you can disable this role's management of the `solr` service entirely by setting `solr_service_manage: false`. You may also want to set `solr_restart_handler_enabled: false` (documented later) in this case. + + solr_install_dir: /opt + solr_install_path: /opt/solr + +The path where Apache Solr will be installed. For Solr 5+, the `solr_install_dir` will be used by Solr's installation script. For Solr < 5, the Solr installation files will be copied in place in the `solr_install_path`. + + solr_home: /var/solr + +The path where local Solr data (search collections and configuration) will be stored. Should typically be outside of the `solr_path`, to make Solr upgrades easier. + + solr_port: "8983" + +The port on which Solr will run. + + solr_xms: "256M" + solr_xmx: "512M" + +Memory settings for the JVM. These should be set as high as you can allow for best performance and to reduce the chance of Solr restarting itself due to OOM situations. + + solr_timezone: "UTC" + +Default timezone of JVM running solr. You can override this if needed when using dataimport and delta imports (ex: comparing against a MySQL external data source). Read through Apache Solr's [Working with Dates](https://cwiki.apache.org/confluence/display/solr/Working+with+Dates) documentation for more background. + + solr_opts: "$SOLR_OPTS -Dlog4j2.formatMsgNoLookups=true" + +Solr options. This option was added to the role in part to mitigate [CVE-2021-44228](https://solr.apache.org/security.html#apache-solr-affected-by-apache-log4j-cve-2021-44228). + + solr_cores: + - collection1 + +A list of cores / collections which should exist on the server. Each one will be created (if it doesn't exist already) using the default example configuration that ships with Solr. Note that this variable only applies when using Solr 5+. + + solr_connect_host: localhost + +The hostname or IP address on which Solr will be reachable. `localhost` should work in most circumstances, but there are special cases where you may only be able to access the local Solr instance via another IP or hostname. + + solr_restart_handler_enabled: true + +Whether the `restart solr` handler should be used or not. If you're building containers or AMIs, you might need to disable the restart handler for a provisioning run. + +### Variables used only for Solr < 5. + +The following variables are currently only applied to installations of Solr 4 and below: + + solr_log_file_path: /var/log/solr.log + +Path where Solr log file will be created. + + solr_host: "0.0.0.0" + +The hostname or IP address to which Solr will bind. Defaults to `0.0.0.0` which allows Solr to listen on all interfaces. + +## Dependencies + +None. + +## Example Playbook + + - hosts: solr-servers + roles: + - geerlingguy.java + - geerlingguy.solr + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.solr/defaults/main.yml b/provisioning/roles/geerlingguy.solr/defaults/main.yml new file mode 100644 index 000000000..72aed123a --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/defaults/main.yml @@ -0,0 +1,39 @@ +--- +solr_workspace: /root + +solr_create_user: true +solr_user: solr +solr_group: "{{ solr_user }}" + +solr_version: "8.11.1" +solr_mirror: "https://archive.apache.org/dist" +solr_remove_cruft: false + +solr_service_manage: true +solr_service_name: solr +solr_service_state: started + +solr_install_dir: /opt +solr_install_path: "/opt/{{ solr_service_name }}" +solr_home: "/var/{{ solr_service_name }}" +solr_connect_host: localhost +solr_port: "8983" + +solr_xms: "256M" +solr_xmx: "512M" + +solr_timezone: "UTC" + +solr_opts: "$SOLR_OPTS -Dlog4j2.formatMsgNoLookups=true" + +solr_cores: + - collection1 + +solr_config_file: /etc/default/{{ solr_service_name }}.in.sh + +# Enable restart solr handler +solr_restart_handler_enabled: true + +# Used only for Solr < 5. +solr_log_file_path: /var/log/solr.log +solr_host: "0.0.0.0" diff --git a/provisioning/roles/geerlingguy.solr/handlers/main.yml b/provisioning/roles/geerlingguy.solr/handlers/main.yml new file mode 100644 index 000000000..e2f1c9e1c --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/handlers/main.yml @@ -0,0 +1,7 @@ +--- +- name: restart solr + service: + name: "{{ solr_service_name }}" + state: restarted + sleep: 5 + when: solr_restart_handler_enabled diff --git a/provisioning/roles/geerlingguy.solr/meta/main.yml b/provisioning/roles/geerlingguy.solr/meta/main.yml new file mode 100644 index 000000000..82b560821 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/meta/main.yml @@ -0,0 +1,29 @@ +--- +dependencies: [] + +galaxy_info: + role_name: solr + author: geerlingguy + description: Apache Solr for Linux. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - 7 + - 8 + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + galaxy_tags: + - development + - solr + - search + - lucene + - container + - apache + - text diff --git a/provisioning/roles/geerlingguy.solr/molecule/default/converge.yml b/provisioning/roles/geerlingguy.solr/molecule/default/converge.yml new file mode 100644 index 000000000..33a4f13f1 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/molecule/default/converge.yml @@ -0,0 +1,40 @@ +--- +- name: Converge + hosts: all + become: true + + pre_tasks: + - name: Set Java 8 package for RedHat. + set_fact: + java_packages: + - java-1.8.0-openjdk + when: ansible_os_family == "RedHat" + + - name: Set Java 8 package for Ubuntu. + set_fact: + java_packages: + - openjdk-8-jdk + when: ansible_os_family == "Ubuntu" + + - name: Set Java 11 package for Debian. + set_fact: + java_packages: + - openjdk-11-jdk + when: ansible_os_family == "Debian" + + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == "Debian" + + # See: http://unix.stackexchange.com/a/342469 + - name: Install dependencies (Debian). + apt: + name: + - openjdk-11-jre-headless + - ca-certificates-java + state: present + when: ansible_distribution == "Debian" + + roles: + - role: geerlingguy.java + - role: geerlingguy.solr diff --git a/provisioning/roles/geerlingguy.solr/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.solr/molecule/default/molecule.yml new file mode 100644 index 000000000..74907107f --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.solr/molecule/default/requirements.yml b/provisioning/roles/geerlingguy.solr/molecule/default/requirements.yml new file mode 100644 index 000000000..8fbe7cb66 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/molecule/default/requirements.yml @@ -0,0 +1,2 @@ +--- +- src: geerlingguy.java diff --git a/provisioning/roles/geerlingguy.solr/molecule/default/solr-3.yml b/provisioning/roles/geerlingguy.solr/molecule/default/solr-3.yml new file mode 100644 index 000000000..07fd927b2 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/molecule/default/solr-3.yml @@ -0,0 +1,16 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + solr_version: "3.6.2" + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == "Debian" + + roles: + - role: geerlingguy.java + - role: geerlingguy.solr diff --git a/provisioning/roles/geerlingguy.solr/molecule/default/solr-4.yml b/provisioning/roles/geerlingguy.solr/molecule/default/solr-4.yml new file mode 100644 index 000000000..954242bd2 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/molecule/default/solr-4.yml @@ -0,0 +1,17 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + solr_version: "4.10.4" + solr_remove_cruft: true + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == "Debian" + + roles: + - role: geerlingguy.java + - role: geerlingguy.solr diff --git a/provisioning/roles/geerlingguy.solr/molecule/default/solr-5.yml b/provisioning/roles/geerlingguy.solr/molecule/default/solr-5.yml new file mode 100644 index 000000000..96d753a0e --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/molecule/default/solr-5.yml @@ -0,0 +1,19 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + solr_version: "5.5.5" + solr_remove_cruft: true + java_packages: + - openjdk-8-jdk + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == "Debian" + + roles: + - role: geerlingguy.java + - role: geerlingguy.solr diff --git a/provisioning/roles/geerlingguy.solr/molecule/default/solr-6.yml b/provisioning/roles/geerlingguy.solr/molecule/default/solr-6.yml new file mode 100644 index 000000000..435b4710a --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/molecule/default/solr-6.yml @@ -0,0 +1,43 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + solr_version: "6.6.6" + + pre_tasks: + - name: Set Java 8 package for RedHat. + set_fact: + java_packages: + - java-1.8.0-openjdk + when: ansible_os_family == "RedHat" + + - name: Set Java 8 package for Ubuntu. + set_fact: + java_packages: + - openjdk-8-jdk + when: ansible_distribution == "Ubuntu" + + - name: Set Java 11 package for Debian. + set_fact: + java_packages: + - openjdk-11-jdk + when: ansible_distribution == "Debian" + + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == "Debian" + + # See: http://unix.stackexchange.com/a/342469 + - name: Install dependencies (Debian). + apt: + name: + - openjdk-11-jre-headless + - ca-certificates-java + state: present + when: ansible_distribution == "Debian" + + roles: + - role: geerlingguy.java + - role: geerlingguy.solr diff --git a/provisioning/roles/geerlingguy.solr/molecule/default/solr-7.yml b/provisioning/roles/geerlingguy.solr/molecule/default/solr-7.yml new file mode 100644 index 000000000..c6b6f74f7 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/molecule/default/solr-7.yml @@ -0,0 +1,43 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + solr_version: "7.7.3" + + pre_tasks: + - name: Set Java 8 package for RedHat. + set_fact: + java_packages: + - java-1.8.0-openjdk + when: ansible_os_family == "RedHat" + + - name: Set Java 8 package for Ubuntu. + set_fact: + java_packages: + - openjdk-8-jdk + when: ansible_distribution == "Ubuntu" + + - name: Set Java 11 package for Debian. + set_fact: + java_packages: + - openjdk-11-jdk + when: ansible_distribution == "Debian" + + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == "Debian" + + # See: http://unix.stackexchange.com/a/342469 + - name: Install dependencies (Debian). + apt: + name: + - openjdk-11-jre-headless + - ca-certificates-java + state: present + when: ansible_distribution == "Debian" + + roles: + - role: geerlingguy.java + - role: geerlingguy.solr diff --git a/provisioning/roles/geerlingguy.solr/tasks/configure.yml b/provisioning/roles/geerlingguy.solr/tasks/configure.yml new file mode 100644 index 000000000..aa63878a1 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/tasks/configure.yml @@ -0,0 +1,25 @@ +--- +- name: Remove existing SOLR_HEAP configuration. + lineinfile: + dest: "{{ solr_config_file }}" + regexp: "^SOLR_HEAP" + state: absent + notify: restart solr + +- name: Apply Solr configuration changes. + lineinfile: + dest: "{{ solr_config_file }}" + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + state: present + mode: 0644 + with_items: + - regexp: "^.?SOLR_JAVA_MEM=" + line: 'SOLR_JAVA_MEM="-Xms{{ solr_xms }} -Xmx{{ solr_xmx }}"' + - regexp: "^SOLR_PORT=" + line: 'SOLR_PORT="{{ solr_port }}"' + - regexp: "^.?SOLR_TIMEZONE=" + line: 'SOLR_TIMEZONE="{{ solr_timezone }}"' + - regexp: "^.?SOLR_OPTS=" + line: 'SOLR_OPTS="{{ solr_opts }}"' + notify: restart solr diff --git a/provisioning/roles/geerlingguy.solr/tasks/cores.yml b/provisioning/roles/geerlingguy.solr/tasks/cores.yml new file mode 100644 index 000000000..aead23c7b --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/tasks/cores.yml @@ -0,0 +1,32 @@ +--- +- name: Check current list of Solr cores. + uri: + url: http://{{ solr_connect_host }}:{{ solr_port }}/solr/admin/cores + return_content: true + register: solr_cores_current + check_mode: false + +- name: Ensure Solr conf directories exist. + file: + path: "{{ solr_home }}/data/{{ item }}/conf" + state: directory + owner: "{{ solr_user }}" + group: "{{ solr_group }}" + recurse: true + mode: 0755 + when: "item not in solr_cores_current.content" + with_items: "{{ solr_cores }}" + +- name: Ensure core configuration directories exist. + command: "cp -r {{ solr_install_path }}/example/files/conf/ {{ solr_home }}/data/{{ item }}/" + when: "item not in solr_cores_current.content" + with_items: "{{ solr_cores }}" + become: true + become_user: "{{ solr_user }}" + +- name: Create configured cores. + command: "{{ solr_install_path }}/bin/solr create -c {{ item }} -p {{ solr_port }}" + when: "item not in solr_cores_current.content" + with_items: "{{ solr_cores }}" + become: true + become_user: "{{ solr_user }}" diff --git a/provisioning/roles/geerlingguy.solr/tasks/install-pre5.yml b/provisioning/roles/geerlingguy.solr/tasks/install-pre5.yml new file mode 100644 index 000000000..f891904ad --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/tasks/install-pre5.yml @@ -0,0 +1,84 @@ +--- +# Install Solr. +- name: Check if Solr is already installed. + stat: "path={{ solr_install_path }}/dist/{{ solr_filename }}.war" + register: solr_war_file + +- name: Copy Solr into place. + command: "cp -r {{ solr_workspace }}/{{ solr_filename }} {{ solr_install_path }}" + when: not solr_war_file.stat.exists + +- name: Ensure Solr install files are owned by the solr_user. + file: # noqa 208 + path: "{{ solr_install_path }}" + owner: "{{ solr_user }}" + group: "{{ solr_group }}" + recurse: true + when: not solr_war_file.stat.exists + +# Set up solr_home. +- name: Check if solr_home is already set up. + stat: "path={{ solr_home }}/solr.xml" + register: solr_example + +- name: Ensure solr_home directory exists. + file: + path: "{{ solr_home }}" + state: directory + owner: "{{ solr_user }}" + group: "{{ solr_group }}" + mode: 0755 + when: not solr_example.stat.exists + +- name: Copy Solr example into solr_home. + shell: "cp -r {{ solr_install_path }}/example/solr/* {{ solr_home }}" + when: not solr_example.stat.exists + +- name: Fix the example solrconfig.xml file. + replace: + dest: "{{ solr_home }}/collection1/conf/solrconfig.xml" + regexp: ^.+solr\.install\.dir.+$ + replace: "" + mode: 0644 + when: "not solr_example.stat.exists and solr_version.split('.')[0] == '4'" + +- name: Ensure Solr home files are owned by the solr_user. + file: # noqa 208 + path: "{{ solr_home }}" + owner: "{{ solr_user }}" + group: "{{ solr_group }}" + recurse: true + when: not solr_example.stat.exists + +# Set up Solr init script. +- name: Ensure log file is created and has proper permissions. + file: + path: "/var/log/solr.log" + state: touch + owner: "{{ solr_user }}" + group: root + mode: 0664 + changed_when: false + when: ansible_service_mgr != 'systemd' + +- name: Copy solr init script into place. + template: + src: "solr-init-{{ ansible_os_family }}-pre5.j2" + dest: "/etc/init.d/{{ solr_service_name }}" + mode: 0755 + when: ansible_service_mgr != 'systemd' + +- name: Ensure daemon is installed (Debian). + apt: name=daemon state=present + when: + - ansible_os_family == "Debian" + - ansible_service_mgr != 'systemd' + +- name: Copy solr systemd unit file into place (for systemd systems). + template: + src: solr-pre5.unit.j2 + dest: /etc/systemd/system/{{ solr_service_name }}.service + owner: root + group: root + mode: 0755 + when: ansible_service_mgr == 'systemd' diff --git a/provisioning/roles/geerlingguy.solr/tasks/install.yml b/provisioning/roles/geerlingguy.solr/tasks/install.yml new file mode 100644 index 000000000..9f02f5665 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/tasks/install.yml @@ -0,0 +1,43 @@ +--- +- name: Ensure dependencies are installed. + package: + name: + - lsof + - acl + - sudo + state: present + +# We add '-n' to Solr versions beyond 6.3.0 to prevent autostart on install. +- name: Run Solr installation script. + command: > + {{ solr_workspace }}/{{ solr_filename }}/bin/install_solr_service.sh + {{ solr_workspace }}/{{ solr_filename }}.tgz + -i {{ solr_install_dir }} + -d {{ solr_home }} + -u {{ solr_user }} + -s {{ solr_service_name }} + -p {{ solr_port }} + {{ (solr_version is version('6.3.0', '>=')) | ternary('-n','') }} + {{ (solr_version is version('5.4.0', '>=')) | ternary('-f','') }} + creates={{ solr_install_path }}/bin/solr + register: solr_install_script_result + +# Workaround for bug https://github.com/ansible/ansible-modules-core/issues/915. +- name: Ensure solr is stopped (RHEL 7 workaround). + command: service {{ solr_service_name }} stop + when: + - ansible_os_family == 'RedHat' + - ansible_distribution_version.split(".")[0] == '7' + - solr_install_script_result.changed + failed_when: false + tags: ['skip_ansible_lint'] + +- name: Run systemd daemon_reload (RHEL 7 workaround). + systemd: + name: solr + daemon_reload: true + when: + - ansible_os_family == 'RedHat' + - ansible_distribution_version.split(".")[0] == '7' + - solr_install_script_result.changed + tags: ['skip_ansible_lint'] diff --git a/provisioning/roles/geerlingguy.solr/tasks/main.yml b/provisioning/roles/geerlingguy.solr/tasks/main.yml new file mode 100644 index 000000000..bff4894f0 --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/tasks/main.yml @@ -0,0 +1,59 @@ +--- +- import_tasks: user.yml + when: solr_create_user + +- name: Set solr_filename for Solr 4+. + set_fact: + solr_filename: "solr-{{ solr_version }}" + when: "solr_version.split('.')[0] >= '4'" + +- name: Set solr_filename for Solr 3.x. + set_fact: + solr_filename: "apache-solr-{{ solr_version }}" + when: "solr_version.split('.')[0] == '3'" + +- name: Check if Solr has been installed already. + stat: + path: "{{ solr_install_path }}" + register: solr_install_path_status + +- name: Download Solr. + get_url: + url: "{{ solr_mirror }}/lucene/solr/{{ solr_version }}/{{ solr_filename }}.tgz" + dest: "{{ solr_workspace }}/{{ solr_filename }}.tgz" + force: false + when: solr_install_path_status.stat.isdir is not defined + register: solr_download_status + +- name: Expand Solr. + unarchive: + src: "{{ solr_workspace }}/{{ solr_filename }}.tgz" + dest: "{{ solr_workspace }}" + copy: false + when: solr_download_status.changed + tags: ['skip_ansible_lint'] + +# Install Solr < 5. +- include_tasks: install-pre5.yml + when: "solr_version.split('.')[0] < '5'" + +# Install Solr 5+. +- include_tasks: install.yml + when: "solr_version.split('.')[0] >= '5'" + +- name: Ensure solr is started and enabled on boot if configured. + service: + name: "{{ solr_service_name }}" + state: "{{ solr_service_state }}" + enabled: true + when: solr_service_manage + +# Configure solr. +- include_tasks: configure.yml + when: "solr_version.split('.')[0] >= '5'" + +# Create cores, if any are configured. +- include_tasks: cores.yml + when: "solr_cores and solr_version.split('.')[0] >= '5'" + +- include_tasks: trim-fat.yml diff --git a/provisioning/roles/geerlingguy.solr/tasks/trim-fat.yml b/provisioning/roles/geerlingguy.solr/tasks/trim-fat.yml new file mode 100644 index 000000000..f5a87e55e --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/tasks/trim-fat.yml @@ -0,0 +1,22 @@ +--- +- name: Remove the downloaded Solr archive. + file: + path: "{{ item }}" + state: absent + with_items: + - "{{ solr_workspace }}/{{ solr_filename }}.tgz" + - "{{ solr_workspace }}/{{ solr_filename }}" + +- name: Remove docs, if not needed. + file: + path: "{{ solr_install_path }}/docs" + state: absent + when: solr_remove_cruft + +- name: Remove example dir, if not needed. + file: + path: "{{ solr_install_path }}/example" + state: absent + when: + - solr_remove_cruft + - solr_version.split('.')[0] >= '5' diff --git a/provisioning/roles/geerlingguy.solr/tasks/user.yml b/provisioning/roles/geerlingguy.solr/tasks/user.yml new file mode 100644 index 000000000..6ef1f7f1f --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/tasks/user.yml @@ -0,0 +1,9 @@ +--- +- name: Ensure solr_group exists. + group: "name={{ solr_group }} state=present" + +- name: Ensure solr_user exists. + user: + name: "{{ solr_user }}" + state: present + group: "{{ solr_group }}" diff --git a/provisioning/roles/geerlingguy.solr/templates/solr-init-Debian-pre5.j2 b/provisioning/roles/geerlingguy.solr/templates/solr-init-Debian-pre5.j2 new file mode 100644 index 000000000..1dd40cf9d --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/templates/solr-init-Debian-pre5.j2 @@ -0,0 +1,94 @@ +#!/bin/sh +# chkconfig: 2345 95 05 +# description: Controls an Apache Solr process. +# +# This script will launch Solr in a mode that will automatically respawn if it +# crashes. Output will be sent to $LOG_FILE. A PID file will be created in the +# standard location. +# +# Adapted by Jeff Geerling from http://stackoverflow.com/a/8014720/100134 + +### BEGIN INIT INFO +# Provides: {{ solr_service_name }} +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Apache Solr search server +### END INIT INFO + +SOLR_DIR="{{ solr_install_path }}/example" +JAVA_OPTIONS="-Dsolr.solr.home={{ solr_home }} -Djetty.host={{ solr_host }} -Djetty.port={{ solr_port }} -Xms{{ solr_xms }} -Xmx{{ solr_xmx }}" +START_COMMAND="java -jar $JAVA_OPTIONS start.jar" +LOG_FILE="{{ solr_log_file_path }}" + +start () { + echo -n "Starting {{ solr_service_name }}... " + + daemon -U --chdir="$SOLR_DIR" --command "$START_COMMAND" --respawn --output=$LOG_FILE --name={{ solr_service_name }} + + RETVAL=$? + if [ $RETVAL = 0 ] + then + echo "done." + else + echo "failed. See error code for more information." + fi + return $RETVAL +} + +stop () { + echo -n "Stopping {{ solr_service_name }}... " + + daemon --stop --name={{ solr_service_name }} + + RETVAL=$? + if [ $RETVAL = 0 ] + then + echo "done." + else + echo "failed. See error code for more information." + fi + return $RETVAL +} + +restart () { + echo -n "Restarting solr... " + daemon --restart --name={{ solr_service_name }} + + RETVAL=$? + if [ $RETVAL = 0 ] + then + echo "done." + else + echo "failed. See error code for more information." + fi + return $RETVAL +} + +check_status () { + # Report on the status of the daemon + daemon --running --name={{ solr_service_name }} --verbose + return $? +} + +case "$1" in + start) + start + ;; + status) + check_status + ;; + stop) + stop + ;; + restart) + restart + ;; + *) + echo $"Usage: solr {start|status|stop|restart}" + exit 3 + ;; +esac + +exit $RETVAL diff --git a/provisioning/roles/geerlingguy.solr/templates/solr-init-RedHat-pre5.j2 b/provisioning/roles/geerlingguy.solr/templates/solr-init-RedHat-pre5.j2 new file mode 100644 index 000000000..979a2176c --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/templates/solr-init-RedHat-pre5.j2 @@ -0,0 +1,91 @@ +#!/bin/sh +# chkconfig: 2345 95 05 +# description: Controls an Apache Solr process. +# +# TODO: Describe this file. +# +# @author Jeff Geerling, 2015 + +. /etc/rc.d/init.d/functions + +SOLR_DIR="{{ solr_install_path }}/example" +JAVA_OPTIONS="-Dsolr.solr.home={{ solr_home }} -Djetty.host={{ solr_host }} -Djetty.port={{ solr_port }} -Xms{{ solr_xms }} -Xmx{{ solr_xmx }} -DSTOP.PORT=8079 -DSTOP.KEY=secret" +START_COMMAND="java -jar $JAVA_OPTIONS start.jar" +STOP_COMMAND="java -jar $JAVA_OPTIONS $SOLR_DIR/start.jar --stop" +LOG_FILE="{{ solr_log_file_path }}" + +start () { + echo -n "Starting solr... " + + if ps aux | grep "[s]olr.solr.home" > /dev/null + then + echo -n "already started... " + else + cd "$SOLR_DIR" && daemon --user="{{ solr_user }}" $START_COMMAND > $LOG_FILE & + fi + + RETVAL=$? + if [ $RETVAL = 0 ] + then + echo "done." + else + echo "failed. See error code for more information." + fi + return $RETVAL +} + +stop () { + echo -n "Stopping solr... " + + if ps aux | grep "[s]olr.solr.home" > /dev/null + then + $STOP_COMMAND + else + echo -n "already stopped... " + fi + + RETVAL=$? + if [ $RETVAL = 0 ] + then + echo "done." + else + echo "failed. See error code for more information." + fi + return $RETVAL +} + +restart () { + $0 stop + sleep 3 + $0 start +} + +check_status () { + if ps aux | grep "[s]olr.solr.home" > /dev/null + then + printf "Solr is running.\n" + else + printf "Solr is stopped.\n" + fi +} + +case "$1" in + start) + start + ;; + status) + check_status + ;; + stop) + stop + ;; + restart) + restart + ;; + *) + echo $"Usage: solr {start|status|stop|restart}" + exit 3 + ;; +esac + +exit $RETVAL diff --git a/provisioning/roles/geerlingguy.solr/templates/solr-pre5.unit.j2 b/provisioning/roles/geerlingguy.solr/templates/solr-pre5.unit.j2 new file mode 100644 index 000000000..edc46ef0b --- /dev/null +++ b/provisioning/roles/geerlingguy.solr/templates/solr-pre5.unit.j2 @@ -0,0 +1,13 @@ +[Unit] +Description=Apache SOLR +After=syslog.target network.target remote-fs.target nss-lookup.target + +[Service] +Type=simple +WorkingDirectory={{ solr_install_path }}/example +ExecStart=/usr/bin/java -jar -Dsolr.solr.home={{ solr_home }} -Djetty.host={{ solr_host }} -Djetty.port={{ solr_port }} -Xms{{ solr_xms }} -Xmx{{ solr_xmx }} start.jar +Restart=on-failure +User={{ solr_user }} + +[Install] +WantedBy=multi-user.target diff --git a/provisioning/roles/geerlingguy.varnish/.github/FUNDING.yml b/provisioning/roles/geerlingguy.varnish/.github/FUNDING.yml new file mode 100644 index 000000000..96b493831 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/provisioning/roles/geerlingguy.varnish/.github/stale.yml b/provisioning/roles/geerlingguy.varnish/.github/stale.yml new file mode 100644 index 000000000..c7ff12754 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/.github/stale.yml @@ -0,0 +1,56 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/provisioning/roles/geerlingguy.varnish/.gitignore b/provisioning/roles/geerlingguy.varnish/.gitignore new file mode 100644 index 000000000..f56f5b578 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/.gitignore @@ -0,0 +1,3 @@ +*.retry +*/__pycache__ +*.pyc diff --git a/provisioning/roles/geerlingguy.varnish/.travis.yml b/provisioning/roles/geerlingguy.varnish/.travis.yml new file mode 100644 index 000000000..917d1be3d --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/.travis.yml @@ -0,0 +1,34 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: varnish + matrix: + - MOLECULE_DISTRO: centos8 + - MOLECULE_DISTRO: centos7 + - MOLECULE_DISTRO: ubuntu1804 + - MOLECULE_DISTRO: ubuntu1604 + - MOLECULE_DISTRO: debian10 + - MOLECULE_DISTRO: debian9 + + - MOLECULE_DISTRO: centos7 + MOLECULE_PLAYBOOK: playbook-41.yml + +install: + # Install test dependencies. + - pip install molecule yamllint ansible-lint docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/geerlingguy.varnish/.yamllint b/provisioning/roles/geerlingguy.varnish/.yamllint new file mode 100644 index 000000000..f14ed57c4 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/.yamllint @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 180 + level: warning diff --git a/provisioning/roles/geerlingguy.varnish/LICENSE b/provisioning/roles/geerlingguy.varnish/LICENSE new file mode 100644 index 000000000..4275cf3c1 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/geerlingguy.varnish/README.md b/provisioning/roles/geerlingguy.varnish/README.md new file mode 100644 index 000000000..fc48da7f7 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/README.md @@ -0,0 +1,127 @@ +# Ansible Role: Varnish + +[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-varnish.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-varnish) + +Installs the [Varnish HTTP Cache](https://varnish-cache.org/) on RedHat/CentOS or Debian/Ubuntu Linux. + +## Requirements + +Requires the EPEL repository on RedHat/CentOS (you can install it using the `geerlingguy.repo-epel` role). + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + varnish_package_name: "varnish" + +Varnish package name you want to install. See `apt-cache policy varnish` or `yum list varnish` for a listing of available candidates. + + varnish_version: "6.4" + +Varnish version that should be installed. See the [Varnish Cache packagecloud.io repositories](https://packagecloud.io/varnishcache) for a listing of available versions. Some examples include: `6.4`, `6.3`, `6.1`, `4.1`, `3.0`, and `2.1`. + + varnish_config_path: /etc/varnish + +The path in which Varnish configuration files will be stored. + + varnish_use_default_vcl: true + +Whether to use the included (simplistic) default Varnish VCL, using the backend host/port defined with the next two variables. Set this to `false` and copy your own `default.vcl` file into the `varnish_config_path` if you'd like to use a more complicated setup. If this variable is set to `true`, all other configuration will be taken from Varnish's own [default VCL](https://www.varnish-cache.org/trac/browser/bin/varnishd/default.vcl?rev=3.0). + + varnish_default_vcl_template_path: default.vcl.j2 + +The default VCL file to be copied (if `varnish_use_default_vcl` is `true`). Defaults the the simple template inside `templates/default.vcl.j2`. This path should be relative to the directory from which you run your playbook. + + varnish_listen_address: "" + varnish_listen_port: "80" + +The address and port on which Varnish will listen. The defaults tell Varnish to listen on all interfaces on port 80, but you can specify an address and/or alternate port if desired. + + varnish_default_backend_host: "127.0.0.1" + varnish_default_backend_port: "8080" + +Some settings for the default "default.vcl" template that will be copied to the `varnish_config_path` folder. The default backend host/port could be Apache or Nginx (or some other HTTP server) running on the same host or some other host (in which case, you might use port 80 instead). + + varnish_limit_nofile: 131072 + +The `nofiles` PAM limit Varnish will attempt to set for open files. The normal default is 1024 which is much too low for Varnish usage. + + varnish_secret: "14bac2e6-1e34-4770-8078-974373b76c90" + +The secret/key to be used for connecting to Varnish's admin backend (for purge requests, etc.). + + varnish_admin_listen_host: "127.0.0.1" + varnish_admin_listen_port: "6082" + +The host and port through which Varnish will accept admin requests (like purge and status requests). + + varnish_storage: "file,/var/lib/varnish/varnish_storage.bin,256M" + +How Varnish stores cache entries (this is passed in as the argument for `-s`). If you want to use in-memory storage, change to something like `malloc,256M`. Please read Varnish's [Getting Started guide](http://book.varnish-software.com/4.0/chapters/Getting_Started.html) for more information. + + varnish_pidfile: /run/varnishd.pid + +Varnish PID file path. Set to an empty string if you don't want to use a PID file. + + varnishd_extra_options: "" + +Extra options or flags to pass to the Varnish daemon when it starts (e.g. `-p http_max_hdr=128`). + + varnish_enabled_services: + - varnish + +Services that will be started at boot and should be running after this role is complete. You might need to add additional services if required, e.g. `varnishncsa` and `varnishlog`. If set to an empty array, no services will be enabled at startup. + + varnish_packagecloud_repo_yum_repository_priority: "1" + +(RedHat/CentOS only) The `yum` priority for the Packagecloud repository used to install Varnish. Setting this explicitly forces yum to use the Packagecloud repositories to install Varnish even in environments (e.g. Amazon Linux) where other repositories may have higher priorities than the default. + + varnish_apt_repo: deb https://packagecloud.io/varnishcache/{{ varnish_packagecloud_repo }}/{{ ansible_distribution | lower }}/ {{ ansible_distribution_release }} main + +(Debian/Ubuntu only) The `repo` for the apt repository. + + varnish_yum_repo_baseurl: https://packagecloud.io/varnishcache/{{ varnish_packagecloud_repo }}/el/{{ ansible_distribution_major_version|int }}/$basearch + +(RedHat/CentOS only) The `baseurl` for the yum repository. + + varnish_backends: + apache: + host: 10.0.2.2 + port: 80 + nodejs: + host: 10.0.2.3 + port: 80 + + varnish_vhosts: + example.com: + backend: apache + nodejs.example.com: + backend: nodejs + +You can configure multiple backends (and direct traffic from multiple virtual hosts to different backends) using the `varnish_backends` and `varnish_vhosts` variables. If you only use one backend (defined via `varnish_default_backend_host` and `varnish_default_backend_port`), then you do not need to define these variables. Do not add a `www` to the `vhosts` keys; it is added automatically by the `default.vcl.j2` VCL template. + +## Dependencies + +None. + +## Example Playbook + + - hosts: webservers + vars_files: + - vars/main.yml + roles: + - geerlingguy.varnish + +*Inside `vars/main.yml`*: + + varnish_secret: "[secret generated by uuidgen]" + varnish_default_backend_port: 81 + ... etc ... + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/provisioning/roles/geerlingguy.varnish/defaults/main.yml b/provisioning/roles/geerlingguy.varnish/defaults/main.yml new file mode 100644 index 000000000..d0f5e7df9 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/defaults/main.yml @@ -0,0 +1,51 @@ +--- +varnish_package_name: "varnish" +varnish_version: "6.4" + +varnish_use_default_vcl: true +varnish_default_vcl_template_path: default.vcl.j2 + +varnish_default_backend_host: "127.0.0.1" +varnish_default_backend_port: "8080" + +varnish_listen_address: "" +varnish_listen_port: "80" +varnish_secret: "14bac2e6-1e34-4770-8078-974373b76c90" +varnish_config_path: /etc/varnish +varnish_limit_nofile: 131072 + +varnish_admin_listen_host: "127.0.0.1" +varnish_admin_listen_port: "6082" + +varnish_storage: "file,/var/lib/varnish/varnish_storage.bin,256M" +varnish_pidfile: /run/varnishd.pid + +varnishd_extra_options: "" + +varnish_enabled_services: + - varnish + +# Make sure Packagecloud repo is used on RHEL/CentOS. +varnish_packagecloud_repo_yum_repository_priority: "1" + +# Only used on RedHat / CentOS. +varnish_yum_repo_baseurl: https://packagecloud.io/varnishcache/{{ varnish_packagecloud_repo }}/el/{{ ansible_distribution_major_version|int }}/$basearch + +# Only used on Debian / Ubuntu. +varnish_apt_repo: deb https://packagecloud.io/varnishcache/{{ varnish_packagecloud_repo }}/{{ ansible_distribution | lower }}/ {{ ansible_distribution_release }} main + +# Optionally define additional backends. +# varnish_backends: +# apache: +# host: 10.0.2.2 +# port: 80 +# nodejs: +# host: 10.0.2.3 +# port: 80 + +# Optionally define vhosts pointed at different backends. +# varnish_vhosts: +# example.com: +# backend: apache +# nodejs.example.com: +# backend: nodejs diff --git a/provisioning/roles/geerlingguy.varnish/handlers/main.yml b/provisioning/roles/geerlingguy.varnish/handlers/main.yml new file mode 100644 index 000000000..93882f0d0 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: reload systemd + systemd: daemon-reload=true + +- name: restart varnish + service: name=varnish state=restarted diff --git a/provisioning/roles/geerlingguy.varnish/meta/main.yml b/provisioning/roles/geerlingguy.varnish/meta/main.yml new file mode 100644 index 000000000..7a5525325 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/meta/main.yml @@ -0,0 +1,34 @@ +--- +dependencies: [] + +galaxy_info: + role_name: varnish + author: geerlingguy + description: Varnish for Linux. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.5 + platforms: + - name: EL + versions: + - 6 + - 7 + - 8 + - name: Ubuntu + versions: + - precise + - trusty + - xenial + - bionic + - name: Debian + versions: + - all + galaxy_tags: + - web + - varnish + - cache + - proxy + - reverse + - performance + - loadbalancer + - balancer diff --git a/provisioning/roles/geerlingguy.varnish/molecule/default/converge.yml b/provisioning/roles/geerlingguy.varnish/molecule/default/converge.yml new file mode 100644 index 000000000..78923beaf --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/molecule/default/converge.yml @@ -0,0 +1,25 @@ +--- +- name: Converge + hosts: all + become: true + + pre_tasks: + - import_tasks: playbook-setup.yml + + roles: + - role: geerlingguy.varnish + + post_tasks: + - name: Check the installed Varnish version. + command: varnishd -V + register: varnish_version_output + failed_when: "varnish_version not in varnish_version_output.stderr" + changed_when: false + tags: ['skip_ansible_lint'] + + - name: Verify Varnish is running on port 80. + shell: 'curl -sI localhost:80 | grep -q "Via: .* varnish"' + args: + warn: false + changed_when: false + tags: ['skip_ansible_lint'] diff --git a/provisioning/roles/geerlingguy.varnish/molecule/default/molecule.yml b/provisioning/roles/geerlingguy.varnish/molecule/default/molecule.yml new file mode 100644 index 000000000..2da47dd1f --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/molecule/default/molecule.yml @@ -0,0 +1,21 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: | + set -e + yamllint . + ansible-lint +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/provisioning/roles/geerlingguy.varnish/molecule/default/playbook-41.yml b/provisioning/roles/geerlingguy.varnish/molecule/default/playbook-41.yml new file mode 100644 index 000000000..0881e724b --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/molecule/default/playbook-41.yml @@ -0,0 +1,28 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + varnish_version: "4.1" + + pre_tasks: + - import_tasks: playbook-setup.yml + + roles: + - role: geerlingguy.varnish + + post_tasks: + - name: Check the installed Ansible version. + command: varnishd -V + register: varnish_version + failed_when: "'4.1' not in varnish_version.stderr" + changed_when: false + tags: ['skip_ansible_lint'] + + - name: Verify Varnish is running on port 80. + shell: 'curl -sI localhost:80 | grep -q "Via: .* varnish"' + args: + warn: false + changed_when: false + tags: ['skip_ansible_lint'] diff --git a/provisioning/roles/geerlingguy.varnish/molecule/default/playbook-setup.yml b/provisioning/roles/geerlingguy.varnish/molecule/default/playbook-setup.yml new file mode 100644 index 000000000..fd85ccf42 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/molecule/default/playbook-setup.yml @@ -0,0 +1,25 @@ +--- +- name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + +- name: Ensure build dependencies are installed (RedHat 7+). + yum: + name: + - logrotate + - systemd-sysv + state: present + when: + - ansible_os_family == 'RedHat' + - ansible_distribution_major_version >= '7' + +- name: Ensure build dependencies are installed (RedHat < 7). + yum: + name: logrotate + state: present + when: + - ansible_os_family == 'RedHat' + - ansible_distribution_major_version < '7' + +- name: Ensure curl is installed. + package: name=curl state=present diff --git a/provisioning/roles/geerlingguy.varnish/tasks/main.yml b/provisioning/roles/geerlingguy.varnish/tasks/main.yml new file mode 100644 index 000000000..92a7003b2 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/tasks/main.yml @@ -0,0 +1,97 @@ +--- +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Set the packagecloud repository name based on the version. + set_fact: + varnish_packagecloud_repo: "varnish{{ varnish_version|replace('.', '') }}" + +- include_tasks: setup-RedHat.yml + when: ansible_os_family == 'RedHat' + +- include_tasks: setup-Debian.yml + when: ansible_os_family == 'Debian' + +- name: Ensure Varnish config path exists. + file: + path: "{{ varnish_config_path }}" + state: directory + +- name: Copy Varnish configuration (sysvinit). + template: + src: varnish.j2 + dest: "{{ varnish_sysvinit_config_path }}/varnish" + owner: root + group: root + mode: 0644 + when: > + (ansible_os_family == 'RedHat' and ansible_distribution_major_version|int < 7) or + (ansible_os_family == 'Debian' and ansible_distribution_release != "xenial") + notify: restart varnish + +- name: Copy Debian Jessie/Xenial specific Varnish configs (systemd). + template: + src: varnish.service.j2 + dest: "{{ varnish_systemd_config_path }}/varnish.service" + owner: root + group: root + mode: 0644 + when: > + (ansible_os_family == 'RedHat' and ansible_distribution_major_version|int >= 7) or + (ansible_distribution == 'Debian' and ansible_distribution_version|int >= 8) or + (ansible_distribution == 'Ubuntu' and ansible_distribution_version.split(".")[0]|int >= 16) + notify: + - reload systemd + - restart varnish + +- name: Copy Varnish configuration (systemd). + template: + src: varnish.params.j2 + dest: "{{ varnish_config_path }}/varnish.params" + owner: root + group: root + mode: 0644 + when: > + (ansible_os_family == 'RedHat' and ansible_distribution_major_version|int >= 7) or + (ansible_os_family == 'Debian' and ansible_distribution_release == "xenial") + +- name: Copy Varnish default VCL. + template: + src: "{{ varnish_default_vcl_template_path }}" + dest: "{{ varnish_config_path }}/default.vcl" + owner: root + group: root + mode: 0644 + when: varnish_use_default_vcl + notify: restart varnish + +- name: Copy varnish secret. + template: + src: secret.j2 + dest: "{{ varnish_config_path }}/secret" + owner: root + group: root + mode: 0644 + notify: restart varnish + +- name: Ensure Varnish services are started and enabled on startup. + service: + name: "{{ item }}" + state: started + enabled: true + with_items: "{{ varnish_enabled_services | default([]) }}" + when: > + varnish_enabled_services and (ansible_os_family != 'Debian' or + (ansible_os_family != 'Debian' and ansible_distribution_release != "xenial")) + +# See: https://github.com/ansible/ansible/issues/22303 +- name: Ensure Varnish services are started and enabled on startup (Xenial specific) + service: + name: "{{ item }}" + state: started + enabled: true + use: "service" + with_items: "{{ varnish_enabled_services | default([]) }}" + when: + - varnish_enabled_services | length > 0 + - (ansible_os_family == 'Debian' and ansible_distribution_release == "xenial") diff --git a/provisioning/roles/geerlingguy.varnish/tasks/setup-Debian.yml b/provisioning/roles/geerlingguy.varnish/tasks/setup-Debian.yml new file mode 100644 index 000000000..795d1f035 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/tasks/setup-Debian.yml @@ -0,0 +1,28 @@ +--- +- name: Ensure dependencies are present. + apt: + name: + - apt-transport-https + - gnupg2 + state: present + +- name: Add packagecloud.io Varnish apt key. + apt_key: + url: https://packagecloud.io/varnishcache/{{ varnish_packagecloud_repo }}/gpgkey + state: present + +- name: Add packagecloud.io Varnish apt repository. + apt_repository: + repo: "{{ varnish_apt_repo }}" + state: present + +- name: Ensure Varnish is installed. + apt: + name: "{{ varnish_package_name }}" + state: present + +- name: Ensure old role-managed Varnish systemd unit file is removed. + file: + path: /etc/systemd/system/varnish.service + state: absent + when: varnish_systemd_config_path != '/etc/systemd/system' diff --git a/provisioning/roles/geerlingguy.varnish/tasks/setup-RedHat.yml b/provisioning/roles/geerlingguy.varnish/tasks/setup-RedHat.yml new file mode 100644 index 000000000..e5707c20e --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/tasks/setup-RedHat.yml @@ -0,0 +1,47 @@ +--- +- name: Ensure Varnish dependency is installed. + yum: + name: yum-utils + state: present + +- name: Ensure extra Varnish dependency on older RHEL versions is installed. + yum: + name: pygpgme + state: present + when: ansible_distribution_major_version | int < 8 + +- name: Add Varnish packagecloud.io yum repo. + yum_repository: + name: varnishcache_{{ varnish_packagecloud_repo }} + description: Varnish Cache packagecloud.io repository. + baseurl: "{{ varnish_yum_repo_baseurl }}" + repo_gpgcheck: false + gpgcheck: false + enabled: true + gpgkey: https://packagecloud.io/varnishcache/{{ varnish_packagecloud_repo }}/gpgkey + sslverify: 1 + sslcacert: /etc/pki/tls/certs/ca-bundle.crt + priority: "{{ varnish_packagecloud_repo_yum_repository_priority }}" + register: varnish_packagecloud_repo_addition + +- name: Refresh yum metadata cache if repo changed. + command: > + yum -q makecache -y --disablerepo='*' --enablerepo='varnishcache_{{ varnish_packagecloud_repo }}' + args: + warn: false + when: varnish_packagecloud_repo_addition.changed + tags: ['skip_ansible_lint'] + +- name: Disable varnish AppStream in RHEL 8. + command: dnf module disable -y varnish + args: + warn: false + when: + - varnish_packagecloud_repo_addition.changed + - ansible_distribution_major_version | int == 8 + tags: ['skip_ansible_lint'] + +- name: Ensure Varnish is installed. + yum: + name: "{{ varnish_package_name }}" + state: present diff --git a/provisioning/roles/geerlingguy.varnish/templates/default.vcl.j2 b/provisioning/roles/geerlingguy.varnish/templates/default.vcl.j2 new file mode 100644 index 000000000..d46723287 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/templates/default.vcl.j2 @@ -0,0 +1,38 @@ +{% if varnish_version is version('4.0', '>=') %} +vcl 4.0; +{% endif %} + +# This is a basic VCL configuration file for varnish. See the vcl(7) +# man page for details on VCL syntax and semantics. +# +# Default backend definition. Set this to point to your content +# server. +backend default { + .host = "{{ varnish_default_backend_host }}"; + .port = "{{ varnish_default_backend_port }}"; +} + +{% if varnish_backends is defined %} +# Other backend servers. +{% for backend, value in varnish_backends.items() | list %} +backend {{ backend }} { + .host = "{{ value.host }}"; + .port = "{{ value.port }}"; +} +{% endfor %} +{% endif %} + +sub vcl_recv { +{% if varnish_vhosts is defined %} + # Varnish vhosts. +{% for vhost, value in varnish_vhosts.items() | list if varnish_vhosts is defined %} + {% if loop.first %} + if (req.http.host == "{{ vhost }}" || req.http.host == "www.{{ vhost }}") { + {% else %} + elseif (req.http.host == "{{ vhost }}" || req.http.host == "www.{{ vhost }}") { + {% endif %} + set req.backend_hint = {{ value.backend }}; + } +{% endfor %} +{% endif %} +} diff --git a/provisioning/roles/geerlingguy.varnish/templates/secret.j2 b/provisioning/roles/geerlingguy.varnish/templates/secret.j2 new file mode 100644 index 000000000..8d7047d7c --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/templates/secret.j2 @@ -0,0 +1 @@ +{{ varnish_secret }} diff --git a/provisioning/roles/geerlingguy.varnish/templates/varnish.j2 b/provisioning/roles/geerlingguy.varnish/templates/varnish.j2 new file mode 100644 index 000000000..74269caff --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/templates/varnish.j2 @@ -0,0 +1,120 @@ +# Configuration file for varnish +# +# /etc/init.d/varnish expects the variable $DAEMON_OPTS to be set from this +# shell script fragment. +# + +# Start varnish (only applies to Debian-based hosts) +START=yes + +# Maximum number of open files (for ulimit -n) +NFILES={{ varnish_limit_nofile }} + +# Locked shared memory (for ulimit -l) +# Default log size is 82MB + header +MEMLOCK=82000 + +# Maximum number of threads (for ulimit -u) +NPROCS="unlimited" + +# Maximum size of corefile (for ulimit -c). Default in Fedora is 0 +# DAEMON_COREFILE_LIMIT="unlimited" + +# Set this to 1 to make init script reload try to switch vcl without restart. +# To make this work, you need to set the following variables +# explicit: VARNISH_VCL_CONF, VARNISH_ADMIN_LISTEN_ADDRESS, +# VARNISH_ADMIN_LISTEN_PORT, VARNISH_SECRET_FILE, or in short, +# use Alternative 3, Advanced configuration, below +RELOAD_VCL=1 + +{% if varnish_pidfile %} +# Varnish PID file +PIDFILE="{{ varnish_pidfile }}" +{% endif %} + +# This file contains 4 alternatives, please use only one. + +## Alternative 1, Minimal configuration, no VCL +# +# Listen on port 6081, administration on localhost:6082, and forward to +# content server on localhost:8080. Use a fixed-size cache file. +# +#DAEMON_OPTS="-a :6081 \ +# -T localhost:6082 \ +# -b localhost:8080 \ +# -u varnish -g varnish \ +# -s file,/var/lib/varnish/varnish_storage.bin,1G" + + +## Alternative 2, Configuration with VCL +# +# Listen on port 6081, administration on localhost:6082, and forward to +# one content server selected by the vcl file, based on the request. Use a +# fixed-size cache file. +# +#DAEMON_OPTS="-a :6081 \ +# -T localhost:6082 \ +# -f /etc/varnish/default.vcl \ +# -u varnish -g varnish \ +# -S /etc/varnish/secret \ +# -s file,/var/lib/varnish/varnish_storage.bin,1G" + + +## Alternative 3, Advanced configuration +# +# See varnishd(1) for more information. +# +# # Main configuration file. You probably want to change it :) +VARNISH_VCL_CONF={{ varnish_config_path }}/default.vcl +# +# # Default address and port to bind to +# # Blank address means all IPv4 and IPv6 interfaces, otherwise specify +# # a host name, an IPv4 dotted quad, or an IPv6 address in brackets. +VARNISH_LISTEN_ADDRESS={{ varnish_listen_address }} +VARNISH_LISTEN_PORT={{ varnish_listen_port }} +# +# # Telnet admin interface listen address and port +VARNISH_ADMIN_LISTEN_ADDRESS={{ varnish_admin_listen_host }} +VARNISH_ADMIN_LISTEN_PORT={{ varnish_admin_listen_port }} +# +# # Shared secret file for admin interface +VARNISH_SECRET_FILE={{ varnish_config_path }}/secret +# +# # The minimum number of worker threads to start +VARNISH_MIN_THREADS=50 +# +# # The Maximum number of worker threads to start +VARNISH_MAX_THREADS=1000 +# +# # Idle timeout for worker threads +VARNISH_THREAD_TIMEOUT=120 +# +# # Backend storage specification +VARNISH_STORAGE="{{ varnish_storage }}" +# +# # Default TTL used when the backend does not specify one +VARNISH_TTL=120 +# +# # DAEMON_OPTS is used by the init script. If you add or remove options, make +# # sure you update this section, too. +DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \ + -f ${VARNISH_VCL_CONF} \ + -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \ + -t ${VARNISH_TTL} \ + -p thread_pool_min=${VARNISH_MIN_THREADS} \ + -p thread_pool_max=${VARNISH_MAX_THREADS} \ + -p thread_pool_timeout=${VARNISH_THREAD_TIMEOUT} \ +{% if varnish_version is version('4.1', '<') %} + -u varnish -g varnish \ +{% endif %} +{% if varnishd_extra_options %} + {{ varnishd_extra_options }} +{% endif %} + -S ${VARNISH_SECRET_FILE} \ + -s ${VARNISH_STORAGE}" +# + + +## Alternative 4, Do It Yourself. See varnishd(1) for more information. +# +# DAEMON_OPTS="" diff --git a/provisioning/roles/geerlingguy.varnish/templates/varnish.params.j2 b/provisioning/roles/geerlingguy.varnish/templates/varnish.params.j2 new file mode 100644 index 000000000..a3567ccc5 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/templates/varnish.params.j2 @@ -0,0 +1,37 @@ +# Varnish environment configuration description. This was derived from +# the old style sysconfig/defaults settings + +# Set this to 1 to make systemd reload try to switch vcl without restart. +RELOAD_VCL=1 + +# Main configuration file. You probably want to change it. +VARNISH_VCL_CONF={{ varnish_config_path }}/default.vcl + +# Default address and port to bind to. Blank address means all IPv4 +# and IPv6 interfaces, otherwise specify a host name, an IPv4 dotted +# quad, or an IPv6 address in brackets. +VARNISH_LISTEN_ADDRESS={{ varnish_listen_address }} +VARNISH_LISTEN_PORT={{ varnish_listen_port }} + +# Admin interface listen address and port +VARNISH_ADMIN_LISTEN_ADDRESS={{ varnish_admin_listen_host }} +VARNISH_ADMIN_LISTEN_PORT={{ varnish_admin_listen_port }} + +# Shared secret file for admin interface +VARNISH_SECRET_FILE={{ varnish_config_path }}/secret + +# Backend storage specification, see Storage Types in the varnishd(5) +# man page for details. +VARNISH_STORAGE="{{ varnish_storage }}" + +# Default TTL used when the backend does not specify one +VARNISH_TTL=120 + +# User and group for the varnishd worker processes +VARNISH_USER=varnish +VARNISH_GROUP=varnish + +# Other options, see the man page varnishd(1) +{% if varnishd_extra_options %} +DAEMON_OPTS="{{ varnishd_extra_options }}" +{% endif %} diff --git a/provisioning/roles/geerlingguy.varnish/templates/varnish.service.j2 b/provisioning/roles/geerlingguy.varnish/templates/varnish.service.j2 new file mode 100644 index 000000000..7c3466e8a --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/templates/varnish.service.j2 @@ -0,0 +1,34 @@ +[Unit] +Description=Varnish Cache, a high-performance HTTP accelerator +After=network-online.target + +[Service] +Type=forking +KillMode=process + +{% if varnish_pidfile %} +PIDFile={{ varnish_pidfile }} +{% endif %} + +# Maximum number of open files (for ulimit -n) +LimitNOFILE={{ varnish_limit_nofile }} + +# Locked shared memory - should suffice to lock the shared memory log +# (varnishd -l argument) +# Default log size is 80MB vsl + 1M vsm + header -> 82MB +# unit is bytes +LimitMEMLOCK=85983232 + +# Enable this to avoid "fork failed" on reload. +TasksMax=infinity + +# Maximum size of the corefile. +LimitCORE=infinity + +ExecStart=/usr/sbin/varnishd -a {{ varnish_listen_address }}:{{ varnish_listen_port }} -T {{ varnish_admin_listen_host }}:{{ varnish_admin_listen_port }}{% if varnish_pidfile %} -P {{ varnish_pidfile }}{% endif %} -f {{ varnish_config_path }}/default.vcl -S {{ varnish_config_path }}/secret -s {{ varnish_storage }} {{ varnishd_extra_options }} +ExecReload=/usr/sbin/varnishreload + +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/provisioning/roles/geerlingguy.varnish/vars/Debian.yml b/provisioning/roles/geerlingguy.varnish/vars/Debian.yml new file mode 100644 index 000000000..f8ebf38a6 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/vars/Debian.yml @@ -0,0 +1,3 @@ +--- +varnish_sysvinit_config_path: /etc/default +varnish_systemd_config_path: /lib/systemd/system diff --git a/provisioning/roles/geerlingguy.varnish/vars/RedHat.yml b/provisioning/roles/geerlingguy.varnish/vars/RedHat.yml new file mode 100644 index 000000000..686dbc634 --- /dev/null +++ b/provisioning/roles/geerlingguy.varnish/vars/RedHat.yml @@ -0,0 +1,3 @@ +--- +varnish_sysvinit_config_path: /etc/sysconfig +varnish_systemd_config_path: /usr/lib/systemd/system diff --git a/provisioning/roles/thom8.php-upload-progress/.travis.yml b/provisioning/roles/thom8.php-upload-progress/.travis.yml new file mode 100644 index 000000000..67d45cf08 --- /dev/null +++ b/provisioning/roles/thom8.php-upload-progress/.travis.yml @@ -0,0 +1,58 @@ +--- +sudo: required + +env: + - distribution: centos + version: 7 + init: /usr/lib/systemd/systemd + run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" + SITE: source + - distribution: ubuntu + version: 14.04 + init: /sbin/init + run_opts: "" + SITE: source + - distribution: ubuntu + version: 12.04 + init: /sbin/init + run_opts: "" + SITE: source + +services: + - docker + +before_install: + # Pull container + - 'sudo docker pull ${distribution}:${version}' + # Customize container + - 'sudo docker build --rm=true --file=tests/Dockerfile.${distribution}-${version} --tag=${distribution}-${version}:ansible tests' + +script: + - container_id=$(mktemp) + # Run container in detached state + - 'sudo docker run --detach --volume="${PWD}":/etc/ansible/roles/role_under_test:ro ${run_opts} ${distribution}-${version}:ansible "${init}" > "${container_id}"' + + # Install dependencies. + - 'sudo docker exec "$(cat ${container_id})" ansible-galaxy install geerlingguy.php geerlingguy.repo-remi' + + # Ansible syntax check. + - 'sudo docker exec --tty "$(cat ${container_id})" env TERM=xterm ansible-playbook /etc/ansible/roles/role_under_test/tests/test-${SITE}.yml --syntax-check' + + # Test role. + - 'sudo docker exec --tty "$(cat ${container_id})" env TERM=xterm ansible-playbook /etc/ansible/roles/role_under_test/tests/test-${SITE}.yml' + + # Test role idempotence. + - > + sudo docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/role_under_test/tests/test-${SITE}.yml + | grep -q 'changed=0.*failed=0' + && (echo 'Idempotence test: pass' && exit 0) + || (echo 'Idempotence test: fail' && exit 1) + + # Run script to test if Upload progress is available and working. + - 'sudo docker exec --tty "$(cat ${container_id})" env TERM=xterm php /etc/ansible/roles/role_under_test/tests/uploadprogress-test.php' + + # Clean up + - 'sudo docker stop "$(cat ${container_id})"' + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/thom8.php-upload-progress/README.md b/provisioning/roles/thom8.php-upload-progress/README.md new file mode 100644 index 000000000..c369de5f5 --- /dev/null +++ b/provisioning/roles/thom8.php-upload-progress/README.md @@ -0,0 +1,39 @@ +# Ansible Role: Upload progress + +[![CircleCI](https://circleci.com/gh/beetboxvm/ansible-role-beetbox-upload-progress.svg?style=svg)](https://circleci.com/gh/beetboxvm/ansible-role-beetbox-upload-progress) + +Installs Upload progress PHP extension on Linux servers. + +## Requirements + +Prior to running this role, make sure the `php-devel` and `@Development Tools` (for RHEL/CentOS) or `php5-dev` + `build-essential` packages (for Debian/Ubuntu) are present on the system, as they are required for the build of Upload progress. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + workspace: /root + +Where Xdebug setup files will be downloaded and built. + + php_uploadprogress_module_path: /usr/lib/php5/modules + +The path where `uploadprogress.so` will be installed. + + php_uploadprogress_config_filename: 20-uploadprogress.ini + +The file name for PHP config. + +## Dependencies + + - geerlingguy.php + +## Example Playbook + + - hosts: webservers + roles: + - { role: beetboxvm.upload-progress } + +## License + +MIT diff --git a/provisioning/roles/thom8.php-upload-progress/defaults/main.yml b/provisioning/roles/thom8.php-upload-progress/defaults/main.yml new file mode 100644 index 000000000..8279f6ad8 --- /dev/null +++ b/provisioning/roles/thom8.php-upload-progress/defaults/main.yml @@ -0,0 +1,2 @@ +--- +workspace: /root diff --git a/provisioning/roles/thom8.php-upload-progress/meta/main.yml b/provisioning/roles/thom8.php-upload-progress/meta/main.yml new file mode 100644 index 000000000..885eb036e --- /dev/null +++ b/provisioning/roles/thom8.php-upload-progress/meta/main.yml @@ -0,0 +1,43 @@ +--- +dependencies: + - geerlingguy.php + +galaxy_info: + author: beetboxvm + description: PHP Upload progress for Linux. + license: "license (BSD, MIT)" + min_ansible_version: 2.0 + platforms: + - name: EL + versions: + - all + - name: GenericUNIX + versions: + - all + - name: Fedora + versions: + - all + - name: opensuse + versions: + - all + - name: GenericBSD + versions: + - all + - name: FreeBSD + versions: + - all + - name: Ubuntu + versions: + - all + - name: SLES + versions: + - all + - name: GenericLinux + versions: + - all + - name: Debian + versions: + - all + categories: + - development + - web diff --git a/provisioning/roles/thom8.php-upload-progress/tasks/main.yml b/provisioning/roles/thom8.php-upload-progress/tasks/main.yml new file mode 100644 index 000000000..dc7c6698a --- /dev/null +++ b/provisioning/roles/thom8.php-upload-progress/tasks/main.yml @@ -0,0 +1,56 @@ +--- +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define php_uploadprogress_module_path. + set_fact: + php_uploadprogress_module_path: "{{ __php_uploadprogress_module_path }}" + when: php_uploadprogress_module_path is not defined + +- name: Define php_uploadprogress_config_filename. + set_fact: + php_uploadprogress_config_filename: "{{ __php_uploadprogress_config_filename }}" + when: php_uploadprogress_config_filename is not defined + +- name: Download and untar uploadprogress. + unarchive: + src: "https://github.com/php/pecl-php-uploadprogress/archive/master.tar.gz" + dest: "{{ workspace }}" + copy: no + creates: "{{ workspace }}/pecl-php-uploadprogress-master" + +- name: Build uploadprogress. + shell: > + {{ item }} + chdir={{ workspace }}/pecl-php-uploadprogress-master + creates={{ workspace }}/pecl-php-uploadprogress-master/modules/uploadprogress.so + with_items: + - phpize + - ./configure + - make + notify: restart webserver + +- name: Ensure uploadprogress module path exists. + file: + path: "{{ php_uploadprogress_module_path }}" + state: directory + owner: root + group: root + mode: 0755 + +- name: Move uploadprogress module into place. + shell: > + cp {{ workspace }}/pecl-php-uploadprogress-master/modules/uploadprogress.so {{ php_uploadprogress_module_path }}/uploadprogress.so + creates={{ php_uploadprogress_module_path }}/uploadprogress.so + notify: restart webserver + +- name: Add php extension config for uploadprogress. + template: + src: uploadprogress.ini.j2 + dest: "{{ item }}/{{ php_uploadprogress_config_filename }}" + owner: root + group: root + force: yes + mode: 0644 + with_items: "{{ php_extension_conf_paths }}" + notify: restart webserver diff --git a/provisioning/roles/thom8.php-upload-progress/templates/uploadprogress.ini.j2 b/provisioning/roles/thom8.php-upload-progress/templates/uploadprogress.ini.j2 new file mode 100644 index 000000000..6bcbad366 --- /dev/null +++ b/provisioning/roles/thom8.php-upload-progress/templates/uploadprogress.ini.j2 @@ -0,0 +1,2 @@ +; activate and configurate for php uploadprogress module +extension={{ php_uploadprogress_module_path }}/uploadprogress.so diff --git a/provisioning/roles/thom8.php-upload-progress/tests/Dockerfile.centos-7 b/provisioning/roles/thom8.php-upload-progress/tests/Dockerfile.centos-7 new file mode 100644 index 000000000..804acdafe --- /dev/null +++ b/provisioning/roles/thom8.php-upload-progress/tests/Dockerfile.centos-7 @@ -0,0 +1,30 @@ +FROM centos:7 + +# Install systemd -- See https://hub.docker.com/_/centos/ +RUN yum -y swap -- remove fakesystemd -- install systemd systemd-libs +RUN yum -y update; yum clean all; \ +(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \ +rm -f /lib/systemd/system/multi-user.target.wants/*; \ +rm -f /etc/systemd/system/*.wants/*; \ +rm -f /lib/systemd/system/local-fs.target.wants/*; \ +rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ +rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ +rm -f /lib/systemd/system/basic.target.wants/*; \ +rm -f /lib/systemd/system/anaconda.target.wants/*; + +# Install Ansible +RUN yum -y install epel-release +RUN yum -y install git ansible sudo +RUN yum clean all + +RUN yum install -y unzip +RUN yum groupinstall -y "Development Tools" + +# Disable requiretty +RUN sed -i -e 's/^\(Defaults\s*requiretty\)/#--- \1/' /etc/sudoers + +# Install Ansible inventory file +RUN echo -e '[local]\nlocalhost ansible_connection=local' > /etc/ansible/hosts + +VOLUME ["/sys/fs/cgroup"] +CMD ["/usr/sbin/init"] \ No newline at end of file diff --git a/provisioning/roles/thom8.php-upload-progress/tests/Dockerfile.ubuntu-12.04 b/provisioning/roles/thom8.php-upload-progress/tests/Dockerfile.ubuntu-12.04 new file mode 100644 index 000000000..576e3bce8 --- /dev/null +++ b/provisioning/roles/thom8.php-upload-progress/tests/Dockerfile.ubuntu-12.04 @@ -0,0 +1,13 @@ +FROM ubuntu:12.04 +RUN apt-get update + +# Install Ansible +RUN apt-get install -y software-properties-common python-software-properties git +RUN apt-add-repository -y ppa:ansible/ansible +RUN apt-get update +RUN apt-get install -y ansible + +RUN apt-get install -y unzip + +# Install Ansible inventory file +RUN echo "[local]\nlocalhost ansible_connection=local" > /etc/ansible/hosts diff --git a/provisioning/roles/thom8.php-upload-progress/tests/Dockerfile.ubuntu-14.04 b/provisioning/roles/thom8.php-upload-progress/tests/Dockerfile.ubuntu-14.04 new file mode 100644 index 000000000..cb7a7bda4 --- /dev/null +++ b/provisioning/roles/thom8.php-upload-progress/tests/Dockerfile.ubuntu-14.04 @@ -0,0 +1,13 @@ +FROM ubuntu:14.04 +RUN apt-get update + +# Install Ansible +RUN apt-get install -y software-properties-common git +RUN apt-add-repository -y ppa:ansible/ansible +RUN apt-get update +RUN apt-get install -y ansible + +RUN apt-get install -y unzip + +# Install Ansible inventory file +RUN echo "[local]\nlocalhost ansible_connection=local" > /etc/ansible/hosts diff --git a/provisioning/roles/thom8.php-upload-progress/tests/inventory b/provisioning/roles/thom8.php-upload-progress/tests/inventory new file mode 100644 index 000000000..2fbb50c4a --- /dev/null +++ b/provisioning/roles/thom8.php-upload-progress/tests/inventory @@ -0,0 +1 @@ +localhost diff --git a/provisioning/roles/thom8.php-upload-progress/tests/test-source.yml b/provisioning/roles/thom8.php-upload-progress/tests/test-source.yml new file mode 100644 index 000000000..dee464c36 --- /dev/null +++ b/provisioning/roles/thom8.php-upload-progress/tests/test-source.yml @@ -0,0 +1,20 @@ +--- +- hosts: all + + vars: + php_enable_webserver: false + php_enablerepo: "remi,remi-php70" + + pre_tasks: + - name: Ensure build dependencies are installed (RedHat). + yum: name=which state=present + when: ansible_os_family == 'RedHat' + + - name: Add repository for PHP 7.0. + apt_repository: repo='ppa:ondrej/php' + when: ansible_os_family == 'Debian' + + roles: + - { role: geerlingguy.repo-remi, when: ansible_os_family == 'RedHat' } + - geerlingguy.php + - role_under_test diff --git a/provisioning/roles/thom8.php-upload-progress/tests/uploadprogress-test.php b/provisioning/roles/thom8.php-upload-progress/tests/uploadprogress-test.php new file mode 100644 index 000000000..a77ff8e5a --- /dev/null +++ b/provisioning/roles/thom8.php-upload-progress/tests/uploadprogress-test.php @@ -0,0 +1,20 @@ +<?php + +/** + * @file + * Test if Upload progress is available and working. + */ + +$success = FALSE; + +// Check uploadprogress extension is loaded. +if (extension_loaded('uploadprogress')) { + $success = TRUE; + print "Upload progress working properly.\r\n"; + exit(0); +} + +if (!$success) { + print "Upload progress not working properly.\r\n"; + exit(1); +} diff --git a/provisioning/roles/thom8.php-upload-progress/vars/Debian.yml b/provisioning/roles/thom8.php-upload-progress/vars/Debian.yml new file mode 100644 index 000000000..9ff5ac245 --- /dev/null +++ b/provisioning/roles/thom8.php-upload-progress/vars/Debian.yml @@ -0,0 +1,3 @@ +--- +__php_uploadprogress_module_path: /usr/lib/php5/modules +__php_uploadprogress_config_filename: 20-uploadprogress.ini \ No newline at end of file diff --git a/provisioning/roles/thom8.php-upload-progress/vars/RedHat.yml b/provisioning/roles/thom8.php-upload-progress/vars/RedHat.yml new file mode 100644 index 000000000..3bd391bed --- /dev/null +++ b/provisioning/roles/thom8.php-upload-progress/vars/RedHat.yml @@ -0,0 +1,3 @@ +--- +__php_uploadprogress_module_path: /usr/lib64/php/modules +__php_uploadprogress_config_filename: uploadprogress.ini diff --git a/provisioning/roles/weareinteractive.newrelic/.ansible-lint b/provisioning/roles/weareinteractive.newrelic/.ansible-lint new file mode 100644 index 000000000..cf73c0ec5 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/.ansible-lint @@ -0,0 +1,2 @@ +exclude_paths: + - ./meta/readme.yml diff --git a/provisioning/roles/weareinteractive.newrelic/.clog.toml b/provisioning/roles/weareinteractive.newrelic/.clog.toml new file mode 100644 index 000000000..5e4317e78 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/.clog.toml @@ -0,0 +1,4 @@ +[clog] +changelog = "CHANGELOG.md" +repository = "https://github.com/weareinteractive/ansible-newrelic" +from-latest-tag = true diff --git a/provisioning/roles/weareinteractive.newrelic/.editorconfig b/provisioning/roles/weareinteractive.newrelic/.editorconfig new file mode 100644 index 000000000..737f59183 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/.editorconfig @@ -0,0 +1,19 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + +[*] +# Change these settings to your own preference +indent_size = 2 +indent_style = space + +# We recommend you to keep these unchanged +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[Makefile] +indent_style = tab diff --git a/provisioning/roles/weareinteractive.newrelic/.gitignore b/provisioning/roles/weareinteractive.newrelic/.gitignore new file mode 100644 index 000000000..61f047aff --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/.gitignore @@ -0,0 +1,6 @@ +*.log +*.retry +.DS_Store +.vagrant +.vscode +.idea diff --git a/provisioning/roles/weareinteractive.newrelic/.travis.yml b/provisioning/roles/weareinteractive.newrelic/.travis.yml new file mode 100644 index 000000000..6aa123b45 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/.travis.yml @@ -0,0 +1,57 @@ +--- +sudo: required +language: python +services: + - docker +env: + global: + - role: weareinteractive.newrelic + matrix: + - distribution: Ubuntu + distribution_version: "18.04" + init: /lib/systemd/systemd + run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" + - distribution: Ubuntu + distribution_version: "16.04" + init: /sbin/init + run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" + - distribution: Debian + distribution_version: "9" + init: /lib/systemd/systemd + run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" + - distribution: Debian + distribution_version: "8" + init: /lib/systemd/systemd + run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" + - distribution: EL + distribution_version: "7" + init: /usr/lib/systemd/systemd + run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" + +before_install: + - sudo apt-get update + - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce + - docker pull ansiblecheck/ansiblecheck:"${distribution,,}"-"${distribution_version}" + +script: + - container_id=$(mktemp) + # Start The Built Container In The Background + - 'docker run --detach --volume="${PWD}":/etc/ansible/roles/${role}:ro ${run_opts} ansiblecheck/ansiblecheck:"${distribution,,}"-"${distribution_version}" "${init}" > "${container_id}"' + + # Ansible syntax check. + - 'docker exec --tty "$(cat ${container_id})" env TERM=xterm ansible-playbook /etc/ansible/roles/${role}/tests/main.yml --syntax-check' + + # Test role. + - 'docker exec "$(cat ${container_id})" env ANSIBLE_FORCE_COLOR=1 ansible-playbook /etc/ansible/roles/${role}/tests/main.yml' + + # Test Idempotence + - idempotence=$(mktemp) + - docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/${role}/tests/main.yml | tee -a ${idempotence} + - > + tail ${idempotence} + | grep -q 'failed=0' + && (echo 'Idempotence test: pass' && exit 0) + || (echo 'Idempotence test: fail' && exit 1) + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/provisioning/roles/weareinteractive.newrelic/CHANGELOG.md b/provisioning/roles/weareinteractive.newrelic/CHANGELOG.md new file mode 100644 index 000000000..6c4f4ae5b --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/CHANGELOG.md @@ -0,0 +1,133 @@ +<a name="1.8.0"></a> +## 1.8.0 (2019-12-08) + + +#### Features + +* update role name ([5979af34](https://github.com/weareinteractive/ansible-newrelic/commit/5979af343fe2905660a3829705894ba05424cdca)) + +#### Bug Fixes + +* add gpg dependency and loop update syntax ([bd11a60b](https://github.com/weareinteractive/ansible-newrelic/commit/bd11a60b10be3bb945f87edc1a9d34d5773d5fa9)) + + + +<a name="1.7.2"></a> +### 1.7.2 (2018-04-25) + + +#### Features + +* update apt on dependency installation ([af5a4208](https://github.com/weareinteractive/ansible-newrelic/commit/af5a42085a23f6aa90d73d597a6f772e2eed4559)) +* update depricated include module ([b00a529f](https://github.com/weareinteractive/ansible-newrelic/commit/b00a529fb329868218626e40760d6b801d6a13dc)) + + + +<a name="1.7.1"></a> +### 1.7.1 (2017-11-07) + + + + +<a name="1.7.0"></a> +## 1.7.0 (2017-11-04) + + +#### Features + +* remove default hostname ([8808db40](https://github.com/weareinteractive/ansible-newrelic/commit/8808db40d26ce00e5b9a2390ad1fde7fc5359ca5)) + + + +<a name="1.6.0"></a> +## 1.6.0 (2016-11-11) + + +#### Features + +* add `cgroup_style` option to config ([fd806272](https://github.com/weareinteractive/ansible-newrelic/commit/fd80627235dca4c6dad2b4edaa13e3d5ab64174d)) + + + +<a name="1.5.0"></a> +## 1.5.0 (2016-11-10) + + +#### Features + +* add proxy options ([d8c80eaa](https://github.com/weareinteractive/ansible-newrelic/commit/d8c80eaac222078c918be6ff80ce94f4d444510b)) + + + +<a name="1.4.3"></a> +### 1.4.3 (2016-11-03) + + +#### Bug Fixes + +* fix readme badge url ([a143bf3e](https://github.com/weareinteractive/ansible-newrelic/commit/a143bf3ee48ee07fa3657186763d857d00083b56)) + + + +<a name="1.4.2"></a> +### 1.4.2 (2016-09-30) + + + + +<a name="1.4.1"></a> +### 1.4.1 (2016-09-20) + + +#### Bug Fixes + +* remove duplicate newrelic_license_key ([036d2777](https://github.com/weareinteractive/ansible-newrelic/commit/036d27779b7db47b9fb06b9a983d759d2ad196bf)) + + + +<a name="1.4.0"></a> +## 1.4.0 (2016-08-05) + + +#### Features + +* add label settings ([169d3867](https://github.com/weareinteractive/ansible-newrelic/commit/169d386710aba0d7d1397cb68ef7f8426d1fac80)) + + + +<a name="1.3.0"></a> +## 1.3.0 (2016-07-04) + + + + +<a name="1.2.1"></a> +### 1.2.1 (2016-04-10) + + +#### Bug Fixes + +* default groups breaks install when docker monitoring is enabled ([3e507b30](https://github.com/weareinteractive/ansible-newrelic/commit/3e507b3080fa8040a3659577f1bdc25c3d97508a)) + + + +<a name="1.2.0"></a> +## 1.2.0 (2016-02-13) + + +#### Breaking Changes + +* add configurable `newrelic_group` and `newrelic_groups` ([b06cf9f4](https://github.com/weareinteractive/ansible-newrelic/commit/b06cf9f4bbaeb6edd3bae8b600d351a27dbd28d5), breaks [#](https://github.com/weareinteractive/ansible-newrelic/issues/)) + +#### Bug Fixes + +* make docker container monitoring work ([89986c76](https://github.com/weareinteractive/ansible-newrelic/commit/89986c7649e3bc3d9f08d1d2027596b9e089b6c5)) + +#### Features + +* add configurable `newrelic_group` and `newrelic_groups` ([b06cf9f4](https://github.com/weareinteractive/ansible-newrelic/commit/b06cf9f4bbaeb6edd3bae8b600d351a27dbd28d5), breaks [#](https://github.com/weareinteractive/ansible-newrelic/issues/)) +* use ansible-role docgen for README generation ([23b5e65f](https://github.com/weareinteractive/ansible-newrelic/commit/23b5e65fb9fe82851ec450f99d80b7db42663e58)) +* add CHANGELOG ([86830e8f](https://github.com/weareinteractive/ansible-newrelic/commit/86830e8f5d84195c2b3c11a8d3b1235a74cb136f)) + + + diff --git a/provisioning/roles/weareinteractive.newrelic/LICENSE b/provisioning/roles/weareinteractive.newrelic/LICENSE new file mode 100644 index 000000000..ebdf0f1dc --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) We Are Interactive + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/provisioning/roles/weareinteractive.newrelic/Makefile b/provisioning/roles/weareinteractive.newrelic/Makefile new file mode 100644 index 000000000..80d9e5fb8 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/Makefile @@ -0,0 +1,35 @@ +PWD=$(shell pwd) +ROLE_NAME=weareinteractive.newrelic +ROLE_PATH=/etc/ansible/roles/$(ROLE_NAME) +TEST_VERSION=ansible --version +TEST_SYNTAX=ansible-playbook -v -i 'localhost,' -c local $(ROLE_PATH)/tests/main.yml --syntax-check +TEST_PLAYBOOK=ansible-playbook -vvvv -i 'localhost,' -c local $(ROLE_PATH)/tests/main.yml +TEST_IDEMPOTENT=$(TEST_PLAYBOOK) | grep -q 'changed=0.*failed=0' && (echo 'Idempotence test: pass' && exit 0) || (echo 'Idempotence test: fail' && exit 1) +TEST_CMD=$(TEST_VERSION); $(TEST_SYNTAX); $(TEST_PLAYBOOK); $(TEST_IDEMPOTENT) + +docs: + ansible-role docgen + +lint: + ansible-lint . + +ubuntu18.04: dist=ubuntu-18.04 +ubuntu18.04: .run + +ubuntu16.04: dist=ubuntu-16.04 +ubuntu16.04: .run + +debian9: dist=debian-9 +debian9: .run + +debian8: dist=debian-8 +debian8: .run + +centos7: dist=el-7 +centos7: .run + +.run: + @echo "RUN:" + @echo " docker run -it --rm -v $(PWD):$(ROLE_PATH) ansiblecheck/ansiblecheck:$(dist) /bin/bash" + @echo " $(TEST_CMD)" + @docker run -it --rm -v $(PWD):$(ROLE_PATH) ansiblecheck/ansiblecheck:$(dist) /bin/bash -c "$(TEST_CMD)" diff --git a/provisioning/roles/weareinteractive.newrelic/README.md b/provisioning/roles/weareinteractive.newrelic/README.md new file mode 100644 index 000000000..e1258de51 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/README.md @@ -0,0 +1,141 @@ +# Ansible weareinteractive.newrelic role + +[![Build Status](https://img.shields.io/travis/weareinteractive/ansible-newrelic.svg)](https://travis-ci.org/weareinteractive/ansible-newrelic) +[![Galaxy](http://img.shields.io/badge/galaxy-weareinteractive.newrelic-blue.svg)](https://galaxy.ansible.com/weareinteractive/newrelic/) +[![GitHub Tags](https://img.shields.io/github/tag/weareinteractive/ansible-newrelic.svg)](https://github.com/weareinteractive/ansible-newrelic) +[![GitHub Stars](https://img.shields.io/github/stars/weareinteractive/ansible-newrelic.svg)](https://github.com/weareinteractive/ansible-newrelic) + +> `weareinteractive.newrelic` is an [Ansible](http://www.ansible.com) role which: +> +> * installs newrelic +> * configures newrelic +> * configures service + +**Note:** + +> Since Ansible Galaxy supports [organization](https://www.ansible.com/blog/ansible-galaxy-2-release) now, this role has moved from `franklinkim.newrelic` to `weareinteractive.newrelic`! + +## Installation + +Using `ansible-galaxy`: + +```shell +$ ansible-galaxy install weareinteractive.newrelic +``` + +Using `requirements.yml`: + +```yaml +- src: weareinteractive.newrelic +``` + +Using `git`: + +```shell +$ git clone https://github.com/weareinteractive/ansible-newrelic.git weareinteractive.newrelic +``` + +## Dependencies + +* Ansible >= 2.4 + +## Variables + +Here is a list of all the default variables for this role, which are also available in `defaults/main.yml`. + +```yaml +--- +# +# newrelic_license_key: yourkey + +# User name +newrelic_user: newrelic +# User group +newrelic_group: newrelic +# User groups to append to user +newrelic_groups: [] +# Name of the file where the server monitor will store its log messages. +newrelic_logfile: /var/log/newrelic/nrsysmond.log +# Level of detail you want in the log file +newrelic_loglevel: info +# Set to true to disable NFS client statistics gathering. +newrelic_disable_nfs: yes +# Set to true to disable Docker container statistics gathering. +newrelic_disable_docker: yes +# start on boot +newrelic_service_enabled: yes +# current state: started, stopped +newrelic_service_state: started +# use default hostname, set a value to override the default hostname +newrelic_override_hostname: +# A series of label_type/label_value pairings: label_type:label_value +newrelic_labels: +# proxy server to use (i.e. proxy-host:8080) +newrelic_proxy: +# Option to fix Docker memory (see: https://discuss.newrelic.com/t/wrong-path-to-cpu-and-memoy-data/36177) +newrelic_cgroup_style: + +``` + +## Handlers + +These are the handlers that are defined in `handlers/main.yml`. + +```yaml +--- + +- name: restart newrelic + service: + name: newrelic-sysmond + state: restarted + when: newrelic_service_state != 'stopped' + +``` + + +## Usage + +This is an example playbook: + +```yaml +--- + +- hosts: all + become: yes + roles: + - weareinteractive.newrelic + vars: + newrelic_license_key: ab2fa361cd4d0d373833cad619d7bcc424d27c16 + # not starting service in docker env + newrelic_service_state: stopped + newrelic_service_enabled: false + +``` + + +## Testing + +```shell +$ git clone https://github.com/weareinteractive/ansible-newrelic.git +$ cd ansible-newrelic +$ make test +``` + +## Contributing +In lieu of a formal style guide, take care to maintain the existing coding style. Add unit tests and examples for any new or changed functionality. + +1. Fork it +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Add some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create new Pull Request + +*Note: To update the `README.md` file please install and run `ansible-role`:* + +```shell +$ gem install ansible-role +$ ansible-role docgen +``` + +## License +Copyright (c) We Are Interactive under the MIT license. diff --git a/provisioning/roles/weareinteractive.newrelic/defaults/main.yml b/provisioning/roles/weareinteractive.newrelic/defaults/main.yml new file mode 100644 index 000000000..2df4878aa --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/defaults/main.yml @@ -0,0 +1,30 @@ +--- +# +# newrelic_license_key: yourkey + +# User name +newrelic_user: newrelic +# User group +newrelic_group: newrelic +# User groups to append to user +newrelic_groups: [] +# Name of the file where the server monitor will store its log messages. +newrelic_logfile: /var/log/newrelic/nrsysmond.log +# Level of detail you want in the log file +newrelic_loglevel: info +# Set to true to disable NFS client statistics gathering. +newrelic_disable_nfs: yes +# Set to true to disable Docker container statistics gathering. +newrelic_disable_docker: yes +# start on boot +newrelic_service_enabled: yes +# current state: started, stopped +newrelic_service_state: started +# use default hostname, set a value to override the default hostname +newrelic_override_hostname: +# A series of label_type/label_value pairings: label_type:label_value +newrelic_labels: +# proxy server to use (i.e. proxy-host:8080) +newrelic_proxy: +# Option to fix Docker memory (see: https://discuss.newrelic.com/t/wrong-path-to-cpu-and-memoy-data/36177) +newrelic_cgroup_style: diff --git a/provisioning/roles/weareinteractive.newrelic/handlers/main.yml b/provisioning/roles/weareinteractive.newrelic/handlers/main.yml new file mode 100644 index 000000000..2ea02f7e8 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/handlers/main.yml @@ -0,0 +1,7 @@ +--- + +- name: restart newrelic + service: + name: newrelic-sysmond + state: restarted + when: newrelic_service_state != 'stopped' diff --git a/provisioning/roles/weareinteractive.newrelic/meta/main.yml b/provisioning/roles/weareinteractive.newrelic/meta/main.yml new file mode 100644 index 000000000..91c86806c --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/meta/main.yml @@ -0,0 +1,142 @@ +--- +galaxy_info: + author: franklin + company: We Are Interactive + description: Installs and configure newrelic + min_ansible_version: 2.4 + license: MIT + # Optionally specify the branch Galaxy will use when accessing the GitHub + # repo for this role. During role install, if no tags are available, + # Galaxy will use this branch. During import Galaxy will access files on + # this branch. If travis integration is cofigured, only notification for this + # branch will be accepted. Otherwise, in all cases, the repo's default branch + # (usually master) will be used. + github_branch: master + # + # Below are all platforms currently available. Just uncomment + # the ones that apply to your role. If you don't see your + # platform on this list, let us know and we'll get it added! + # + platforms: + - name: EL + versions: + - all + # - 5 + # - 6 + # - 7 + #- name: GenericUNIX + # versions: + # - all + # - any + #- name: Solaris + # versions: + # - all + # - 10 + # - 11.0 + # - 11.1 + # - 11.2 + # - 11.3 + #- name: Fedora + # versions: + # - all + # - 16 + # - 17 + # - 18 + # - 19 + # - 20 + # - 21 + # - 22 + # - 23 + #- name: Windows + # versions: + # - all + # - 2012R2 + #- name: SmartOS + # versions: + # - all + # - any + #- name: opensuse + # versions: + # - all + # - 12.1 + # - 12.2 + # - 12.3 + # - 13.1 + # - 13.2 + #- name: Amazon + # versions: + # - all + # - 2013.03 + # - 2013.09 + #- name: GenericBSD + # versions: + # - all + # - any + #- name: FreeBSD + # versions: + # - all + # - 10.0 + # - 10.1 + # - 10.2 + # - 8.0 + # - 8.1 + # - 8.2 + # - 8.3 + # - 8.4 + # - 9.0 + # - 9.1 + # - 9.1 + # - 9.2 + # - 9.3 + - name: Ubuntu + versions: + - all + # - lucid + # - maverick + # - natty + # - oneiric + # - precise + # - quantal + # - raring + # - saucy + # - trusty + # - utopic + # - vivid + # - wily + #- name: SLES + # versions: + # - all + # - 10SP3 + # - 10SP4 + # - 11 + # - 11SP1 + # - 11SP2 + # - 11SP3 + #- name: GenericLinux + # versions: + # - all + # - any + - name: Debian + versions: + - all + # - etch + # - jessie + # - lenny + # - squeeze + # - wheezy + # + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. + galaxy_tags: + - monitoring + - newrelic +# List your role dependencies here, one per line. Only +# dependencies available via galaxy should be listed here. +# Be sure to remove the '[]' above if you add dependencies +# to this list. +dependencies: [] diff --git a/provisioning/roles/weareinteractive.newrelic/meta/readme.yml b/provisioning/roles/weareinteractive.newrelic/meta/readme.yml new file mode 100644 index 000000000..74b51f080 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/meta/readme.yml @@ -0,0 +1,18 @@ +--- + +galaxy_name: weareinteractive.newrelic +github_user: weareinteractive +github_name: ansible-newrelic +badges: | + [![Build Status](https://img.shields.io/travis/weareinteractive/ansible-newrelic.svg)](https://travis-ci.org/weareinteractive/ansible-newrelic) + [![Galaxy](http://img.shields.io/badge/galaxy-weareinteractive.newrelic-blue.svg)](https://galaxy.ansible.com/weareinteractive/newrelic/) + [![GitHub Tags](https://img.shields.io/github/tag/weareinteractive/ansible-newrelic.svg)](https://github.com/weareinteractive/ansible-newrelic) + [![GitHub Stars](https://img.shields.io/github/stars/weareinteractive/ansible-newrelic.svg)](https://github.com/weareinteractive/ansible-newrelic) +description: | + > * installs newrelic + > * configures newrelic + > * configures service + + **Note:** + + > Since Ansible Galaxy supports [organization](https://www.ansible.com/blog/ansible-galaxy-2-release) now, this role has moved from `franklinkim.newrelic` to `weareinteractive.newrelic`! diff --git a/provisioning/roles/weareinteractive.newrelic/tasks/config.yml b/provisioning/roles/weareinteractive.newrelic/tasks/config.yml new file mode 100644 index 000000000..56b78b8f5 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/tasks/config.yml @@ -0,0 +1,19 @@ +--- + +- name: Configuring module + template: + src: "{{ item }}.j2" + dest: "/{{ item }}" + owner: "{{ newrelic_user }}" + group: "{{ newrelic_group }}" + mode: "0640" + notify: restart newrelic + with_items: + - "etc/newrelic/nrsysmond.cfg" + +- name: Configuring user groups + user: + name: "{{ newrelic_user }}" + groups: "{{ newrelic_groups|join(',') }}" + append: yes + when: not newrelic_disable_docker diff --git a/provisioning/roles/weareinteractive.newrelic/tasks/install.yml b/provisioning/roles/weareinteractive.newrelic/tasks/install.yml new file mode 100644 index 000000000..46b9ba804 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/tasks/install.yml @@ -0,0 +1,7 @@ +--- + +- import_tasks: install_debian.yml + when: ansible_os_family == 'Debian' + +- import_tasks: install_redhat.yml + when: ansible_os_family == 'RedHat' diff --git a/provisioning/roles/weareinteractive.newrelic/tasks/install_debian.yml b/provisioning/roles/weareinteractive.newrelic/tasks/install_debian.yml new file mode 100644 index 000000000..e65ac6cef --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/tasks/install_debian.yml @@ -0,0 +1,24 @@ +--- + +- name: Installing dependencies + apt: + pkg: + - apt-transport-https + - ca-certificates + - gnupg2 + state: present + +- name: Adding APT key + apt_key: + id: 548C16BF + url: https://download.newrelic.com/548C16BF.gpg + +- name: Add APT repository + apt_repository: + repo: "deb http://apt.newrelic.com/debian/ newrelic non-free" + update_cache: yes + +- name: Installing packages + apt: + pkg: newrelic-sysmond + state: present diff --git a/provisioning/roles/weareinteractive.newrelic/tasks/install_redhat.yml b/provisioning/roles/weareinteractive.newrelic/tasks/install_redhat.yml new file mode 100644 index 000000000..c9e97fa37 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/tasks/install_redhat.yml @@ -0,0 +1,11 @@ +--- + +- name: Installing dependencies + yum: + name: http://download.newrelic.com/pub/newrelic/el5/i386/newrelic-repo-5-3.noarch.rpm + state: present + +- name: Installing packages + yum: + name: newrelic-sysmond + state: present diff --git a/provisioning/roles/weareinteractive.newrelic/tasks/main.yml b/provisioning/roles/weareinteractive.newrelic/tasks/main.yml new file mode 100644 index 000000000..11c5ba454 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/tasks/main.yml @@ -0,0 +1,28 @@ +--- + +- name: Checking for key + fail: + msg: "newrelic_license_key has not been defined" + when: newrelic_license_key is not defined + +- import_tasks: install.yml + tags: + - monitoring + - newrelic + - install + - newrelic-install + +- import_tasks: config.yml + tags: + - monitoring + - newrelic + - config + - newrelic-config + +- import_tasks: service.yml + tags: + - monitoring + - newrelic + - service + - newrelic-service + diff --git a/provisioning/roles/weareinteractive.newrelic/tasks/service.yml b/provisioning/roles/weareinteractive.newrelic/tasks/service.yml new file mode 100644 index 000000000..c5314c313 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/tasks/service.yml @@ -0,0 +1,7 @@ +--- + +- name: Configuring service + service: + name: newrelic-sysmond + state: "{{ newrelic_service_state }}" + enabled: "{{ newrelic_service_enabled }}" diff --git a/provisioning/roles/weareinteractive.newrelic/templates/etc/newrelic/nrsysmond.cfg.j2 b/provisioning/roles/weareinteractive.newrelic/templates/etc/newrelic/nrsysmond.cfg.j2 new file mode 100644 index 000000000..a7c188522 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/templates/etc/newrelic/nrsysmond.cfg.j2 @@ -0,0 +1,235 @@ +# {{ ansible_managed }} +# +# New Relic Server Monitor configuration file. +# +# Lines that begin with a # are comment lines and are ignored by the server +# monitor. For those options that have command line equivalents, if the +# option is specified on the command line it will over-ride any value set +# in this file. +# + +# +# Option : cgroup_style +# Value : 0 +# Note : Setting `cgroup_style=0` fixes issue with docker memory reporting +# Workaround for an issue where new relic cannot get container memory stats. +# http://stackoverflow.com/questions/36788770/newrelic-does-not-display-cpu-memory-usage-for-dockers-container +# Default: none +# +#cgroup_style= +{% if newrelic_cgroup_style|default(None) != None %} +cgroup_style={{ newrelic_cgroup_style }} +{% endif %} + +# +# Option : license_key +# Value : 40-character hexadecimal string provided by New Relic. This is +# required in order for the server monitor to start. +# Default: none +# +license_key={{ newrelic_license_key }} + +# +# Option : loglevel +# Value : Level of detail you want in the log file (as defined by the logfile +# setting below. Valid values are (in increasing levels of verbosity): +# error - show errors only +# warning - show errors and warnings +# info - show minimal additional information messages +# verbose - show more detailed information messages +# debug - show debug messages +# verbosedebug - show very detailed debug messages +# Default: error +# Note : Can also be set with the -d command line option. +# +loglevel={{ newrelic_loglevel }} + +# +# Option : logfile +# Value : Name of the file where the server monitor will store it's log +# messages. The amount of detail stored in this file is controlled +# by the loglevel option (above). +# Default: none. However it is highly recommended you set a value for this. +# Note : Can also be set with the -l command line option. +# +logfile={{ newrelic_logfile }} + +# +# Option : proxy +# Value : The name and optional login credentials of the proxy server to use +# for all communication with the New Relic collector. In its simplest +# form this setting is just a hostname[:port] setting. The default +# port if none is specified is 1080. If your proxy requires a user +# name, use the syntax user@host[:port]. If it also requires a +# password use the format user:password@host[:port]. For example: +# fred:secret@proxy.mydomain.com:8181 +# Default: none (use a direct connection) +# +#proxy= +{% if newrelic_proxy|default(None) != None %} +proxy={{ newrelic_proxy }} +{% endif %} + +# +# Setting: ssl +# Type : boolean +# Purpose: If you prefer the daemon to use the secure HTTP (https) protocol +# when communicating with the New Relic collector servers, set this +# to true. +# Default: true (as of version 1.4) +# +#ssl=true + +# +# Setting: docker_connection +# Type : string +# Purpose: Determine how to communicate with the Docker API on the local host. +# Valid values are: +# +# uds:///path/to/socket +# unix:///path/to/socket +# /path/to/socket +# These three forms are all equivalent and are used to point to the +# UNIX-domain socket (UDS). The socket path must be absolute and the +# socket must be writeable. +# +# tcp://localhost:port +# http://localhost:port +# Use an unencrypted connection to the local host on the specified +# port. If the :port portion is missing it defaults to 2376. The +# host name MUST be localhost or 127.0.0.1. No other host name is +# valid. +# +# https://localhost:port +# Use an encrypted connection to the local host om the specified +# port. If the :port portion is missing it defaults to 2376. The +# host name MUST be localhost or 127.0.0.1. No other host name is +# valid. In order to use TLS authentication you may need to set +# the various key and certificate options below. +# +# If no value is set, attempt to use the default (/var/run/docker.sock) +# if it exists and is writable. If that fails, attempt to use the value +# of the environment variable DOCKER_HOST. +# +# You may need to add the user that you run LSM as to the docker +# group. Please consult the Docker web site for details and security +# implications. +# Default: empty +#docker_connection= + +# +# Setting: docker_cert_path +# Type : string +# Purpose: Set the default location to look for the certificate, key and CA +# certificate for using TLS. If no value is set and the directory +# $HOME/.docker exists, that is used as the default value. LSM will +# look in this directory for the cert.pem, key.pem and cacert.pem +# files, and use them if present. If set, the environment variable +# $DOCKER_CERT_PATH will be used as the default value if no value +# is explicitly set here. +# Default: empty +#docker_cert_path= + +# +# Setting: docker_cert +# docker_key +# docker_cacert +# Type : string +# Purpose: Set the name of the certificate, key and CA certificate files to +# use for TLS. If these are not absolute paths they are searched for +# in the directory determined by docker_cert_path above. +# Default: empty +#docker_cert= +#docker_key= +#docker_cacert= + +# +# Setting: ssl_ca_bundle +# Type : string +# Purpose: Sets the location of a file containing CA certificates in PEM +# format. When set, the certificates in this file will be used +# to authenticate the New Relic collector servers. If ssl_ca_path +# is also set (see below), the certificates in this file will be +# searched first, followed by the certificates contained in the +# ssl_ca_path directory. This setting has no effect when ssl +# is set to false. +# Default: none +# Note : Can also be set with the -b command line option. +# +#ssl_ca_bundle= + +# +# Setting: ssl_ca_path +# Type : string +# Purpose: Sets the location of a directory containing trusted CA certificates +# in PEM format. When set, the certificates in this directory will be +# used to authenticate the New Relic collector servers. If +# ssl_ca_bundle is also set (see above), it will be searched first +# followed by the certificates contained in ssl_ca_path. This +# setting has no effect when ssl is set to false. +# Default: none +# Note : Can also be set with the -S command line option. +# +#ssl_ca_path= + +# +# Option : pidfile +# Value : Name of a file where the server monitoring daemon will store it's +# process ID (PID). This is used by the startup and shutdown script +# to determine if the monitor is already running, and to start it up +# or shut it down. +# Default: /tmp/nrsysmond.pid +# Note : Can also be set with the -p command line option. +# +#pidfile=/var/run/newrelic/nrsysmond.pid + +# Option : collector_host +# Value : The name of the New Relic collector to connect to. This should only +# ever be changed on advise from a New Relic support staff member. +# The format is host[:port]. Using a port number of 0 means the default +# port, which is 80 (if not using the ssl option - see below) or 443 +# if SSL is enabled. If the port is omitted the default value is used. +# Default: collector.newrelic.com +# +#collector_host=collector.newrelic.com + +# +# Option : labels +# Value : A series of label_type/label_value pairings +# Each item in the pair is separated by a colon +# Each pair is separated by a semicolon +# e.g. +# labels = Environment:Production;DataCenter:EastUS; +# Default: none +# +#labels=label_type:label_value +{% if newrelic_labels|default(None) != None %} +labels={{ newrelic_labels }} +{% endif %} + +# +# Option : disable_nfs +# Type : boolean +# Value : Set to true to disable NFS client statistics gathering. +# Default: false +# +disable_nfs={{ newrelic_disable_nfs | to_nice_json }} + +# +# Option : disable_docker +# Type : boolean +# Value : Set to true to disable Docker container statistics gathering. +# Default: false +# +disable_docker={{ newrelic_disable_docker | to_nice_json }} + +# +# Option : override_hostname +# Type : string +# Value : Set to a non-empty value to use as the hostname that will be reported to New Relic +# Default: none +# +#hostname=newrelic.com +{% if newrelic_override_hostname|default(None) != None %} +hostname={{ newrelic_override_hostname }} +{% endif %} diff --git a/provisioning/roles/weareinteractive.newrelic/tests/main.yml b/provisioning/roles/weareinteractive.newrelic/tests/main.yml new file mode 100644 index 000000000..e5b915df8 --- /dev/null +++ b/provisioning/roles/weareinteractive.newrelic/tests/main.yml @@ -0,0 +1,11 @@ +--- + +- hosts: all + become: yes + roles: + - weareinteractive.newrelic + vars: + newrelic_license_key: ab2fa361cd4d0d373833cad619d7bcc424d27c16 + # not starting service in docker env + newrelic_service_state: stopped + newrelic_service_enabled: false diff --git a/provisioning/tasks/app-toggles.yml b/provisioning/tasks/app-toggles.yml new file mode 100644 index 000000000..d48193be2 --- /dev/null +++ b/provisioning/tasks/app-toggles.yml @@ -0,0 +1,46 @@ +--- +- name: Configure toggle vars for Debian/Ubuntu. + set_fact: + apache_service: apache2 + mysql_daemon: mysql + when: ansible_os_family == 'Debian' + +- name: Configure toggle vars for CentOS. + set_fact: + apache_service: httpd + mysql_daemon: "{{ 'mysqld' if ansible_distribution_major_version == '6' else 'mariadb' }}" + when: ansible_os_family == 'RedHat' + +# Toggle for drupalvm_webserver. +- name: Ensure Apache is stopped and disabled if Nginx is used. + service: + name: "{{ apache_service }}" + state: stopped + enabled: false + failed_when: false + when: drupalvm_webserver == 'nginx' + +- name: Ensure Nginx is stopped and disabled if Apache is used. + service: + name: nginx + state: stopped + enabled: false + failed_when: false + when: drupalvm_webserver == 'apache' + +# Toggle for drupal_db_backend. +- name: Ensure MySQL is stopped and disabled if Postgres is used. + service: + name: "{{ mysql_daemon }}" + state: stopped + enabled: false + failed_when: false + when: drupal_db_backend == 'pgsql' + +- name: Ensure Postgres is stopped and disabled if MySQL is used. + service: + name: postgresql + state: stopped + enabled: false + failed_when: false + when: drupal_db_backend == 'mysql' diff --git a/provisioning/tasks/apparmor.yml b/provisioning/tasks/apparmor.yml index 926f65cf6..c9b6dd09d 100644 --- a/provisioning/tasks/apparmor.yml +++ b/provisioning/tasks/apparmor.yml @@ -1,12 +1,23 @@ --- +- name: Detect if AppArmor is working. + command: service apparmor status + args: + warn: no + register: apparmor_status + failed_when: false + changed_when: false + - name: Ensure MySQL AppArmor profile is disabled (for slow query log). file: path: /etc/apparmor.d/disable/usr.sbin.mysqld src: /etc/apparmor.d/usr.sbin.mysqld state: link register: mysql_apparmor - when: mysql_slow_query_log_enabled + when: + - mysql_slow_query_log_enabled + - apparmor_status.rc == 0 -- name: Restart AppArmor if necessary. +- name: Restart the AppArmor if necessary. service: name=apparmor state=restarted when: mysql_apparmor.changed + tags: ['skip_ansible_lint'] diff --git a/provisioning/tasks/backwards-compatibility.yml b/provisioning/tasks/backwards-compatibility.yml new file mode 100644 index 000000000..53760db94 --- /dev/null +++ b/provisioning/tasks/backwards-compatibility.yml @@ -0,0 +1,5 @@ +--- +- name: nginx_hosts shim + set_fact: + nginx_vhosts: "{{ nginx_hosts }}" + when: nginx_hosts is defined diff --git a/provisioning/tasks/build-makefile.yml b/provisioning/tasks/build-makefile.yml deleted file mode 100644 index ef1be3a47..000000000 --- a/provisioning/tasks/build-makefile.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -- name: Ensure drupal_core_path directory exists. - file: - path: "{{ drupal_core_path }}" - state: directory - mode: 0775 - sudo: no - when: drupal_site.stat.exists == false - -- name: Generate Drupal site with drush makefile. - command: > - {{ drush_path }} make -y {{ drush_makefile_path }} --no-gitinfofile - chdir={{ drupal_core_path }} - when: drupal_site.stat.exists == false - sudo: no diff --git a/provisioning/tasks/config.yml b/provisioning/tasks/config.yml new file mode 100644 index 000000000..904501cc2 --- /dev/null +++ b/provisioning/tasks/config.yml @@ -0,0 +1,16 @@ +--- +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define config_dir. + set_fact: + config_dir: "{{ playbook_dir }}/.." + when: config_dir is not defined + +- name: Include optional configuration files. + include_vars: "{{ item }}" + with_fileglob: + - "{{ config_dir }}/config.yml" + - "{{ config_dir }}/secrets.yml" + - "{{ config_dir }}/{{ lookup('env', 'DRUPALVM_ENV')|default(drupalvm_env, true)|default(ansible_env.DRUPALVM_ENV)|default(omit) }}.config.yml" + - "{{ config_dir }}/local.config.yml" diff --git a/provisioning/tasks/cron.yml b/provisioning/tasks/cron.yml index 4fdfdf8e5..f015cde16 100644 --- a/provisioning/tasks/cron.yml +++ b/provisioning/tasks/cron.yml @@ -1,5 +1,5 @@ --- -- name: Ensure configured cron jobs exist in root account's crontab. +- name: Ensure configured cron jobs exist in user account's crontab. cron: name: "{{ item.name }}" minute: "{{ item.minute | default('*') }}" @@ -9,5 +9,5 @@ month: "{{ item.month | default('*') }}" job: "{{ item.job }}" state: "{{ item.state | default('present') }}" - with_items: drupalvm_cron_jobs - when: drupalvm_cron_jobs is defined + with_items: "{{ drupalvm_cron_jobs|default([]) }}" + become: no diff --git a/provisioning/tasks/dashboard.yml b/provisioning/tasks/dashboard.yml new file mode 100644 index 000000000..164b07aa8 --- /dev/null +++ b/provisioning/tasks/dashboard.yml @@ -0,0 +1,18 @@ +--- +- name: Ensure the dashboard directory exists. + file: + path: "{{ dashboard_install_dir }}" + state: directory + mode: 0755 + +- name: Copy dashboard page into place. + template: + src: ../templates/dashboard.html.j2 + dest: "{{ dashboard_install_dir }}/index.html" + mode: 0644 + +- name: Copy phpinfo file into place. + copy: + src: ../templates/server-info.php.j2 + dest: "{{ dashboard_install_dir }}/server-info.php" + mode: 0644 diff --git a/provisioning/tasks/drush-aliases.yml b/provisioning/tasks/drush-aliases.yml index 9f89d03ba..65bc58d63 100644 --- a/provisioning/tasks/drush-aliases.yml +++ b/provisioning/tasks/drush-aliases.yml @@ -1,43 +1,111 @@ --- -- name: Ensure drush directory exists for vagrant user inside VM. - file: 'path="~/.drush" state=directory' - sudo: no +# On the host machine. +- name: Ensure Drush directories exist. + file: + path: "{{ item }}" + state: directory + mode: 0755 + delegate_to: 127.0.0.1 + become: no + with_items: + - ~/.drush + - ~/.drush/sites -- name: Configure drush aliases for vagrant user inside VM. - template: - src: ../templates/drupalvm-local.aliases.drushrc.php.j2 - dest: "~/.drush/{{ vagrant_machine_name }}.aliases.drushrc.php" - sudo: no +- name: Check if Drush configuration file exists. + stat: + path: ~/.drush/drush.yml + delegate_to: 127.0.0.1 + become: no + register: drush_config_file -- name: Ensure drush directory exists for root user inside VM. - file: 'path="~/.drush" state=directory' +- name: Create a Drush configuration file with a custom alias-path. + copy: + src: ../templates/drush.yml + dest: ~/.drush/drush.yml + mode: 0644 + delegate_to: 127.0.0.1 + become: no + when: not drush_config_file.stat.exists -- name: Configure drush aliases for root user inside VM. +# Note that this doesn't work for Windows, since Ansible's running in the VM. +# Note also that we are copying both Drush < 9 and Drush >= 9 alias files since +# there's no other way to support multiple versions of Drush :-(. +- name: Configure host machine drush aliases. template: - src: ../templates/drupalvm-local.aliases.drushrc.php.j2 - dest: "~/.drush/{{ vagrant_machine_name }}.aliases.drushrc.php" + src: "{{ item.src }}" + dest: "{{ item.dest }}" + delegate_to: 127.0.0.1 + become: no + with_items: + - src: "{{ drush_aliases_host_template }}" + dest: "~/.drush/{{ vagrant_machine_name }}.aliases.drushrc.php" + - src: "{{ drush_aliases_host_template_yml }}" + dest: "~/.drush/sites/{{ vagrant_machine_name }}.site.yml" + +# Inside the VM - Vagrant user. +- name: Ensure drush directories exist for vagrant user inside VM. + file: + path: "{{ item }}" + state: directory + mode: 0755 + become: no + with_items: + - ~/.drush + - ~/.drush/sites -- name: Check if local Drush configuration folder exists. +- name: Check if Drush configuration file exists. stat: - path: ~/.drush - register: local_drush_config_folder - delegate_to: 127.0.0.1 - sudo: no - when: configure_local_drush_aliases + path: ~/.drush/drush.yml + become: no + register: drush_config_file_inside -- name: Create Drush configuration folder if it doesn't exist. +- name: Create a Drush configuration file with a custom alias-path. + copy: + src: ../templates/drush.yml + dest: ~/.drush/drush.yml + mode: 0644 + become: no + when: not drush_config_file_inside.stat.exists + +- name: Configure drush aliases for vagrant user inside VM. + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + become: no + with_items: + - src: "{{ drush_aliases_guest_template }}" + dest: "~/.drush/{{ vagrant_machine_name }}.aliases.drushrc.php" + - src: "{{ drush_aliases_guest_template_yml }}" + dest: "~/.drush/sites/{{ vagrant_machine_name }}.site.yml" + +# Inside the VM - root user. +- name: Ensure drush directories exist for root user inside VM. file: - path: ~/.drush + path: "{{ item }}" state: directory - delegate_to: 127.0.0.1 - sudo: no - when: configure_local_drush_aliases and (local_drush_config_folder.stat.exists == false) + mode: 0755 + with_items: + - ~/.drush + - ~/.drush/sites -# Note that this doesn't work for Windows, since Ansible's running in the VM. -- name: Configure host machine drush aliases. +- name: Check if Drush configuration file exists. + stat: + path: ~/.drush/drush.yml + register: drush_config_file_inside_root + +- name: Create a Drush configuration file with a custom alias-path. + copy: + src: ../templates/drush.yml + dest: ~/.drush/drush.yml + mode: 0644 + when: not drush_config_file_inside_root.stat.exists + +- name: Configure drush aliases for root user inside VM. template: - src: ../templates/drupalvm.aliases.drushrc.php.j2 - dest: "~/.drush/{{ vagrant_machine_name }}.aliases.drushrc.php" - delegate_to: 127.0.0.1 - sudo: no - when: configure_local_drush_aliases + src: "{{ item.src }}" + dest: "{{ item.dest }}" + with_items: + - src: "{{ drush_aliases_guest_template }}" + dest: "~/.drush/{{ vagrant_machine_name }}.aliases.drushrc.php" + - src: "{{ drush_aliases_guest_template_yml }}" + dest: "~/.drush/sites/{{ vagrant_machine_name }}.site.yml" diff --git a/provisioning/tasks/extras.yml b/provisioning/tasks/extras.yml index a7b7e7b74..635d2c25b 100644 --- a/provisioning/tasks/extras.yml +++ b/provisioning/tasks/extras.yml @@ -1,10 +1,12 @@ --- - name: Install extra apt packages (if any are configured). - apt: "name={{ item }} state=installed" - with_items: extra_packages | list - when: ansible_os_family == 'Debian' and extra_packages | length + apt: "name={{ extra_packages | list }} state=present" + when: + - ansible_os_family == 'Debian' + - extra_packages | length - name: Install extra yum packages (if any are configured). - yum: "name={{ item }} state=installed" - with_items: extra_packages | list - when: ansible_os_family == 'RedHat' and extra_packages | length + yum: "name={{ extra_packages | list }} state=present" + when: + - ansible_os_family == 'RedHat' + - extra_packages | length diff --git a/provisioning/tasks/init-Debian.yml b/provisioning/tasks/init-Debian.yml new file mode 100644 index 000000000..d707c2d72 --- /dev/null +++ b/provisioning/tasks/init-Debian.yml @@ -0,0 +1,27 @@ +--- +- name: Update apt cache if needed. + apt: update_cache=true cache_valid_time=86400 + +- name: Install required dependencies. + apt: + name: + - curl + - python-apt + - python-pycurl + - sudo + - unzip + - make + state: present + +# Ubuntu-specific tasks. +- name: Add repository for Apache 2.4.9+ (Ubuntu 12/14). + apt_repository: repo='ppa:ondrej/apache2' + when: + - ansible_distribution_release == "precise" or ansible_distribution_release == "trusty" + - ansible_distribution == "Ubuntu" + +- name: Define php_xhprof_html_dir. + set_fact: + php_xhprof_html_dir: "/usr/share/php/xhprof_html" + when: php_xhprof_html_dir is not defined + tags: ['webserver'] diff --git a/provisioning/tasks/init-RedHat.yml b/provisioning/tasks/init-RedHat.yml new file mode 100644 index 000000000..415742d61 --- /dev/null +++ b/provisioning/tasks/init-RedHat.yml @@ -0,0 +1,21 @@ +--- +- name: Install required dependencies. + yum: + name: + - curl + - python3-pycurl + - unzip + - make + - gcc + state: present + +- name: Enable remi repo for MySQL. + set_fact: + mysql_enablerepo: remi + when: mysql_enablerepo is not defined or mysql_enablerepo == "" + +- name: Define php_xhprof_html_dir. + set_fact: + php_xhprof_html_dir: /usr/share/pear/xhprof_html + when: php_xhprof_html_dir is not defined + tags: ['webserver'] diff --git a/provisioning/tasks/init-debian.yml b/provisioning/tasks/init-debian.yml deleted file mode 100644 index 1e39ad63e..000000000 --- a/provisioning/tasks/init-debian.yml +++ /dev/null @@ -1,30 +0,0 @@ ---- -- name: Update apt cache if needed. - apt: update_cache=yes cache_valid_time=86400 - -- name: Get software for Python-based control. - apt: "name={{ item }} state=installed" - with_items: - - curl - - python-apt - - python-pycurl - - build-essential - -- name: Disable the ufw firewall (since we use a simple iptables firewall). - service: name=ufw state=stopped - -- name: Install postfix so Drupal can send emails. - apt: name=postfix state=installed - -- name: Add repository for PHP 5.5. - apt_repository: repo='ppa:ondrej/php5' - when: php_version == "5.5" - -- name: Add repository for PHP 5.6. - apt_repository: repo='ppa:ondrej/php5-5.6' - when: php_version == "5.6" - -# Experimental. -- name: Add repository for PHP 7.0. - apt_repository: repo='ppa:ondrej/php-7.0' - when: php_version == "7.0" diff --git a/provisioning/tasks/init-redhat.yml b/provisioning/tasks/init-redhat.yml deleted file mode 100644 index b4d265efc..000000000 --- a/provisioning/tasks/init-redhat.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -- name: Get software for Python-based control. - yum: "name={{ item }} state=installed" - with_items: - - "curl" - - "python-pycurl" - - "@development" - -- name: Install postfix so Drupal can send emails. - yum: name=postfix state=installed - -- name: Enable remi repo for MySQL. - set_fact: mysql_enablerepo="remi" - -- name: Enable remi repo for PHP 5.5. - set_fact: php_enablerepo="remi,remi-php55" - when: php_version == "5.5" - -- name: Enable remi repo for PHP 5.6. - set_fact: php_enablerepo="remi,remi-php56" - when: php_version == "5.6" - -- name: Enable remi repo for PHP 7.0. - set_fact: php_enablerepo="remi,remi-test" - when: php_version == "7.0" diff --git a/provisioning/tasks/install-site.yml b/provisioning/tasks/install-site.yml deleted file mode 100644 index 9ee4df24b..000000000 --- a/provisioning/tasks/install-site.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- name: Check if site is already installed. - command: > - {{ drush_path }} status bootstrap - chdir={{ drupal_core_path }} - register: drupal_site_installed - failed_when: false - changed_when: false - sudo: no - -- name: Install Drupal with drush. - command: > - {{ drush_path }} site-install {{ drupal_install_profile | default('standard') }} -y - --site-name="{{ drupal_site_name }}" - --account-name={{ drupal_account_name }} - --account-pass={{ drupal_account_pass }} - --db-url=mysql://{{ drupal_mysql_user }}:{{ drupal_mysql_password }}@localhost/{{ mysql_databases[0].name }} - chdir={{ drupal_core_path }} - notify: restart webserver - when: "'Successful' not in drupal_site_installed.stdout" - sudo: no - -- name: Install configured modules with drush. - command: > - {{ drush_path }} pm-enable -y {{ drupal_enable_modules | join(" ") }} - chdir={{ drupal_core_path }} - when: "'Successful' not in drupal_site_installed.stdout" - sudo: no diff --git a/provisioning/tasks/php.yml b/provisioning/tasks/php.yml new file mode 100644 index 000000000..688e84f96 --- /dev/null +++ b/provisioning/tasks/php.yml @@ -0,0 +1,13 @@ +--- +- name: Set the PHP webserver daemon correctly when nginx is in use. + set_fact: + php_webserver_daemon: nginx + when: drupalvm_webserver == 'nginx' + tags: ['webserver', 'database', 'php'] + +- name: Ensure PHP version-specific workspace directory exists. + file: + path: "/root/php{{ php_version }}" + state: directory + mode: 0775 + tags: ['php', 'xdebug'] diff --git a/provisioning/tasks/sshd.yml b/provisioning/tasks/sshd.yml new file mode 100644 index 000000000..ede2cdbf5 --- /dev/null +++ b/provisioning/tasks/sshd.yml @@ -0,0 +1,42 @@ +--- +- name: Do not accept locale environment variables passed over SSH. + lineinfile: + dest: /etc/ssh/sshd_config + regexp: "^AcceptEnv LANG" + state: absent + validate: "/usr/sbin/sshd -T -f %s" + +- name: Allow client to pass PHP and XDEBUG environment variables over SSH. + lineinfile: + dest: /etc/ssh/sshd_config + line: "AcceptEnv {{ item }}" + validate: "/usr/sbin/sshd -T -f %s" + with_items: + - PHP_IDE_CONFIG + - XDEBUG_CONFIG + - PHP_OPTIONS + when: '"xdebug" in installed_extras' + +- name: Check if local known_hosts file is present. + stat: "path={{ known_hosts_path | default('~/.ssh/known_hosts') }}" + register: known_hosts_file + connection: local + become: no + +- name: Copy known_hosts file from host into Drupal VM. + copy: + src: "{{ known_hosts_path | default('~/.ssh/known_hosts') }}" + dest: ~/.ssh/known_hosts + mode: 0644 + become: no + when: known_hosts_file.stat.exists + +- name: Set SSH home directory. + lineinfile: + dest: "/home/{{ drupalvm_user }}/.bashrc" + state: present + create: yes + regexp: "^SSH_HOME=" + line: "SSH_HOME={{ ssh_home }} && [ -e $SSH_HOME ] && cd $SSH_HOME" + become: no + when: ssh_home is defined diff --git a/provisioning/tasks/www.yml b/provisioning/tasks/www.yml deleted file mode 100644 index d1b23d07d..000000000 --- a/provisioning/tasks/www.yml +++ /dev/null @@ -1,23 +0,0 @@ ---- -# Originally I tried adding to the www group, but because Ansible uses one SSH -# connection, that broke the initial provisioning, since groups aren't refreshed -# without a new session or log off/log on. -- name: Ensure necessary groups exist. - group: "name={{ item }} state=present" - with_items: - - admin - - dialout - -- name: Ensure vagrant user is in admin group. - user: "name={{ vagrant_user }} append=yes groups=admin" - -- name: Ensure www-data user is in dialout group (Debian). - user: "name=www-data append=yes groups=dialout" - when: ansible_os_family == 'Debian' - -- name: Set nicer permissions on Apache log directory. - file: - path: "/var/log/{{ apache_daemon }}" - state: directory - mode: 0755 - recurse: true diff --git a/provisioning/templates/dashboard.html.j2 b/provisioning/templates/dashboard.html.j2 new file mode 100644 index 000000000..212732902 --- /dev/null +++ b/provisioning/templates/dashboard.html.j2 @@ -0,0 +1,380 @@ +<!DOCTYPE html> + <head> + <title>Drupal VM + + + + + + {# Sets vagrant IP if equals 0.0.0.0 #} + {%- if vagrant_ip == '0.0.0.0' -%} + {%- set vagrant_ip = ansible_all_ipv4_addresses[1] -%} + {%- endif -%} + {# Returns the hosts server name based on the document root #} + {%- macro getServernameFromDocroot(path) -%} + {%- if drupalvm_webserver == 'apache' -%} + {%- for host in apache_vhosts -%} + {%- if host.documentroot == path -%} + {{ host.servername }} + {%- endif -%} + {%- endfor -%} + {%- elif drupalvm_webserver == 'nginx' -%} + {%- for host in nginx_vhosts -%} + {%- if host.root == path -%} + {{ host.server_name }} + {%- endif -%} + {%- endfor -%} + {%- endif -%} + {%- endmacro -%} + + {%- macro printSite(servername, docroot) -%} + {%- if docroot not in _devtool_docroots -%} + + {{ servername }} + {{ docroot }} + {% if configure_drush_aliases %} + drush @{{ vagrant_machine_name }}.{{ servername }} + {% endif %} + + {% endif %} + {%- endmacro %} + + {%- macro printHostsEntry(ip, servername) -%} + {%- if servername != ip -%} +
  • {{ ip }} {{ servername }}
  • + {%- endif -%} + {%- endmacro %} + + {%- macro sectionHost() -%} +
      + {% if drupalvm_webserver == 'apache' -%} + {%- for host in apache_vhosts -%} + + {{ printHostsEntry(vagrant_ip, host.servername) }} + {% if host.serveralias is defined -%} + {%- for alias in host.serveralias.split() -%} + {{ printHostsEntry(vagrant_ip, alias) }} + {%- endfor -%} + {%- endif %} + + {%- endfor -%} + {%- elif drupalvm_webserver == 'nginx' -%} + {%- for host in nginx_vhosts -%} + + {% for server_name in host.server_name.split(' ') -%} + {{ printHostsEntry(vagrant_ip, server_name) }} + {%- endfor %} + {% if host.server_name_redirect is defined -%} + {%- for server_name in host.server_name_redirect.split(' ') -%} + {{ printHostsEntry(vagrant_ip, server_name) }} + {%- endfor -%} + {%- endif %} + + {%- endfor -%} + {%- endif %} +
    + {%- endmacro -%} + + {%- macro sectionSiteList() -%} +
    + + + + + + {% if configure_drush_aliases -%} + + {%- endif %} + + + + {% if drupalvm_webserver == 'apache' -%} + {%- for host in apache_vhosts -%} + {%- if host.documentroot is defined -%} + {{ printSite(host.servername, host.documentroot) }} + {%- endif -%} + {%- endfor -%} + {%- elif drupalvm_webserver == 'nginx' -%} + {%- for host in nginx_vhosts -%} + {%- if host.root is defined -%} + {%- for hostname in host.server_name.split() -%} + {{ printSite(hostname, host.root) }} + {%- endfor -%} + {%- endif -%} + {%- endfor -%} + {%- endif %} + + +
    HostnameDocument RootDrush alias*
    *Note: If Ansible isn't installed on your host, Drush aliases are only created inside the VM.
    +
    + {%- endmacro -%} + + {%- macro sectionDevelopmentTools() -%} +
    + + {% if not installed_extras -%} + + + + {%- endif -%} + {% if 'adminer' in installed_extras -%} + {% macro servername() %}{{ getServernameFromDocroot(adminer_install_dir) }}/{{ adminer_install_filename }}{% endmacro %} + {%- if servername() != "/{{ adminer_install_filename }}" -%} + + + + + {%- endif -%} + {%- endif %} + {% if 'mailhog' in installed_extras -%} + {% macro servername() %}{{ vagrant_hostname }}:8025{% endmacro %} + {%- if servername() != ":8025" -%} + + + + + {%- endif -%} + {%- endif %} + {% if 'solr' in installed_extras -%} + {% macro servername() %}{{ vagrant_hostname }}:{{ solr_port }}/solr/{% endmacro %} + + + + + {%- endif %} + {% if 'xhprof' in installed_extras -%} + {% macro servername() %}{{ getServernameFromDocroot(php_xhprof_html_dir) }}{% endmacro %} + {%- if servername() -%} + + + + + {%- endif -%} + {%- endif %} +
    There are no development tools installed inside the VM.
    Adminer{{ servername() }} +
    + Open + Documentation +
    MailHog{{ servername() }} +
    + Open + Documentation +
    Solr{{ servername() }} +
    + Open + Documentation +
    XHProf{{ servername() }} +
    + Open + Documentation +
    +
    + {%- endmacro -%} + + {%- macro sectionPhpInformation() -%} +
    + + + + + + + + + + + + + + + + + + +
    PHP Version{{ php_version }}
    Webserver{{ drupalvm_webserver|capitalize }}
    Memory limit{{ php_memory_limit }}
    PHP-FPM enabled{{ 'yes' if php_enable_php_fpm else 'no' }}
    View more details in the server's phpinfo() report.
    +
    + {%- endmacro -%} + + {%- macro sectionDatabaseConnection() -%} +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MySQL Hostname127.0.0.1
    MySQL Port{{ mysql_port }}
    MySQL Username{{ mysql_root_username }}
    MySQL Password{{ mysql_root_password }}
    SSH Hostname{{ vagrant_ip }}
    SSH Username{{ vagrant_user }}
    SSH Private Key~/.vagrant.d/insecure_private_key
    +
    + {%- endmacro -%} + + {%- macro sectionDatabaseList() -%} +
    + + + {% for database in mysql_databases -%} + {% if 'adminer' in installed_extras -%} + + + + {% else -%} + + + + {%- endif %} + {%- endfor %} + +
    + {{ database.name }} +
    {{ database.name }}
    +
    + {%- endmacro -%} + + {%- macro SectionDatabaseListLabel() -%} + {% if 'adminer' in installed_extras -%} + Databases using Adminer + {% else -%} + Databases + {%- endif %} + {%- endmacro -%} + + + {%- macro sectionDatabaseUserList() -%} +
    + + + + + + + + + {% for user in mysql_users -%} + + + + + {%- endfor %} + +
    UsernamePassword
    {{ user.name }}{{ user.password }}
    +
    + {%- endmacro -%} + +
    + +
    +
    +
    + Drupal VM +

    Drupal VM is a VM for local Drupal development, built with Vagrant + Ansible.

    +

    Machine name: {{ vagrant_machine_name }}

    +

    Read the documentation

    +
    +
    +
    + +
    +
    +
    +
    Your sites
    +
    + {{ sectionSiteList() }} +
    +
    +
    + +
    +
    +
    {{ SectionDatabaseListLabel() }}
    +
    + {{ sectionDatabaseList() }} + + {{ sectionDatabaseUserList() }} +
    +
    +
    +
    + +
    +
    +
    +
    PHP information
    +
    + {{ sectionPhpInformation() }} +
    +
    +
    + +
    +
    +
    MySQL connection information
    +
    + {{ sectionDatabaseConnection() }} +
    +
    +
    + +
    +
    +
    Development tools
    +
    + {{ sectionDevelopmentTools() }} +
    +
    +
    +
    + +
    +
    +
    +
    /etc/hosts
    +
    +
    + {{ sectionHost() }} +
    + Unless you're using the vagrant-hostsupdater or vagrant-hostmanager plugin, add the lines above to your host machine's hosts file. +
    +
    +
    +
    +
    + + + + diff --git a/provisioning/templates/drupalvm-local.aliases.drushrc.php.j2 b/provisioning/templates/drupalvm-local.aliases.drushrc.php.j2 index 20c40ed63..280d62394 100644 --- a/provisioning/templates/drupalvm-local.aliases.drushrc.php.j2 +++ b/provisioning/templates/drupalvm-local.aliases.drushrc.php.j2 @@ -3,13 +3,34 @@ /** * Drupal VM drush aliases. * - * @see example.aliases.drushrc.php. + * {{ ansible_managed }} */ -{% for vhost in apache_vhosts %} -$aliases['{{ vhost.servername }}'] = array( - 'uri' => '{{ vhost.servername }}', - 'root' => '{{ vhost.documentroot }}', +{% macro alias(host, root) -%} +{%- if root not in _devtool_docroots %} +$aliases['{{ host.split('.')[0] }}'] = array( + 'uri' => '{{ host }}', + 'root' => '{{ root }}', ); -{% endfor %} +{% endif -%} +{% endmacro -%} + +{% block aliases -%} +{%- if drupalvm_webserver == 'apache' -%} + {%- for vhost in apache_vhosts -%} + {{ alias(vhost.servername, vhost.documentroot) }} + {%- if vhost.serveralias is defined -%} + {%- for serveralias in vhost.serveralias.split() -%} + {{ alias(serveralias, vhost.documentroot) }} + {%- endfor -%} + {%- endif -%} + {%- endfor -%} +{%- elif drupalvm_webserver == 'nginx' -%} + {%- for host in nginx_vhosts -%} + {%- for server_name in host.server_name.split() -%} + {{ alias(server_name, host.root) }} + {%- endfor -%} + {%- endfor -%} +{%- endif -%} +{%- endblock %} diff --git a/provisioning/templates/drupalvm-local.aliases.yml.j2 b/provisioning/templates/drupalvm-local.aliases.yml.j2 new file mode 100644 index 000000000..cefdb4ccc --- /dev/null +++ b/provisioning/templates/drupalvm-local.aliases.yml.j2 @@ -0,0 +1,29 @@ +# {{ ansible_managed }} +{% macro alias(host, root) -%} +{%- if root not in _devtool_docroots %} +{{ host.split('.')[0] }}: + options: { } + root: '{{ root }}' + uri: '{{ host }}' + +{% endif -%} +{% endmacro -%} + +{% block aliases -%} +{%- if drupalvm_webserver == 'apache' -%} + {%- for vhost in apache_vhosts -%} + {{ alias(vhost.servername, vhost.documentroot) }} + {%- if vhost.serveralias is defined -%} + {%- for serveralias in vhost.serveralias.split() -%} + {{ alias(serveralias, vhost.documentroot) }} + {%- endfor -%} + {%- endif -%} + {%- endfor -%} +{%- elif drupalvm_webserver == 'nginx' -%} + {%- for host in nginx_vhosts -%} + {%- for server_name in host.server_name.split() -%} + {{ alias(server_name, host.root) }} + {%- endfor -%} + {%- endfor -%} +{%- endif -%} +{%- endblock %} diff --git a/provisioning/templates/drupalvm.aliases.drushrc.php.j2 b/provisioning/templates/drupalvm.aliases.drushrc.php.j2 index 9f1138518..efb3e3ccc 100644 --- a/provisioning/templates/drupalvm.aliases.drushrc.php.j2 +++ b/provisioning/templates/drupalvm.aliases.drushrc.php.j2 @@ -3,16 +3,40 @@ /** * Drupal VM drush aliases. * - * @see example.aliases.drushrc.php. + * {{ ansible_managed }} */ -{% for vhost in apache_vhosts %} -$aliases['{{ vhost.servername }}'] = array( - 'uri' => '{{ vhost.servername }}', - 'root' => '{{ vhost.documentroot }}', - 'remote-host' => '{{ vhost.servername }}', - 'remote-user' => 'vagrant', - 'ssh-options' => '-o PasswordAuthentication=no -i ~/.vagrant.d/insecure_private_key', +{% macro alias(host, root) -%} +{%- if root not in _devtool_docroots %} +$aliases['{{ host.split('.')[0] }}'] = array( + 'uri' => '{{ host }}', + 'root' => '{{ root }}', + 'remote-host' => '{{ host }}', + 'remote-user' => '{{ vagrant_user }}', + 'ssh-options' => '-o "SendEnv PHP_IDE_CONFIG PHP_OPTIONS XDEBUG_CONFIG" -o PasswordAuthentication=no -i "' . (getenv('VAGRANT_HOME') ?: drush_server_home() . '/.vagrant.d') . '/insecure_private_key"', + 'path-aliases' => array( + '%drush-script' => '{{ drush_path }}', + ), ); -{% endfor %} +{% endif -%} +{% endmacro -%} + +{% block aliases -%} +{%- if drupalvm_webserver == 'apache' -%} + {%- for vhost in apache_vhosts -%} + {{ alias(vhost.servername, vhost.documentroot) }} + {%- if vhost.serveralias is defined -%} + {%- for serveralias in vhost.serveralias.split() -%} + {{ alias(serveralias, vhost.documentroot) }} + {%- endfor -%} + {%- endif -%} + {%- endfor -%} +{%- elif drupalvm_webserver == 'nginx' -%} + {%- for host in nginx_vhosts -%} + {%- for server_name in host.server_name.split() -%} + {{ alias(server_name, host.root) }} + {%- endfor -%} + {%- endfor -%} +{%- endif -%} +{%- endblock %} diff --git a/provisioning/templates/drupalvm.aliases.yml.j2 b/provisioning/templates/drupalvm.aliases.yml.j2 new file mode 100644 index 000000000..c91041ade --- /dev/null +++ b/provisioning/templates/drupalvm.aliases.yml.j2 @@ -0,0 +1,33 @@ +# {{ ansible_managed }} +{% macro alias(host, root) -%} +{%- if root not in _devtool_docroots %} +{{ host.split('.')[0] }}: + host: '{{ host }}' + options: { } + root: '{{ root }}' + uri: '{{ host }}' + user: '{{ vagrant_user }}' + ssh: + options: '-o "SendEnv PHP_IDE_CONFIG PHP_OPTIONS XDEBUG_CONFIG" -o PasswordAuthentication=no -i "${env.home}/.vagrant.d/insecure_private_key"' + +{% endif -%} +{% endmacro -%} + +{% block aliases -%} +{%- if drupalvm_webserver == 'apache' -%} + {%- for vhost in apache_vhosts -%} + {{ alias(vhost.servername, vhost.documentroot) }} + {%- if vhost.serveralias is defined -%} + {%- for serveralias in vhost.serveralias.split() -%} + {{ alias(serveralias, vhost.documentroot) }} + {%- endfor -%} + {%- endif -%} + {%- endfor -%} +{%- elif drupalvm_webserver == 'nginx' -%} + {%- for host in nginx_vhosts -%} + {%- for server_name in host.server_name.split() -%} + {{ alias(server_name, host.root) }} + {%- endfor -%} + {%- endfor -%} +{%- endif -%} +{%- endblock %} diff --git a/provisioning/templates/drupalvm.vcl.j2 b/provisioning/templates/drupalvm.vcl.j2 index 29ede513f..cef0ae133 100644 --- a/provisioning/templates/drupalvm.vcl.j2 +++ b/provisioning/templates/drupalvm.vcl.j2 @@ -1,21 +1,30 @@ +{% block version -%} vcl 4.0; +{% endblock %} # This Varnish VCL has been adapted from the Four Kitchens VCL for Varnish 3. # Default backend definition. Points to Apache, normally. backend default { + {% block backend -%} .host = "{{ varnish_default_backend_host }}"; .port = "{{ varnish_default_backend_port }}"; .first_byte_timeout = 300s; + {% endblock %} + } # Access control list for PURGE requests. acl purge { + {% block acl_purge -%} "127.0.0.1"; + {% endblock %} + } # Respond to incoming requests. sub vcl_recv { + {% block http_header -%} # Add an X-Forwarded-For header with the client IP address. if (req.restarts == 0) { if (req.http.X-Forwarded-For) { @@ -25,20 +34,48 @@ sub vcl_recv { set req.http.X-Forwarded-For = client.ip; } } + {% endblock %} + {% block method_purge -%} # Only allow PURGE requests from IP addresses in the 'purge' ACL. if (req.method == "PURGE") { if (!client.ip ~ purge) { return (synth(405, "Not allowed.")); } - return (hash); + return (purge); + } + {% endblock %} + + {% block method_ban -%} + # Only allow BAN requests from IP addresses in the 'purge' ACL. + if (req.method == "BAN") { + # Same ACL check as above: + if (!client.ip ~ purge) { + return (synth(403, "Not allowed.")); + } + + # Logic for the ban, using the Cache-Tags header. For more info + # see https://github.com/geerlingguy/drupal-vm/issues/397. + if (req.http.Cache-Tags) { + ban("obj.http.Cache-Tags ~ " + req.http.Cache-Tags); + } + else { + return (synth(403, "Cache-Tags header missing.")); + } + + # Throw a synthetic page so the request won't go to the backend. + return (synth(200, "Ban added.")); } + {% endblock %} + {% block pass_post -%} # Only cache GET and HEAD requests (pass through POST requests). if (req.method != "GET" && req.method != "HEAD") { return (pass); } + {% endblock %} + {% block pass_admin -%} # Pass through any administrative or AJAX-related paths. if (req.url ~ "^/status\.php$" || req.url ~ "^/update\.php$" || @@ -49,7 +86,9 @@ sub vcl_recv { req.url ~ "^.*/ahah/.*$") { return (pass); } + {% endblock %} + {% block cookies -%} # Removing cookies for static content so Varnish caches these files. if (req.url ~ "(?i)\.(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)?$") { unset req.http.Cookie; @@ -86,25 +125,46 @@ sub vcl_recv { return (pass); } } + {% endblock %} + } # Set a header to track a cache HITs and MISSes. sub vcl_deliver { + {% block vcl_deliver -%} + # Remove ban-lurker friendly custom headers when delivering to client. + unset resp.http.X-Url; + unset resp.http.X-Host; + unset resp.http.Purge-Cache-Tags; + if (obj.hits > 0) { set resp.http.X-Varnish-Cache = "HIT"; } else { set resp.http.X-Varnish-Cache = "MISS"; } + {% endblock %} + } # Instruct Varnish what to do in the case of certain backend responses (beresp). sub vcl_backend_response { + {% block vcl_backend_response -%} + # Set ban-lurker friendly custom headers. + set beresp.http.X-Url = bereq.url; + set beresp.http.X-Host = bereq.http.host; + # Cache 404s, 301s, at 500s with a short lifetime to protect the backend. if (beresp.status == 404 || beresp.status == 301 || beresp.status == 500) { set beresp.ttl = 10m; } + # Enable streaming directly to backend for BigPipe responses. + if (beresp.http.Surrogate-Control ~ "BigPipe/1.0") { + set beresp.do_stream = true; + set beresp.ttl = 0s; + } + # Don't allow static files to set cookies. # (?i) denotes case insensitive in PCRE (perl compatible regular expressions). # This list of extensions appears twice, once here and again in vcl_recv so @@ -115,4 +175,6 @@ sub vcl_backend_response { # Allow items to remain in cache up to 6 hours past their cache expiration. set beresp.grace = 6h; + {% endblock %} + } diff --git a/provisioning/templates/drush.yml b/provisioning/templates/drush.yml new file mode 100644 index 000000000..4ad3f737e --- /dev/null +++ b/provisioning/templates/drush.yml @@ -0,0 +1,5 @@ +--- +drush: + paths: + alias-path: + - '${env.home}/.drush/sites' diff --git a/provisioning/templates/nginx-vhost.conf.j2 b/provisioning/templates/nginx-vhost.conf.j2 new file mode 100644 index 000000000..3ba2f3fa8 --- /dev/null +++ b/provisioning/templates/nginx-vhost.conf.j2 @@ -0,0 +1,143 @@ +{% block server_redirect -%} +{% if item.server_name_redirect is defined -%} +server { + listen 80; + server_name {{ item.server_name_redirect }}; + return 301 $scheme://{{ item.server_name.split(' ')[0] }}$request_uri; +} +{% endif %} +{% endblock %} + +server { + {% block server_begin -%}{% endblock %} + + {% block server_basic -%} + listen {{ item.listen | default('80') }}; + server_name {{ item.server_name }}; + root {{ item.root }}; + index {{ item.index | default('index.php index.html index.htm') }}; + {% endblock %} + + {% block server_logs -%} + {%- if item.access_log is defined -%} + access_log {{ item.access_log }}; + {%- endif -%} + error_log {{ item.error_log|default('/var/log/nginx/error.log') }} info; + {% endblock %} + +{% if item.is_php is defined and item.is_php %} + {% block location_primary -%} + location / { + # Don't touch PHP for static content. + try_files $uri $uri/ /index.php?$query_string; + } + {% endblock %} + + {% block location_deny -%} + # Don't allow direct access to PHP files in the vendor directory. + location ~ /vendor/.*\.php$ { + deny all; + return 404; + } + # Allow "Well-Known URIs" as per RFC 5785 + location ~* ^/.well-known/ { + allow all; + } + location ~ (^|/)\. { + return 403; + } + {% endblock %} + + {% block location_drupal_legacy -%} + {% if drupal_major_version >= 8 -%} + # Redirect common PHP files to their new locations. + location ~ ^((?!.*(?:core)).*)/(install.php|rebuild.php) { + return 301 $scheme://$host$1/core/$2$is_args$args; + } + {% endif %} + {% endblock %} + + {% block location_php -%} + # Use fastcgi for all php files. + location ~ \.php$|^/update.php { + fastcgi_split_path_info ^(.+?\.php)(|/.*)$; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $request_filename; + fastcgi_intercept_errors on; + fastcgi_read_timeout {{ php_max_execution_time }}; + include fastcgi_params; + fastcgi_pass {{ php_fpm_listen }}; + } + {% endblock %} + + {% block location_rewrite -%} + location @rewrite { + rewrite ^ /index.php; + } + {% endblock %} + + {% block location_image_styles -%} + location ~ ^/sites/.*/files/styles/ { + try_files $uri @rewrite; + } + location ~ ^(/[a-z\-]+)?/system/files/ { + try_files $uri /index.php?$query_string; + } + {% endblock %} + + {% block location_favicon -%} + location = /favicon.ico { + log_not_found off; + access_log off; + } + {% endblock %} + + {% block location_robots -%} + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + {% endblock %} + + {% block location_assets -%} + location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { + expires max; + log_not_found off; + } + {% endblock %} +{% endif %} + + {% block server_compression -%} + gzip on; + gzip_proxied any; + gzip_static on; + gzip_http_version 1.0; + gzip_disable "MSIE [1-6]\."; + gzip_vary on; + gzip_comp_level 6; + gzip_types + text/plain + text/css + text/xml + text/javascript + application/javascript + application/x-javascript + application/json + application/xml + application/xml+rss + application/xhtml+xml + application/x-font-ttf + application/x-font-opentype + image/svg+xml + image/x-icon; + gzip_buffers 16 8k; + gzip_min_length 512; + {% endblock %} + + {% block server_end -%}{% endblock %} + +{% if item.extra_parameters is defined -%} + {{ item.extra_parameters|indent(4) }} +{%- endif %} +} diff --git a/provisioning/templates/server-info.php.j2 b/provisioning/templates/server-info.php.j2 new file mode 100644 index 000000000..147cebcdd --- /dev/null +++ b/provisioning/templates/server-info.php.j2 @@ -0,0 +1 @@ + diff --git a/provisioning/vars/Debian.yml b/provisioning/vars/Debian.yml new file mode 100644 index 000000000..ed97d539c --- /dev/null +++ b/provisioning/vars/Debian.yml @@ -0,0 +1 @@ +--- diff --git a/provisioning/vars/RedHat.yml b/provisioning/vars/RedHat.yml new file mode 100644 index 000000000..c5cf1bf3c --- /dev/null +++ b/provisioning/vars/RedHat.yml @@ -0,0 +1,20 @@ +--- +# Defaults set by `ansible-role-php` with the addition of `php-pecl-yaml` and `php-mcrypt`. +php_packages: + - php + - php-cli + - php-common + - php-devel + - php-fpm + - php-gd + - php-imap + - php-ldap + - php-mbstring + - php-mcrypt + - php-opcache + - php-pdo + - php-pear + - php-pecl-apcu + - php-xml + - php-xmlrpc + - php-pecl-yaml diff --git a/provisioning/vars/main.yml b/provisioning/vars/main.yml new file mode 100644 index 000000000..4c145acb4 --- /dev/null +++ b/provisioning/vars/main.yml @@ -0,0 +1,7 @@ +--- +_devtool_docroots: + - "{{ adminer_install_dir }}" + - "{{ php_xhprof_html_dir }}" + - "{{ dashboard_install_dir|default('') }}" + +drupalvm_user: "{{ ansible_env.SUDO_USER | default(ansible_env.USER, true) | default(ansible_user_id, true) }}"