├── .gitignore
├── .pylintrc
├── .travis.yml
├── .travis
├── flow.py
└── test_python_pep8_compliancy.py
├── LICENSE.txt
├── README.md
├── app
├── Dockerfile
├── __init__.py
├── ansible.cfg
├── arguments.py
├── base.py
├── containers.py
├── db.py
├── edge.py
├── init.py
├── local_setup.py
├── mirror.py
├── orchestration.py
├── orchestration
│ ├── _tests
│ │ ├── db-tests.yml
│ │ ├── edge-tests.yml
│ │ ├── mirror-tests.yml
│ │ ├── plays
│ │ │ ├── db
│ │ │ │ ├── adminer-tests.yml
│ │ │ │ ├── db-tests.yml
│ │ │ │ ├── memcached-tests.yml
│ │ │ │ └── phpmyadmin-tests.yml
│ │ │ ├── drupal
│ │ │ │ └── drupal-tests.yml
│ │ │ ├── edge
│ │ │ │ ├── mirror-tests.yml
│ │ │ │ ├── nginx-tests.yml
│ │ │ │ └── varnish-tests.yml
│ │ │ ├── php
│ │ │ │ ├── apache-common-tests.yml
│ │ │ │ ├── apache-tests.yml
│ │ │ │ ├── pecl-yaml-tests.yml
│ │ │ │ └── php-tests.yml
│ │ │ ├── run-db-tests.yml
│ │ │ ├── run-edge-tests.yml
│ │ │ ├── run-mirror-tests.yml
│ │ │ ├── run-search-tests.yml
│ │ │ ├── run-system-tests.yml
│ │ │ ├── run-web-tests.yml
│ │ │ ├── solr
│ │ │ │ └── solr-configuration-tests.yml
│ │ │ ├── system
│ │ │ │ ├── git-tests.yml
│ │ │ │ ├── ssh-keys-tests.yml
│ │ │ │ └── system-setup-tests.yml
│ │ │ └── tools
│ │ │ │ ├── coder-tests.yml
│ │ │ │ ├── codesniffer-tests.yml
│ │ │ │ ├── composer-tests.yml
│ │ │ │ ├── drupal-console-tests.yml
│ │ │ │ ├── drush-tests.yml
│ │ │ │ ├── mcstat-tests.yml
│ │ │ │ ├── phantomjs-tests.yml
│ │ │ │ ├── php-cs-fixer-tests.yml
│ │ │ │ ├── phpmd-tests.yml
│ │ │ │ ├── tideways-tests.yml
│ │ │ │ └── xdebug-tests.yml
│ │ ├── search-tests.yml
│ │ ├── system-tests.yml
│ │ └── web-tests.yml
│ ├── commands
│ │ ├── app-blt.yml
│ │ ├── app-delete.yml
│ │ ├── app-dev.yml
│ │ ├── app-drupal.yml
│ │ ├── app-import.yml
│ │ ├── app-lightning.yml
│ │ ├── app-prod.yml
│ │ ├── default-php.yml
│ │ ├── legacy-php.yml
│ │ └── previous-php.yml
│ ├── files
│ │ ├── .bash_aliases
│ │ ├── .git-completion.bash
│ │ ├── .git-prompt.sh
│ │ ├── .gitconfig
│ │ ├── .gitignore
│ │ ├── .gitignore-global
│ │ ├── README-import.txt
│ │ ├── apache-template.conf
│ │ ├── apt.conf
│ │ ├── composer-dev-template.json
│ │ ├── composer-template.json
│ │ ├── composer.json
│ │ ├── db-backup.sh
│ │ ├── default.vcl
│ │ ├── drush.site.yml
│ │ ├── drush.yml
│ │ ├── nginx-template.conf
│ │ ├── phpstan.neon
│ │ ├── solr-conf-7.x
│ │ │ ├── elevate.xml
│ │ │ ├── mapping-ISOLatin1Accent.txt
│ │ │ ├── protwords.txt
│ │ │ ├── schema.xml
│ │ │ ├── schema_extra_fields.xml
│ │ │ ├── schema_extra_types.xml
│ │ │ ├── solrconfig.xml
│ │ │ ├── solrconfig_extra.xml
│ │ │ ├── solrconfig_spellcheck.xml
│ │ │ ├── solrcore.properties
│ │ │ ├── stopwords.txt
│ │ │ └── synonyms.txt
│ │ ├── sources.list
│ │ ├── ssl
│ │ │ ├── nginx.crt
│ │ │ └── nginx.key
│ │ └── varnish
│ ├── handlers.yml
│ ├── hosts
│ ├── plays
│ │ ├── app
│ │ │ ├── blt.yml
│ │ │ ├── delete.yml
│ │ │ ├── dev.yml
│ │ │ ├── drupal.yml
│ │ │ ├── import.yml
│ │ │ ├── lightning.yml
│ │ │ └── prod.yml
│ │ ├── common
│ │ │ ├── apache-installation.yml
│ │ │ ├── apache-vhost-fcgi.yml
│ │ │ ├── apache-vhost.yml
│ │ │ ├── app-registry.yml
│ │ │ ├── apt-repos.yml
│ │ │ ├── apt-update.yml
│ │ │ ├── database.yml
│ │ │ ├── drucker-config.yml
│ │ │ ├── drupal-common.yml
│ │ │ ├── drush-aliases.yml
│ │ │ ├── mirror-deploy.yml
│ │ │ ├── mirror-downloads.yml
│ │ │ └── permissions.yml
│ │ ├── db
│ │ │ ├── adminer.yml
│ │ │ ├── db-tools.yml
│ │ │ ├── memcached.yml
│ │ │ ├── mysql-backup.yml
│ │ │ ├── mysql.yml
│ │ │ └── phpmyadmin.yml
│ │ ├── drupal
│ │ │ ├── drupal-create.yml
│ │ │ ├── drupal-tools.yml
│ │ │ └── drupal.yml
│ │ ├── edge
│ │ │ ├── nginx.yml
│ │ │ └── varnish.yml
│ │ ├── mirror
│ │ │ ├── mirror-setup.yml
│ │ │ └── mirror-vhost.yml
│ │ ├── php
│ │ │ ├── default-php.yml
│ │ │ ├── default_php_ini.yml
│ │ │ ├── legacy-php.yml
│ │ │ ├── legacy_php_ini.yml
│ │ │ ├── libyaml.yml
│ │ │ ├── pecl-yaml.yml
│ │ │ ├── php.yml
│ │ │ ├── php_version_and_vhost_check.yml
│ │ │ ├── phpfpm_process_check.yml
│ │ │ ├── previous-php.yml
│ │ │ └── previous_php_ini.yml
│ │ ├── post-install.yml
│ │ ├── solr
│ │ │ ├── java.yml
│ │ │ └── solr.yml
│ │ ├── stack.yml
│ │ ├── system
│ │ │ ├── git.yml
│ │ │ ├── ssh-keys.yml
│ │ │ ├── ssh.yml
│ │ │ └── system-setup.yml
│ │ └── tools
│ │ │ ├── coder.yml
│ │ │ ├── codesniffer.yml
│ │ │ ├── composer.yml
│ │ │ ├── drupal-console.yml
│ │ │ ├── drush.yml
│ │ │ ├── mcstat.yml
│ │ │ ├── phantomjs.yml
│ │ │ ├── php-cs-fixer.yml
│ │ │ ├── phpmd.yml
│ │ │ ├── sass.yml
│ │ │ ├── tideways.yml
│ │ │ └── xdebug.yml
│ ├── provisioning
│ │ ├── base.yml
│ │ ├── db.yml
│ │ ├── edge.yml
│ │ ├── mirror.yml
│ │ ├── search.yml
│ │ ├── ssh.yml
│ │ └── web.yml
│ └── vars.yml
├── requirements.py
├── requirements.txt
├── search.py
├── services.py
├── ssh.py
├── variables.py
└── web.py
├── config
├── drucker
├── drucker-logo.png
└── util
├── drucker-screencast.sh
└── var_usage.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore Ansible files.
2 | *.retry
3 |
4 | # Ignore drucker's custom config file.
5 | config
6 |
7 | # Ignore Python cache files.
8 | __pycache__
9 | *.pyc
10 |
11 | # Ignore Mac OS files
12 | .DS_Store
13 | .AppleDouble
14 | .LSOverride
15 | .Spotlight-V100
16 | .Trashes
17 |
18 | # Ignore Windows files
19 | ._*
20 | Thumbs.db
21 | ehthumbs.db
22 | Desktop.ini
23 | $RECYCLE.BIN/
24 |
25 | ####################### IDEs #######################
26 | .vscode/settings.json
27 |
28 | # Eclipse
29 | *.pydevproject
30 | .project
31 | .metadata
32 | tmp/**
33 | tmp/**/*
34 | *.tmp
35 | *.bak
36 | *.swp
37 | *~.nib
38 | local.properties
39 | .classpath
40 | .settings/
41 | .loadpath
42 | *.launch
43 |
44 | # CDT-specific
45 | .cproject
46 |
47 | # PDT-specific
48 | .buildpathk
49 |
50 | # Emacs
51 | *~
52 | \#*\#
53 | /.emacs.desktop
54 | /.emacs.desktop.lock
55 | *.elc
56 | auto-save-list
57 | tramp
58 | .\#*
59 |
60 | #Netbeans IDE
61 | nbproject
62 | nbproject/*
63 |
64 | # PHPStorm
65 | .idea/
66 | atlassian-ide-plugin.xml
67 | ####################### END IDEs #######################
68 |
69 | # Exports
70 | *.gz
71 | *.sql
72 | *.zip
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 | python: 3.6
3 | dist: trusty
4 | sudo: required
5 |
6 | script: ./.travis/test_$t.py $a
7 |
8 | matrix:
9 | fast_finish: true
10 | include:
11 | - env: t=python_pep8_compliancy
12 | install: pip install pycodestyle pylint click
13 |
--------------------------------------------------------------------------------
/.travis/flow.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """Test, output and flow-control helpers."""
3 | import os
4 | import sys
5 |
6 |
7 | def banner(caller, subtext=None, char='#'):
8 | """Print the head-banner for a test-script."""
9 | caller = os.path.basename(caller)
10 | caller = os.path.splitext(caller)[0].lstrip('test_').upper()
11 | if subtext and "\n" in subtext:
12 | caller = "%s:\n%s" % (caller, subtext)
13 | elif subtext:
14 | caller = "%s - %s" % (caller, subtext)
15 | hbreak(0)
16 | hbox(caller, char=char)
17 | hbreak(0)
18 |
19 |
20 | def exit_error(msg="Exiting..."):
21 | """Exit the script in ERROR state with a positive status code."""
22 | exit_as(1, 'error', msg=msg)
23 |
24 |
25 | def exit_info(msg="Exiting..."):
26 | """Exit the script in INFO state with a positive status code."""
27 | exit_as(0, 'info', msg=msg)
28 |
29 |
30 | def exit_failed(msg="Exiting..."):
31 | """Exit the script in FAILED state with a positive status code."""
32 | exit_as(1, 'failed', msg=msg)
33 |
34 |
35 | def exit_passed(msg="Exiting..."):
36 | """Exit the script in PASSED state with a zero status code."""
37 | exit_as(0, 'passed', msg=msg)
38 |
39 |
40 | def exit_as(scode, sstring, msg=False, char='#'):
41 | """Exit the script as specified."""
42 | if msg is False:
43 | sys.exit(scode)
44 | # Update the status string and decorative character.
45 | sstring = sstring.upper()
46 | if scode:
47 | char = '!'
48 | # Start rendering the output.
49 | hbreak()
50 | hline(char=char)
51 | if msg is None:
52 | hline(sstring, char=char)
53 | elif '\n' in msg:
54 | hline("%s:\n%s" % (sstring, msg), char=char)
55 | else:
56 | hline("%s - %s" % (sstring, msg), char=char)
57 | hline(char=char)
58 | sys.exit(scode)
59 |
60 |
61 | def hbox(text, char='.'):
62 | """Print a horizontal box with text."""
63 | hline(char=char)
64 | hline(text, char=char)
65 | hline(char=char)
66 |
67 |
68 | def hbreak(lines=1):
69 | """Print newlines (two by default, just one with lines=0)."""
70 | print(lines * "\n")
71 |
72 |
73 | def hline(text='', mlen=95, char='-', lchar=None, rchar=None):
74 | """Print a horizontal line (with optional text)."""
75 | if not lchar:
76 | lchar = char
77 | if not rchar:
78 | rchar = char
79 | for index, line in enumerate(text.split('\n')):
80 | if line:
81 | line = ' ' + line + ' '
82 | if index == 0:
83 | line_right = (mlen-2-len(line)) * rchar
84 | else:
85 | line_right = ((mlen-4-len(line)) * ' ') + rchar + rchar
86 | print(lchar + lchar + line + line_right)
87 |
--------------------------------------------------------------------------------
/.travis/test_python_pep8_compliancy.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | """Tests the PEP8 compliancy of all Python code."""
4 | import subprocess
5 | import flow
6 |
7 |
8 | def _test_pep8(args):
9 | """Shell wrapper for Pylint/Pycodestyle calls."""
10 | flow.hline("%s (%s)" % (args[1], args[0]))
11 | cmd = " ".join(args)
12 | proc = subprocess.run(cmd,
13 | stdout=subprocess.PIPE,
14 | stderr=subprocess.STDOUT,
15 | shell=True)
16 | proc_output = proc.stdout.decode("utf-8") + "\n"
17 | if proc.returncode == 127:
18 | print("Binary %s not found!" % args[0])
19 | return False
20 | if args[0] == 'pylint':
21 | if proc.returncode != 0:
22 | print("cmd: %s (exit status: %d)\n" % (cmd, proc.returncode))
23 | print(proc_output)
24 |
25 | # Scan and report pylint ignore tags.
26 | ignores = subprocess.run(
27 | "grep -r 'pylint:disable' %s|grep -v grep" % args[1],
28 | stdout=subprocess.PIPE,
29 | stderr=subprocess.DEVNULL,
30 | shell=True)
31 | ignores = ignores.stdout.decode("utf-8").strip()
32 | if ignores:
33 | flow.hline("Code-level linter ignores", char=".")
34 | print(ignores)
35 | return False
36 | else:
37 | if proc.returncode == 1:
38 | print("cmd: %s (exit status: %d)\n" % (cmd, proc.returncode))
39 | print(proc_output)
40 | return False
41 | return True
42 |
43 |
44 | if __name__ == '__main__':
45 | flow.banner(__file__)
46 | TESTS = []
47 | TESTS.append(
48 | _test_pep8(["pycodestyle",
49 | ".travis/",
50 | "--show-source"]))
51 | TESTS.append(
52 | _test_pep8(["pylint",
53 | ".travis/*.py",
54 | "--disable=duplicate-code",
55 | "--disable=no-value-for-parameter"]))
56 | TESTS.append(
57 | _test_pep8(["pycodestyle",
58 | "app",
59 | "--show-source",
60 | "--max-line-length=300"]))
61 | TESTS.append(
62 | _test_pep8(["pylint",
63 | "app",
64 | "--disable=line-too-long"]))
65 | if False in TESTS:
66 | flow.exit_failed(msg="Please fix the reported codestyle issues.")
67 | flow.exit_passed(msg="All code is PEP8 compliant!")
68 |
--------------------------------------------------------------------------------
/app/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM debian:stretch
2 |
3 | ARG DEBIAN_FRONTEND=noninteractive
4 | ARG USER=drucker
5 | ARG SSH=/home/"$USER"/.ssh
6 |
7 | VOLUME ["/data"]
8 |
9 | # Ensure we're up-to-date.
10 | RUN apt-get update -y && apt-get upgrade -y
11 |
12 | # Make sure dpkg works as intended.
13 | RUN apt-get install -y apt-utils
14 |
15 | # Packages needed for Ansible orchestration.
16 | RUN apt-get install -y \
17 | ssh \
18 | python-simplejson \
19 | unzip \
20 | sudo \
21 | vim
22 |
23 | # Create a drucker sudoer.
24 | RUN adduser -q --disabled-password --gecos '' "$USER" \
25 | && usermod -aG sudo "$USER"
26 | RUN echo "$USER":"$USER" | chpasswd
27 |
28 | # Prepare for SSH access
29 | RUN mkdir -p "$SSH"
30 | ENTRYPOINT service ssh restart && bash
31 |
--------------------------------------------------------------------------------
/app/__init__.py:
--------------------------------------------------------------------------------
1 | """Initialization file for the drucker support library."""
2 | from . import variables
3 | from . import arguments
4 | from . import requirements
5 | from . import local_setup
6 | from . import init
7 | from . import base
8 | from . import mirror
9 | from . import edge
10 | from . import db
11 | from . import search
12 | from . import web
13 |
14 | # Declare all submodules so that pydoc and others know how to find them.
15 | __all__ = [
16 | "variables",
17 | "arguments",
18 | "requirements",
19 | "local_setup",
20 | "init",
21 | "base",
22 | "mirror",
23 | "edge",
24 | "db",
25 | "search",
26 | "web",
27 | ]
28 |
--------------------------------------------------------------------------------
/app/ansible.cfg:
--------------------------------------------------------------------------------
1 | [defaults]
2 | retry_files_enabled = False
3 | allow_world_readable_tmpfiles = True
4 |
5 | [inventory]
6 |
7 | [privilege_escalation]
8 |
9 | [paramiko_connection]
10 |
11 | [ssh_connection]
12 | pipelining = True
13 |
14 | [persistent_connection]
15 |
16 | [accelerate]
17 |
18 | [selinux]
19 |
20 | [colors]
21 |
22 | [diff]
23 |
--------------------------------------------------------------------------------
/app/base.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """Manages the base image and container"""
3 |
4 | from datetime import date
5 | import subprocess
6 | import colorful
7 | from . import ssh
8 | from . import orchestration as o
9 |
10 |
11 | def create_base_container(drucker):
12 | """Create base container from init image"""
13 | print(
14 | colorful.white_on_blue(
15 | "Spinning up %s container with ID:" % (drucker.vars.BASE_CONTAINER)
16 | )
17 | )
18 | subprocess.run(
19 | "docker run -d --name %s -it --net %s --ip %s %s bash"
20 | % (
21 | drucker.vars.BASE_CONTAINER,
22 | drucker.vars.APP,
23 | drucker.vars.BASE_IP,
24 | drucker.vars.INIT_IMAGE,
25 | ),
26 | shell=True,
27 | )
28 |
29 | ssh.configure_ssh_base(drucker)
30 | o.run_base_orchestration(drucker)
31 |
32 |
33 | def create_base_image(drucker):
34 | """Create base image from base container"""
35 | print(
36 | colorful.white_on_blue(
37 | "Committing %s image from %s container..."
38 | % (drucker.vars.BASE_IMAGE, drucker.vars.BASE_CONTAINER)
39 | )
40 | )
41 | subprocess.run(
42 | 'docker commit -m "%s on %s" %s %s'
43 | % (
44 | drucker.vars.BASE_CONTAINER,
45 | str(date.today()),
46 | drucker.vars.BASE_CONTAINER,
47 | drucker.vars.BASE_IMAGE,
48 | ),
49 | shell=True,
50 | )
51 |
52 |
53 | def delete_base_container(drucker):
54 | """Delete base container"""
55 | print(
56 | colorful.white_on_blue(
57 | "Deleting %s container..." % (drucker.vars.BASE_CONTAINER)
58 | )
59 | )
60 | subprocess.getoutput(
61 | "docker rm -f %s > /dev/null 2>&1" % (drucker.vars.BASE_CONTAINER)
62 | )
63 |
64 |
65 | def delete_init_image(drucker):
66 | """Delete init image"""
67 | print(colorful.white_on_blue("Deleting %s image..." % (drucker.vars.INIT_IMAGE)))
68 | subprocess.getoutput("docker rmi %s > /dev/null 2>&1" % (drucker.vars.INIT_IMAGE))
69 |
70 |
71 | def provision_base_container(drucker):
72 | """Set up base container from init image"""
73 | if subprocess.getoutput(drucker.vars.CHECK_BASE_IMAGE):
74 | print(colorful.green("%s image already exists." % (drucker.vars.BASE_IMAGE)))
75 |
76 | if subprocess.getoutput(drucker.vars.CHECK_INIT_IMAGE):
77 | delete_init_image(drucker)
78 | else:
79 | if subprocess.getoutput(
80 | 'docker ps -a | grep -o "%s"' % (drucker.vars.BASE_CONTAINER)
81 | ):
82 | delete_base_container(drucker)
83 | else:
84 | create_base_container(drucker)
85 | create_base_image(drucker)
86 | delete_base_container(drucker)
87 | delete_init_image(drucker)
88 |
89 |
90 | def main(drucker):
91 | """Main dispatcher called by the main drucker script."""
92 | provision_base_container(drucker)
93 |
--------------------------------------------------------------------------------
/app/init.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """Initialize app with Docker networking and init image"""
3 |
4 | import subprocess
5 | import colorful
6 |
7 |
8 | def create_bridge_network(drucker):
9 | """Creates a custom bridge network"""
10 | if subprocess.getoutput(drucker.vars.CHECK_BRIDGE):
11 | print(
12 | colorful.green(
13 | "Custom %s bridge network already exists." % (drucker.vars.APP)
14 | )
15 | )
16 | else:
17 | print(
18 | colorful.white_on_blue(
19 | "Creating custom %s bridge network..." % (drucker.vars.APP)
20 | )
21 | )
22 | subprocess.getoutput(drucker.vars.CREATE_BRIDGE)
23 |
24 |
25 | def pull_base_image(drucker):
26 | """Pulls and updates the preferred distribution image from the Docker Hub"""
27 | distro_image_exists = subprocess.getoutput(drucker.vars.CHECK_DISTRO_IMAGE)
28 | base_image_exists = subprocess.getoutput(drucker.vars.CHECK_BASE_IMAGE)
29 |
30 | if distro_image_exists and not base_image_exists:
31 | print(colorful.green("%s image already exists" % (drucker.vars.DISTRO_IMAGE)))
32 | print(
33 | colorful.white_on_blue(
34 | "Check if %s can be updated..." % (drucker.vars.DISTRO_IMAGE)
35 | )
36 | )
37 | subprocess.run(drucker.vars.UPDATE_DISTRO_IMAGE, shell=True)
38 | elif not distro_image_exists:
39 | print(
40 | colorful.white_on_blue(
41 | "Pulling %s image from Docker Hub..." % (drucker.vars.DISTRO_IMAGE)
42 | )
43 | )
44 | subprocess.run(drucker.vars.PULL_DISTRO_IMAGE, shell=True)
45 |
46 |
47 | def build_init_image(drucker):
48 | """Builds the init image from Dockerfile"""
49 | if subprocess.getoutput(drucker.vars.CHECK_INIT_IMAGE):
50 | print(colorful.green("%s image already exists." % (drucker.vars.INIT_IMAGE)))
51 | elif not subprocess.getoutput(drucker.vars.CHECK_BASE_IMAGE):
52 | print(
53 | colorful.white_on_blue(
54 | "Building %s image from Dockerfile..." % (drucker.vars.INIT_IMAGE)
55 | )
56 | )
57 | subprocess.run(
58 | 'docker build -t "%s" %s' % (drucker.vars.INIT_IMAGE, drucker.vars.APP_DIR),
59 | shell=True,
60 | )
61 |
62 |
63 | def main(drucker):
64 | """Main dispatcher called by the main drucker script."""
65 | create_bridge_network(drucker)
66 | pull_base_image(drucker)
67 | build_init_image(drucker)
68 |
--------------------------------------------------------------------------------
/app/local_setup.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """Edit the config file to accommodate for local user preferences"""
3 |
4 | import os
5 | import colorful
6 |
7 |
8 | def replace_string(file, old_string, new_string):
9 | """Allows to easily replace a string in a file"""
10 | with open(file) as target:
11 | replacement = target.read().replace(old_string, new_string)
12 | with open(file, "w") as target:
13 | target.write(replacement)
14 |
15 |
16 | def set_local_ssh_path(drucker):
17 | """Write the SSH public key path to the config file"""
18 | if drucker.vars.KEY_PLACEHOLDER in open(drucker.vars.DEFAULT_CONFIG).read():
19 | pubkey = input(
20 | "Enter path to SSH public key (%s): " % (drucker.vars.DEFAULT_PUBKEY)
21 | )
22 |
23 | if not pubkey:
24 | replace_string(
25 | drucker.vars.DEFAULT_CONFIG,
26 | drucker.vars.KEY_PLACEHOLDER,
27 | drucker.vars.DEFAULT_PUBKEY,
28 | )
29 | elif os.path.isfile(pubkey):
30 | replace_string(
31 | drucker.vars.DEFAULT_CONFIG, drucker.vars.KEY_PLACEHOLDER, pubkey
32 | )
33 | else:
34 | print(colorful.red("This filepath doesn't exist. Please try again."))
35 | set_local_ssh_path(drucker)
36 |
37 |
38 | def set_local_html_path(drucker):
39 | """Write the local HTML path to the config file"""
40 | if drucker.vars.HTML_PLACEHOLDER in open(drucker.vars.DEFAULT_CONFIG).read():
41 | host_html_path = input(
42 | """
43 | Where should we store sites locally? (%s): """
44 | % (drucker.vars.DEFAULT_HTML_PATH)
45 | )
46 |
47 | if not host_html_path:
48 | replace_string(
49 | drucker.vars.DEFAULT_CONFIG,
50 | drucker.vars.HTML_PLACEHOLDER,
51 | drucker.vars.DEFAULT_HTML_PATH,
52 | )
53 | elif os.path.isfile(host_html_path):
54 | replace_string(
55 | drucker.vars.DEFAULT_CONFIG,
56 | drucker.vars.HTML_PLACEHOLDER,
57 | host_html_path,
58 | )
59 | else:
60 | print(colorful.red("This filepath doesn't exist. Please try again."))
61 | set_local_html_path(drucker)
62 |
63 |
64 | def set_local_db_path(drucker):
65 | """Write the local DB path to the config file"""
66 | if drucker.vars.DB_PLACEHOLDER in open(drucker.vars.DEFAULT_CONFIG).read():
67 | host_db_path = input(
68 | """
69 | Where should we store databases locally? (%s): """
70 | % (drucker.vars.DEFAULT_DB_PATH)
71 | )
72 |
73 | if not host_db_path:
74 | replace_string(
75 | drucker.vars.DEFAULT_CONFIG,
76 | drucker.vars.DB_PLACEHOLDER,
77 | drucker.vars.DEFAULT_DB_PATH,
78 | )
79 | elif os.path.isfile(host_db_path):
80 | replace_string(
81 | drucker.vars.DEFAULT_CONFIG, drucker.vars.DB_PLACEHOLDER, host_db_path
82 | )
83 | else:
84 | print(colorful.red("This filepath doesn't exist. Please try again."))
85 | set_local_db_path(drucker)
86 |
87 |
88 | def main(drucker):
89 | """Main dispatcher called by the main drucker script."""
90 | set_local_ssh_path(drucker)
91 | set_local_html_path(drucker)
92 | set_local_db_path(drucker)
93 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/db-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Invoked via run_tests() in containers/orchestration.
3 | - hosts: drucker_db
4 | become: yes
5 |
6 | gather_facts: yes
7 | vars_files:
8 | - ../vars.yml
9 | handlers:
10 | - import_tasks: ../handlers.yml
11 | tasks:
12 | - import_tasks: plays/run-db-tests.yml
13 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/edge-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Invoked via run_tests() in containers/orchestration.
3 | - hosts: drucker_edge
4 | become: yes
5 |
6 | gather_facts: yes
7 | vars_files:
8 | - ../vars.yml
9 | handlers:
10 | - import_tasks: ../handlers.yml
11 | tasks:
12 | - import_tasks: plays/run-edge-tests.yml
13 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/mirror-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Invoked via run_tests() in containers/orchestration.
3 | - hosts: drucker_mirror
4 | become: yes
5 |
6 | gather_facts: yes
7 | vars_files:
8 | - ../vars.yml
9 | handlers:
10 | - import_tasks: ../handlers.yml
11 | tasks:
12 | - import_tasks: plays/run-mirror-tests.yml
13 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/db/adminer-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: Adminer needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ adminer_root }}"
7 | - "{{ adminer_index }}"
8 | - "{{ adminer_vhost }}"
9 | register: adminer
10 | failed_when: adminer.stat.exists == false
11 |
12 | - name: "TEST: Adminer should be at the latest version"
13 | shell: grep -o "version {{ adminer_stable_release }}" {{ adminer_index }} || echo "update"
14 | register: adminer_release
15 | changed_when: adminer_release == "update"
16 | failed_when: adminer_release == "update"
17 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/db/db-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: MariaDB and utilities need to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ db_config }}"
7 | - "{{ db_data }}"
8 | - "{{ db_backup_path }}"
9 | register: mariadb_check
10 | failed_when: mariadb_check.stat.exists == false
11 |
12 | - name: "TEST: Check if MariaDB and utilities packages are installed"
13 | shell: dpkg -l | grep {{ item }}
14 | with_items:
15 | - mariadb-server
16 | - mysql-common
17 | - python-mysqldb
18 | - memcached
19 | register: mariadb_packages
20 | changed_when: mariadb_packages == ''
21 |
22 | - name: "TEST: Check if MariaDB innodb_file_per_table setting is configured"
23 | shell: grep -o "innodb_file_per_table = 1" {{ db_config }} || echo "missing"
24 | register: mariadb_innodb_setting
25 | changed_when: mariadb_innodb_setting.stdout == "missing"
26 | failed_when: mariadb_innodb_setting.stdout == "missing"
27 |
28 | - set_fact:
29 | db_dir_expected_ownership: "mysql:mysql"
30 |
31 | - name: "TEST: The database directory should have correct ownership"
32 | shell: stat -c %U:%G {{ db_data }}
33 | register: db_dir_ownership
34 | changed_when: db_dir_ownership.stdout != db_dir_expected_ownership
35 | failed_when: db_dir_ownership.stdout != db_dir_expected_ownership
36 |
37 | - name: "TEST: Check if MariaDB backup cron job exists"
38 | shell: crontab -l | grep -o "{{ db_backup_path }}" || echo "missing"
39 | register: mariadb_backup_cron
40 | changed_when: mariadb_backup_cron.stdout == "missing"
41 | failed_when: mariadb_backup_cron.stdout == "missing"
42 |
43 | - name: "TEST: Check if MariaDB backup cleanup cron job exists"
44 | shell: crontab -l | grep -o "mmin +180" || echo "missing"
45 | register: mariadb_cleanup_cron
46 | changed_when: mariadb_cleanup_cron.stdout == "missing"
47 | failed_when: mariadb_cleanup_cron.stdout == "missing"
48 |
49 | - name: "TEST: Check if MariaDB remote access is configured"
50 | shell: grep -o "0.0.0.0" {{ db_config }} || echo "denied"
51 | register: mariadb_remote_access
52 | changed_when: mariadb_remote_access.stdout == "denied"
53 | failed_when: mariadb_remote_access.stdout == "denied"
54 |
55 | - name: "TEST: MariaDB process needs to be started"
56 | command: pgrep mysqld
57 | register: mariadb_process
58 | changed_when: mariadb_process.stdout == ""
59 | failed_when: mariadb_process.stdout == ""
60 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/db/memcached-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: Check if memcached is installed"
3 | shell: dpkg -l | grep {{ item }}
4 | with_items:
5 | - memcached
6 | register: memcached_package
7 | changed_when: memcached_package == ''
8 |
9 | - name: "TEST: memcached process needs to be started"
10 | command: pgrep memcached
11 | register: memcached_process
12 | changed_when: memcached_process.stdout == ""
13 | failed_when: memcached_process.stdout == ""
14 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/db/phpmyadmin-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: phpMyAdmin needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ phpmyadmin_vhost }}"
7 | - "{{ phpmyadmin_config }}"
8 | - "{{ phpmyadmin_release_date_file }}"
9 | register: pma
10 | failed_when: pma.stat.exists == false
11 |
12 | - name: "TEST: phpMyAdmin should use the latest stable release"
13 | stat:
14 | path: "{{ phpmyadmin_release_date_file }}"
15 | register: pma_version
16 | failed_when: pma_version.stat.exists == false
17 |
18 | - name: "TEST: The mariadb client should be installed"
19 | shell: dpkg -l | grep mariadb-client
20 | register: mariadb_client_package
21 | changed_when: mariadb_client_package == ''
22 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/drupal/drupal-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: Drupal needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ drupal_root }}"
7 | - "{{ drupal_docroot }}/{{ default_site }}/settings.php"
8 | - "{{ drupal_docroot }}/{{ default_site }}/services.yml"
9 | - "{{ drupal_docroot }}/{{ sites_php }}"
10 | - "{{ drupal_root }}/{{ default_configuration_dir }}"
11 | - "{{ drupal_docroot }}"
12 | - "{{ files_dir }}"
13 | - "{{ libraries_dir }}"
14 | - "{{ settings_php }}"
15 | - "{{ services_yml }}"
16 | - "{{ simpletest_dir }}"
17 | - "{{ drupal_git }}"
18 | - "{{ drupal_gitignore }}"
19 | # - "{{ db_data }}/{{ user }}"
20 | - "{{ phpunit_xml }}"
21 | - "{{ import_dir }}"
22 | - "{{ archives_dir }}"
23 | - "{{ log_dir }}/{{ user }}-access.log"
24 | - "{{ log_dir }}/{{ user }}-error.log"
25 | register: drupal
26 | failed_when: drupal.stat.exists == false
27 |
28 | - name: "TEST: The config directory should have correct permissions"
29 | shell: stat -c -%a {{ drupal_root }}/{{ default_configuration_dir }} | tail -c5
30 | register: config_permissions
31 | changed_when: config_permissions.stdout != "2775"
32 | failed_when: config_permissions.stdout != "2775"
33 |
34 | - name: "TEST: settings.php should hold the correct trusted_host_patterns setting"
35 | shell: grep -F "{{ user }}\.{{ tld }}" {{ settings_php }} || echo "missing"
36 | register: trusted_host_patterns
37 | changed_when: trusted_host_patterns.stdout == "missing"
38 | failed_when: trusted_host_patterns.stdout == "missing"
39 |
40 | - set_fact:
41 | expected_ownership: "{{ user }}:{{ apache_user }}"
42 |
43 | - name: "TEST: The styles directory should have correct ownership"
44 | shell: stat -c %U:%G {{ files_dir }}/styles
45 | register: styles_dir_ownership
46 | changed_when: styles_dir_ownership.stdout != expected_ownership
47 | failed_when: styles_dir_ownership.stdout != expected_ownership
48 |
49 | - name: "TEST: Make sure the codebase was added under version control"
50 | shell: git -C {{ drupal_root }} log --oneline | grep -o "Initial commit" || echo 'no commit'
51 | args:
52 | warn: no
53 | register: initial_commit
54 | changed_when: initial_commit == "no commit"
55 | failed_when: initial_commit == "no commit"
56 |
57 | - name: "TEST: Ensure remote MySQL databases can be managed"
58 | shell: dpkg -l | grep "python-mysqldb"
59 | register: remote_db_management
60 | changed_when: remote_db_management == ''
61 |
62 | - name: "TEST: Ensure Drupal can talk to the Solr backend"
63 | shell: grep -o "{{ search_ip }}" {{ hosts_file }} || echo "absent"
64 | register: search_hostname_check
65 | changed_when: search_hostname_check == "absent"
66 | failed_when: search_hostname_check == "absent"
67 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/edge/mirror-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: APT mirror needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ mirror_cache_dir }}"
7 | - "{{ mirror_log_dir }}"
8 | register: mirror_installation
9 | failed_when: mirror_installation.stat.exists == false
10 |
11 | - name: "TEST: APT mirror web interface should be accessible"
12 | uri:
13 | url: "http://mirror.{{ tld }}:3142"
14 | status_code: 406
15 |
16 | - name: "TEST: Archives, directories and files should be accessible"
17 | stat:
18 | path: "{{ item }}"
19 | with_items:
20 | - "{{ mirror_archives_dir }}"
21 | - "{{ solr_mirror_archive_path }}"
22 | - "{{ libyaml_mirror_archive_path }}"
23 | - "{{ pecl_yaml_mirror_archive_path }}"
24 | - "{{ xdebug_mirror_archive_path }}"
25 | - "{{ tideways_mirror_archive_path }}"
26 | - "{{ phantomjs_mirror_archive_path }}"
27 | - "{{ phpcs_mirror_archive_path }}"
28 | - "{{ phpcbf_mirror_archive_path }}"
29 | - "{{ php_cs_fixer_mirror_archive_file }}"
30 | # - "{{ phpmd_mirror_archive_file }}"
31 | - "{{ mcstat_mirror_archive_file }}"
32 | - "{{ phpmyadmin_mirror_archive_file_path }}"
33 | - "{{ adminer_mirror_filepath }}"
34 | register: archive_elements
35 | failed_when: archive_elements.stat.exists == false
36 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/edge/nginx-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: nginx signing key should be installed"
3 | shell: apt-key list | grep -o "nginx signing key" || echo "no signing key"
4 | register: nginx_key
5 | changed_when: nginx_key == "no signing key"
6 | failed_when: nginx_key == "no signing key"
7 |
8 | - name: "TEST: nginx needs to be correctly installed"
9 | stat:
10 | path: "{{ item }}"
11 | with_items:
12 | - "{{ nginx_conf }}"
13 | - "{{ drucker_nginx_vhost }}"
14 | - "{{ nginx_conf_dir }}"
15 | register: nginx
16 | failed_when: nginx.stat.exists == false
17 |
18 | - name: "TEST: nginx default files should not exist"
19 | stat:
20 | path: "{{ item }}"
21 | with_items:
22 | - "{{ nginx_default_site }}"
23 | - "{{ nginx_default_conf }}"
24 | register: nginx_default_files
25 | failed_when: nginx_default_files.stat.exists == true
26 |
27 | - name: "TEST: Check if nginx package is installed"
28 | shell: dpkg -l | grep nginx
29 | register: nginx_package
30 | changed_when: nginx_package == ''
31 |
32 | - name: "TEST: nginx proxy_pass should be set"
33 | shell: grep -o "proxy_pass http://{{ web_ip }}:{{ edge_port }}" "{{ drucker_nginx_vhost }}" || echo "missing"
34 | register: nginx_proxy_pass
35 | changed_when: nginx_proxy_pass.stdout == "missing"
36 | failed_when: nginx_proxy_pass.stdout == "missing"
37 |
38 | - name: "TEST: nginx process needs to be started"
39 | command: pgrep nginx
40 | register: nginx_process
41 | changed_when: nginx_process.stdout == ""
42 | failed_when: nginx_process.stdout == ""
43 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/edge/varnish-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: Varnish needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ varnish_config }}"
7 | - "{{ varnish_default_path }}"
8 | - "{{ varnish_default_vcl }}"
9 | register: varnish
10 | failed_when: varnish.stat.exists == false
11 |
12 | - name: "TEST: Check if Varnish package is installed"
13 | shell: dpkg -l | grep {{ item }}
14 | with_items:
15 | - varnish
16 | register: varnish_packages
17 | changed_when: varnish_packages == ''
18 |
19 | - name: "TEST: Varnish should listen on port 80"
20 | shell: grep -o "{{ edge_port }}" {{ varnish_config }} || || echo "wrong port"
21 | register: varnish_port_check
22 | changed_when: varnish_port_check.stdout == "wrong port"
23 | failed_when: varnish_port_check.stdout == "wrong port"
24 |
25 | - name: "TEST: Varnish process needs to be started"
26 | command: pgrep varnishd
27 | register: varnishd_process
28 | changed_when: varnishd_process.stdout == ""
29 | failed_when: varnishd_process.stdout == ""
30 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/php/apache-common-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: Apache needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ apache_security_conf }}"
7 | - "{{ apache_actions_mod }}"
8 | - "{{ apache_rewrite_mod }}"
9 | - "{{ apache_proxy_http_mod }}"
10 | register: apache
11 | failed_when: apache.stat.exists == false
12 |
13 | - name: "TEST: The POODLE SSL v3 vulnerability should be fixed"
14 | shell: grep -o "SSLProtocol all -SSLv2 -SSLv3" {{ apache_ssl_mod }} || echo "absent"
15 | register: poodle
16 | changed_when: poodle.stdout == "absent"
17 | failed_when: poodle.stdout == "absent"
18 |
19 | - name: "TEST: apache2 process needs to be started"
20 | command: pgrep apache2
21 | register: apache2_process
22 | changed_when: apache2_process.stdout == ""
23 | failed_when: apache2_process.stdout == ""
24 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/php/apache-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - import_tasks: apache-common-tests.yml
3 |
4 | - name: "TEST: Check if Apache and web tools are installed"
5 | shell: dpkg -l | grep {{ item }}
6 | with_items:
7 | - apache2
8 | - apache2-utils
9 | - goaccess
10 | register: apache_packages
11 | changed_when: apache_packages == ''
12 |
13 | - name: "TEST: APACHE_RUN_USER should be set"
14 | shell: grep -o "export APACHE_RUN_USER={{ user }}" {{ apache_envvars }} || echo "absent"
15 | register: apache_run_user
16 | changed_when: apache_run_user.stdout == "absent"
17 | failed_when: apache_run_user.stdout == "absent"
18 |
19 | - name: "TEST: Web server group should be added to the drucker user"
20 | shell: groups {{ user }} | awk '{print $NF}'
21 | register: group_check
22 | changed_when: group_check.stdout != apache_user
23 | failed_when: group_check.stdout != apache_user
24 |
25 | - name: "TEST: Permissions should be correct in the webroot"
26 | shell: stat -c %U:%G "{{ item }}" | grep "{{ user }}:{{ apache_user }}" || echo "Wrong permissions"
27 | with_items:
28 | - "{{ adminer_root }}"
29 | - "{{ phpmyadmin_root }}"
30 | - "{{ import_dir }}"
31 | register: webroot_permissions
32 | changed_when: webroot_permissions.stdout == "Wrong permissions"
33 | failed_when: webroot_permissions.stdout == "Wrong permissions"
34 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/php/pecl-yaml-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: PECL YAML needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ pecl_yaml_extension_path }}"
7 | - "{{ pecl_yaml_archive }}"
8 | - "{{ libyaml_archive_path }}"
9 | register: pecl_yaml
10 | failed_when: pecl_yaml.stat.exists == false
11 |
12 | - name: "TEST: PECL YAML should be configured in php.ini"
13 | shell: grep -o "{{ pecl_yaml_extension_name }}" {{ default_php_ini }} || echo "absent"
14 | register: pecl_yaml_phpini
15 | changed_when: pecl_yaml_phpini == "absent"
16 | failed_when: pecl_yaml_phpini == "absent"
17 |
18 | - name: "TEST: Temporary C YAML parser directory should not exist"
19 | stat:
20 | path: "{{ libyaml_temp_path }}"
21 | register: pecl_yaml_temp_dir
22 | failed_when: pecl_yaml_temp_dir.stat.exists == true
23 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/php/php-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: Check if PHP is installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ default_php_ini }}"
7 | - "{{ default_php_ini_cli }}"
8 | - "{{ apache_proxy_fcgi_mod }}"
9 | - "{{ default_php_extensions }}"
10 | register: php
11 |
12 | - name: "TEST: Check if PHP packages are installed"
13 | shell: dpkg -l | grep {{ item }}
14 | with_items:
15 | - php-apcu
16 | - php-imagick
17 | - php-memcached
18 | - php{{ default_php_version }}-fpm
19 | - php{{ default_php_version }}-cli
20 | - php{{ default_php_version }}-common
21 | - php{{ default_php_version }}-dev
22 | - php{{ default_php_version }}-curl
23 | - php{{ default_php_version }}-gd
24 | - php{{ default_php_version }}-mbstring
25 | - php{{ default_php_version }}-mysql
26 | - php{{ default_php_version }}-xmlrpc
27 | - php{{ default_php_version }}-xsl
28 | - php{{ default_php_version }}-bz2
29 | - php{{ default_php_version }}-sqlite3
30 | register: php_packages
31 | changed_when: php_packages == ''
32 |
33 | - name: "TEST: Apache's mod_proxy_fcgi needs to be correctly enabled"
34 | stat:
35 | path: "{{ apache_proxy_http_mod }}"
36 | register: apache_proxy_http_mod_check
37 | failed_when: apache_proxy_http_mod_check.stat.exists == false
38 |
39 | - name: "TEST: Apache vHosts need to support php-fpm Fast-CGI"
40 | shell: grep -o "ProxyPassMatch" "{{ sites_enabled }}/{{ sitename }}.conf" || echo "absent"
41 | register: proxypassmatch_conf
42 | changed_when: proxypassmatch_conf.stdout == "absent"
43 | failed_when: proxypassmatch_conf.stdout == "absent"
44 |
45 | - name: "TEST: Check php.ini's custom configuration"
46 | shell: grep -o "{{ item }}" {{ default_php_ini }} || echo "absent"
47 | with_items:
48 | - max_input_time = {{ max_input_time }}
49 | - max_execution_time = {{ max_execution_time }}
50 | - memory_limit = {{ memory_limit }}
51 | - upload_max_filesize = {{ upload_max_filesize }}
52 | - max_file_uploads = {{ max_file_uploads }}
53 | - post_max_size = {{ post_max_size }}
54 | - zend.assertions = -1
55 | - display_errors = Off
56 | register: php_ini_conf
57 | changed_when: php_ini_conf.stdout == "absent"
58 | failed_when: php_ini_conf.stdout == "absent"
59 |
60 | - name: "TEST: Check php.ini CLI's custom configuration"
61 | shell: grep -o "{{ item }}" {{ default_php_ini_cli }} || echo "absent"
62 | with_items:
63 | - date.timezone = {{ timezone }}
64 | register: php_ini_cli_conf
65 | changed_when: php_ini_cli_conf.stdout == "absent"
66 | failed_when: php_ini_cli_conf.stdout == "absent"
67 |
68 | - name: "TEST: APCu is expected to run the latest stable version"
69 | shell: php -r '$version = phpversion("apcu"); echo $version;'
70 | register: apcu_version
71 | changed_when: apcu_version.stdout != apcu_stable_release
72 | failed_when: apcu_version.stdout != apcu_stable_release
73 |
74 | - name: "TEST: php-memcached is expected to run the latest stable version"
75 | shell: dpkg -l | grep php-memcached | awk '{print $3}' | cut -c1-5
76 | register: memcached_version_check
77 | changed_when: memcached_version_check.stdout != php_memcached_stable_release
78 | failed_when: memcached_version_check.stdout != php_memcached_stable_release
79 |
80 | - name: "TEST: php-fpm process needs to be started"
81 | command: pgrep {{ php_process }}
82 | register: php_fpm_process
83 | changed_when: php_fpm_process.stdout == ""
84 | failed_when: php_fpm_process.stdout == ""
85 |
86 | - name: "TEST: All URLs should be accessible"
87 | uri:
88 | url: "{{ item }}"
89 | with_items:
90 | - http://{{ user }}.{{ tld }}
91 | - http://search.{{ tld }}:{{ solr_port }}/solr/#
92 | - http://phpmyadmin.{{ tld }}
93 | - http://adminer.{{ tld }}
94 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/run-db-tests.yml:
--------------------------------------------------------------------------------
1 | - import_tasks: plays/db/db-tests.yml
2 | - import_tasks: plays/db/memcached-tests.yml
3 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/run-edge-tests.yml:
--------------------------------------------------------------------------------
1 | - import_tasks: plays/edge/varnish-tests.yml
2 | - import_tasks: plays/edge/nginx-tests.yml
3 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/run-mirror-tests.yml:
--------------------------------------------------------------------------------
1 | - import_tasks: plays/edge/mirror-tests.yml
2 | - import_tasks: plays/php/apache-common-tests.yml
3 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/run-search-tests.yml:
--------------------------------------------------------------------------------
1 | - import_tasks: plays/solr/solr-configuration-tests.yml
2 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/run-system-tests.yml:
--------------------------------------------------------------------------------
1 | - import_tasks: plays/system/system-setup-tests.yml
2 | - import_tasks: plays/system/git-tests.yml
3 | - import_tasks: plays/system/ssh-keys-tests.yml
4 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/run-web-tests.yml:
--------------------------------------------------------------------------------
1 | - import_tasks: plays/php/apache-tests.yml
2 | - import_tasks: plays/php/php-tests.yml
3 | - import_tasks: plays/tools/composer-tests.yml
4 | - import_tasks: plays/db/phpmyadmin-tests.yml
5 | - import_tasks: plays/db/adminer-tests.yml
6 | - import_tasks: plays/tools/drush-tests.yml
7 | - import_tasks: plays/tools/drupal-console-tests.yml
8 | - import_tasks: plays/php/pecl-yaml-tests.yml
9 | - import_tasks: plays/tools/xdebug-tests.yml
10 | - import_tasks: plays/tools/tideways-tests.yml
11 | - import_tasks: plays/tools/phantomjs-tests.yml
12 | - import_tasks: plays/tools/codesniffer-tests.yml
13 | - import_tasks: plays/tools/php-cs-fixer-tests.yml
14 | - import_tasks: plays/tools/coder-tests.yml
15 | # - import_tasks: plays/tools/phpmd-tests.yml
16 | - import_tasks: plays/tools/mcstat-tests.yml
17 | - import_tasks: plays/drupal/drupal-tests.yml
18 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/solr/solr-configuration-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: Check that all Apache Solr configuration files exist"
3 | stat:
4 | path: "{{ solr_configuration_path }}/{{ item }}"
5 | with_items:
6 | - elevate.xml
7 | - mapping-ISOLatin1Accent.txt
8 | - protwords.txt
9 | - schema.xml
10 | - schema_extra_fields.xml
11 | - schema_extra_types.xml
12 | - solrconfig.xml
13 | - solrconfig_spellcheck.xml
14 | - solrcore.properties
15 | - stopwords.txt
16 | - synonyms.txt
17 | register: solr_conf_files_check
18 | failed_when: solr_conf_files_check.stat.exists == false
19 |
20 | - name: "TEST: Apache Solr schema must be tuned for search_api_solr"
21 | shell: grep -o "search_api_solr" {{ solr_configuration_path }}/schema.xml | head -n1 || echo "missing"
22 | register: solr_conf_files_check
23 | changed_when: solr_conf_files_check.stdout == "missing"
24 | failed_when: solr_conf_files_check.stdout == "missing"
25 |
26 | - name: "TEST: Make sure Apache Solr server is running"
27 | shell: "{{ solr_binary }} status | grep 'running on port {{ solr_port }}' || echo 'not running'"
28 | register: solr_status
29 | changed_when: solr_status.stdout == "not running"
30 | failed_when: solr_status.stdout == "not running"
31 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/system/git-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: Git needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ git_completion }}"
7 | - "{{ git_prompt }}"
8 | - "{{ bash_git_prompt }}"
9 | - "{{ git_config }}"
10 | - "{{ global_gitignore }}"
11 | - "{{ bash_git_prompt_archive_path }}"
12 | register: git
13 | failed_when: git.stat.exists == false
14 |
15 | - name: "TEST: Check if Git has been configured in .bashrc"
16 | shell: grep -o 'MANAGED GIT BLOCK' {{ bashrc }} || echo "absent"
17 | register: git_bashrc
18 | changed_when: git_bashrc.stdout == "absent"
19 | failed_when: git_bashrc.stdout == "absent"
20 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/system/ssh-keys-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: SSH keys needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ id_rsa }}"
7 | - "{{ id_rsa_pub }}"
8 | register: ssh_keys
9 | failed_when: ssh_keys.stat.exists == false
10 |
11 | - name: "TEST: Public SSH key needs to have 4096 bits"
12 | shell: ssh-keygen -l -f {{ id_rsa_pub }} | awk '{print $1}'
13 | register: ssh_bits
14 | changed_when: ssh_bits.stdout != "4096"
15 | failed_when: ssh_bits.stdout != "4096"
16 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/system/system-setup-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: System needs to be cleaned up"
3 | shell: dpkg -l | grep vim-tiny || echo "absent"
4 | register: system_cleanup
5 | changed_when: system_cleanup.stdout != 'absent'
6 | failed_when: system_cleanup.stdout != 'absent'
7 |
8 | - name: "TEST: System files need to be correctly installed"
9 | stat:
10 | path: "{{ item }}"
11 | with_items:
12 | - "{{ bash_aliases }}"
13 | - "{{ sudo_tty_workaround_file }}"
14 | register: system
15 | failed_when: system.stat.exists == false
16 |
17 | - name: "TEST: sources.list file needs to be correctly configured"
18 | shell: grep -o -m1 "{{ codename }} main contrib non-free" {{ sources_list }} || echo "absent"
19 | register: sources_list_repos
20 | changed_when: sources_list_repos.stdout == 'absent'
21 | failed_when: sources_list_repos.stdout == 'absent'
22 |
23 | - name: "TEST: System packages need to be correctly installed"
24 | shell: dpkg -l | grep {{ item }}
25 | with_items:
26 | - aptitude
27 | - ack-grep
28 | - apt-transport-https
29 | - curl
30 | - dstat
31 | - exuberant-ctags
32 | - git
33 | - htop
34 | - iputils-ping
35 | - libfontconfig1
36 | - logrotate
37 | - lsof
38 | - ncdu
39 | - netcat
40 | - net-tools
41 | - ntp
42 | - patchutils
43 | - silversearcher-ag
44 | - strace
45 | - sysstat
46 | - telnet
47 | - tcpdump
48 | - time
49 | - neovim
50 | - wget
51 | - xterm
52 | register: system_packages
53 | changed_when: system_packages == ''
54 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/tools/coder-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: Coder needs to be correctly installed"
3 | stat:
4 | path: "{{ coder_binary }}"
5 | register: coder
6 | failed_when: coder.stat.exists == false
7 |
8 | - name: "TEST: Coder should use the latest stable release"
9 | shell: grep -o "{{ coder_stable_release }}" {{ composer_json_path }} || echo "absent"
10 | register: coder_stable
11 | changed_when: coder_stable.stdout == "absent"
12 | failed_when: coder_stable.stdout == "absent"
13 |
14 | - name: "TEST: Check if Coder has been configured in .bashrc"
15 | shell: grep -o 'MANAGED CODE SNIFFER BLOCK' {{ bashrc }} || echo "absent"
16 | register: coder_bashrc
17 | changed_when: coder_bashrc.stdout == "absent"
18 | failed_when: coder_bashrc.stdout == "absent"
19 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/tools/codesniffer-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: CodeSniffer needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ phpcs_binary }}"
7 | - "{{ phpcbf_binary }}"
8 | register: xdebug_install
9 | failed_when: xdebug_install.stat.exists == false
10 |
11 | - name: "TEST: CodeSniffer phpcs should use the latest stable release"
12 | shell: phpcs --version | awk '{print $3}'
13 | register: phpcs_version_check
14 | changed_when: phpcs_version_check.stdout != phpcs_stable_release
15 | failed_when: phpcs_version_check.stdout != phpcs_stable_release
16 | ignore_errors: true
17 |
18 | - name: "TEST: CodeSniffer phpcbf should use the latest stable release"
19 | shell: phpcbf --version | awk '{print $3}'
20 | register: phpcbf_version_check
21 | changed_when: phpcbf_version_check.stdout != phpcbf_stable_release
22 | failed_when: phpcbf_version_check.stdout != phpcbf_stable_release
23 | ignore_errors: true
24 |
25 | - name: "TEST: The CodeSniffer phpcs binary should be executable"
26 | stat:
27 | path: "{{ phpcs_binary }}"
28 | register: executable_phpcs
29 |
30 | - name: "TEST: The CodeSniffer phpcs binary should be executable"
31 | fail:
32 | msg: "The CodeSniffer phpcs binary isn't executable"
33 | when: executable_phpcs.stat.mode != "0755"
34 |
35 | - name: "TEST: The CodeSniffer phpcbf binary should be executable"
36 | stat:
37 | path: "{{ phpcbf_binary }}"
38 | register: executable_phpcbf
39 |
40 | - name: "TEST: The CodeSniffer phpcbf binary should be executable"
41 | fail:
42 | msg: "The CodeSniffer phpcbf binary isn't executable"
43 | when: executable_phpcbf.stat.mode != "0755"
44 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/tools/composer-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: Composer needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ composer_dir_path }}"
7 | - "{{ composer_dir_path }}/vendor"
8 | - "{{ composer_json_path }}"
9 | - "{{ composer_binary }}"
10 | register: composer
11 | failed_when: composer.stat.exists == false
12 |
13 | - name: "TEST: The composer binary should be executable"
14 | stat:
15 | path: "{{ composer_binary }}"
16 | register: executable_composer
17 |
18 | - name: "TEST: The Composer binary isn't executable"
19 | fail:
20 | msg: "The Composer binary isn't executable"
21 | when: executable_composer.stat.mode != "0755"
22 |
23 | - name: "TEST: Composer should use the latest stable release"
24 | shell: composer --version | awk '{print $3}'
25 | register: composer_version
26 | become: yes
27 | become_user: "{{ user }}"
28 | changed_when: composer_version.stdout != composer_stable_release
29 | failed_when: composer_version.stdout != composer_stable_release
30 |
31 | - name: "TEST: Composer should be in the $PATH"
32 | shell: grep -o "export PATH=\"\$PATH:\$HOME/.composer/vendor/bin\"" {{ bashrc }} || echo "absent"
33 | register: composer_path
34 | changed_when: composer_path.stdout == "absent"
35 | failed_when: composer_path.stdout == "absent"
36 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/tools/drupal-console-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: Drupal Console needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ drupal_console_binary }}"
7 | register: drupal_console
8 | failed_when: drupal_console.stat.exists == false
9 |
10 | - name: "TEST: Drupal Console Launcher should use the latest stable release"
11 | shell: drupal --version | head -n1 | awk '{print $NF}'
12 | register: drupal_console_launcher_version
13 | changed_when: drupal_console_launcher_version.stdout != drupal_console_launcher_stable_release
14 | failed_when: drupal_console_launcher_version.stdout != drupal_console_launcher_stable_release
15 |
16 | - name: "TEST: Check if Drupal Console has been configured in .bashrc"
17 | shell: grep -o "source \"\$HOME/.console/console.rc\" 2>/dev/null" {{ bashrc }} || echo "absent"
18 | register: drupal_console_bashrc
19 | changed_when: drupal_console_bashrc == "absent"
20 | failed_when: drupal_console_bashrc == "absent"
21 |
22 | - name: "TEST: Check if Drupal Console can connect to the drucker database"
23 | shell: drupal database:connect --root={{ drupal_docroot }} | grep -o "{{ user }}" || echo "Cannot connect to the database"
24 | register: drupal_console_db_connection
25 | changed_when: drupal_console_db_connection.stdout == "Cannot connect to the database"
26 | failed_when: drupal_console_db_connection.stdout == "Cannot connect to the database"
27 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/tools/drush-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: Drush needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ drush_launcher }}"
7 | - "{{ global_drush }}"
8 | - "{{ drush_alias_path }}"
9 | - "{{ drush_dir }}"
10 | register: drush
11 | failed_when: drush.stat.exists == false
12 |
13 | - name: "TEST: Drush Launcher should use the latest stable release"
14 | shell: drush --root={{ webroot }}/{{ user }} --version | head -n1 | awk '{print $NF}'
15 | register: drush_launcher_version_check
16 | changed_when: drush_launcher_version_check.stdout != drush_launcher_stable_release
17 | failed_when: drush_launcher_version_check.stdout != drush_launcher_stable_release
18 |
19 | - name: "TEST: Global Drush should use the latest stable release"
20 | shell: drush --root={{ webroot }}/{{ user }} --version | tail -n1 | awk '{print $NF}'
21 | register: global_drush_version_check
22 | changed_when: global_drush_version_check.stdout != global_drush_stable_release
23 | failed_when: global_drush_version_check.stdout != global_drush_stable_release
24 |
25 | - name: "TEST: Check if Drush can connect to the drucker database"
26 | shell: drush --root={{ webroot }}/{{ user }} sql-connect | grep -o "{{ user }}" || echo "Cannot connect to the database"
27 | register: drush_db_connection
28 | changed_when: drush_db_connection.stdout == "Cannot connect to the database"
29 | failed_when: drush_db_connection.stdout == "Cannot connect to the database"
30 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/tools/mcstat-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: mcstat needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ mcstat_binary }}"
7 | - "{{ user_programs_path }}/{{ mcstat_unarchived_directory }}"
8 | register: mcstat_check
9 | failed_when: mcstat_check.stat.exists == false
10 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/tools/phantomjs-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: PhantomJS needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ phantomjs_binary }}"
7 | register: phantomjs
8 | failed_when: phantomjs.stat.exists == false
9 |
10 | - name: "TEST: The phantomjs binary should be executable"
11 | stat:
12 | path: "{{ phantomjs_binary }}"
13 | register: executable_phantomjs
14 |
15 | - name: "TEST: The phantomjs binary isn't executable"
16 | fail:
17 | msg: "The phantomjs binary isn't executable"
18 | when: executable_phantomjs.stat.mode != "0755"
19 |
20 | - name: "TEST: The path to generate HTML files should be valid"
21 | shell: grep -o "{{ simpletest_dir }}" {{ phpunit_xml }} || echo "incorrect"
22 | register: phpunit_html_export_dir
23 | changed_when: phpunit_html_export_dir.stdout == "incorrect"
24 | failed_when: phpunit_html_export_dir.stdout == "incorrect"
25 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/tools/php-cs-fixer-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: php-cs-fixer needs to be correctly installed"
3 | stat:
4 | path: "{{ php_cs_fixer_binary }}"
5 | register: php_cs_fixer
6 | failed_when: php_cs_fixer.stat.exists == false
7 |
8 | - name: "TEST: php-cs-fixer should use the latest stable release"
9 | shell: php-cs-fixer --version | awk '{print $5}'
10 | register: php_cs_fixer_version_check
11 | changed_when: php_cs_fixer_version_check.stdout != php_cs_fixer_stable_release
12 | failed_when: php_cs_fixer_version_check.stdout != php_cs_fixer_stable_release
13 | ignore_errors: true
14 |
15 | - name: "TEST: The php-cs-fixer binary should be executable"
16 | stat:
17 | path: "{{ php_cs_fixer_binary }}"
18 | register: executable_php_cs_fixer
19 |
20 | - name: "TEST: The php-cs-fixer binary isn't executable"
21 | fail:
22 | msg: "The php-cs-fixer binary isn't executable"
23 | when: executable_php_cs_fixer.stat.mode != "0755"
24 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/tools/phpmd-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: phpmd needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ user_programs_path }}/phpmd"
7 | register: phpmd
8 | failed_when: phpmd.stat.exists == false
9 |
10 | - name: "TEST: phpmd should use the latest stable release"
11 | shell: phpmd --version | awk '{print $NF}'
12 | register: phpmd_version_check
13 | changed_when: phpmd_version_check.stdout != phpmd_stable_version
14 | failed_when: phpmd_version_check.stdout != phpmd_stable_version
15 | ignore_errors: true
16 |
17 | - name: "TEST: The phpmd binary should be executable"
18 | stat:
19 | path: "{{ user_programs_path }}/phpmd"
20 | register: executable_phpmd
21 |
22 | - name: "TEST: The phpmd binary isn't executable"
23 | fail:
24 | msg: "The phpmd binary isn't executable"
25 | when: executable_phpmd.stat.mode != "0755"
26 |
27 | - name: "TEST: Check if Coder has been configured in .bashrc"
28 | shell: grep -o 'MANAGED PHPMD BLOCK' {{ bashrc }} || echo "absent"
29 | register: phpmd_bashrc
30 | changed_when: phpmd_bashrc.stdout == "absent"
31 | failed_when: phpmd_bashrc.stdout == "absent"
32 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/tools/tideways-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: Tideways needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ tideways_extension_path }}"
7 | - "{{ tideways_archive }}"
8 | - "{{ tideways_output_dir }}"
9 | register: tideways
10 | failed_when: tideways.stat.exists == false
11 |
12 | - name: "TEST: Tideways should use the latest stable release"
13 | shell: php -c {{ default_php_ini }} -i | grep 'tideways' | grep -o '{{ tideways_stable_release }}' || echo 'update'
14 | register: tideways_version_check
15 | changed_when: tideways_version_check.stdout == "update"
16 | failed_when: tideways_version_check.stdout == "update"
17 |
18 | - name: "TEST: Tideways should be configured in php.ini"
19 | shell: grep -o "{{ tideways_extension_name }}" {{ default_php_ini }} || echo "absent"
20 | register: tideways_phpini
21 | changed_when: tideways_phpini == "absent"
22 | failed_when: tideways_phpini == "absent"
23 |
24 | - name: "TEST: The Tideways output directory should be writable"
25 | stat:
26 | path: "{{ tideways_output_dir }}"
27 | register: writable_tideways
28 |
29 | - name: "TEST: The Tideways output directory should be writable"
30 | fail:
31 | msg: "The Tideways output directory isn't writable"
32 | when: writable_tideways.stat.mode != "0777"
33 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/plays/tools/xdebug-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TEST: Xdebug needs to be correctly installed"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ xdebug_extension_path }}"
7 | - "{{ xdebug_archive_path }}"
8 | register: xdebug_install
9 | failed_when: xdebug_install.stat.exists == false
10 |
11 | - name: "TEST: Xdebug should be configured in php.ini"
12 | shell: grep -o "{{ xdebug_extension_name }}" {{ default_php_ini }} || echo "absent"
13 | register: xdebug_phpini
14 | changed_when: xdebug_phpini == "absent"
15 | failed_when: xdebug_phpini == "absent"
16 |
17 | - name: "TEST: Xdebug should use the latest release"
18 | shell: php -c {{ default_php_ini }} -i | grep -m1 -o {{ xdebug_stable_release }} || "absent"
19 | register: xdebug_phpini_version
20 | changed_when: xdebug_phpini_version == "absent"
21 | failed_when: xdebug_phpini_version == "absent"
22 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/search-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Invoked via run_tests() in containers/orchestration.
3 | - hosts: drucker_search
4 | become: yes
5 |
6 | gather_facts: yes
7 | vars_files:
8 | - ../vars.yml
9 | handlers:
10 | - import_tasks: ../handlers.yml
11 | tasks:
12 | - import_tasks: plays/run-search-tests.yml
13 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/system-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Invoked via run_tests() in containers/orchestration.
3 | - hosts: drucker_web
4 | become: yes
5 |
6 | gather_facts: yes
7 | vars_files:
8 | - ../vars.yml
9 | handlers:
10 | - import_tasks: ../handlers.yml
11 | tasks:
12 | - import_tasks: plays/run-system-tests.yml
13 |
--------------------------------------------------------------------------------
/app/orchestration/_tests/web-tests.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Invoked via run_tests() in containers/orchestration.
3 | - hosts: drucker_web
4 | become: yes
5 |
6 | gather_facts: yes
7 | vars_files:
8 | - ../vars.yml
9 | handlers:
10 | - import_tasks: ../handlers.yml
11 | tasks:
12 | - import_tasks: plays/run-web-tests.yml
13 | vars:
14 | sitename: "drucker"
15 |
--------------------------------------------------------------------------------
/app/orchestration/commands/app-blt.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_web
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/app/blt.yml
12 |
--------------------------------------------------------------------------------
/app/orchestration/commands/app-delete.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_web
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/app/delete.yml
12 |
--------------------------------------------------------------------------------
/app/orchestration/commands/app-dev.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_web
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/app/dev.yml
12 |
--------------------------------------------------------------------------------
/app/orchestration/commands/app-drupal.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_web
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/app/drupal.yml
12 |
--------------------------------------------------------------------------------
/app/orchestration/commands/app-import.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_web
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/app/import.yml
12 |
--------------------------------------------------------------------------------
/app/orchestration/commands/app-lightning.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_web
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/app/lightning.yml
12 |
--------------------------------------------------------------------------------
/app/orchestration/commands/app-prod.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_web
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/app/prod.yml
12 |
--------------------------------------------------------------------------------
/app/orchestration/commands/default-php.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_web
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/php/default-php.yml
12 |
--------------------------------------------------------------------------------
/app/orchestration/commands/legacy-php.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_web
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/php/legacy-php.yml
12 |
--------------------------------------------------------------------------------
/app/orchestration/commands/previous-php.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_web
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/php/previous-php.yml
12 |
--------------------------------------------------------------------------------
/app/orchestration/files/.bash_aliases:
--------------------------------------------------------------------------------
1 | # System
2 | alias ll='ls -lh --color=auto'
3 | alias la='ls -lhA --color=auto'
4 | alias grep='grep --color=auto'
5 | alias fgrep='fgrep --color=auto'
6 | alias egrep='egrep --color=auto'
7 |
8 | # VIM
9 | alias vi='vim'
10 | alias tags="/usr/bin/ctags --exclude=.git --exclude='*.css' --exclude='*.js' -R"
11 |
--------------------------------------------------------------------------------
/app/orchestration/files/.gitconfig:
--------------------------------------------------------------------------------
1 | [user]
2 | name = drucker
3 | email = drucker@drucker.local
4 | [core]
5 | autocrlf = false
6 | safecrlf = false
7 | ignorecase = false
8 | excludesfile = ~/.gitignore
9 | [color]
10 | ui = true
11 | [push]
12 | default = current
13 | [diff]
14 | renames = copies
15 | [alias]
16 | apply = apply --index -v
17 | p = format-patch --stdout
18 | diff = diff --full-index --binary
19 | co = checkout
20 | st = status --untracked-files=all
21 | unstash = !git stash show -p | git apply -R
22 | hist = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)[%an]%Creset' --abbrev-commit
23 | clean = clean -fdx
24 | reset = reset --hard
25 |
--------------------------------------------------------------------------------
/app/orchestration/files/.gitignore:
--------------------------------------------------------------------------------
1 | docroot/sites/*/files
2 | docroot/sites/*/private
3 | docroot/sites/simpletest/*
4 |
--------------------------------------------------------------------------------
/app/orchestration/files/.gitignore-global:
--------------------------------------------------------------------------------
1 | ######################
2 | # OS generated files #
3 | ######################
4 | ehthumbs.db
5 | Icon?
6 | Thumbs.db
7 | ._*
8 | .DS*
9 | .project
10 | *.lnk
11 | tmp*
12 |
13 | ############
14 | # Packages #
15 | ############
16 | *.7z
17 | *.dmg
18 | *.gz
19 | *.iso
20 | *.jar
21 | *.rar
22 | *.tar
23 | *.zip
24 |
25 | ######################
26 | # Logs and databases #
27 | ######################
28 | *.log
29 | *.sql
30 |
31 | ######################
32 | # Vim generated files #
33 | ######################
34 | *.un~
35 | *.swp
36 |
37 | ##########
38 | # SASS #
39 | ##########
40 | .sass-cache
41 |
42 | ########################
43 | # Patch/diff artifacts #
44 | ########################
45 | *.patch
46 | *.diff
47 | *.orig
48 | *.rej
49 | interdiff*.txt
50 |
51 | ###################
52 | # emacs artifacts #
53 | ###################
54 | *~
55 | \#*\#
56 |
57 | ########
58 | # IDEs #
59 | ########
60 | nbproject
61 | .idea
62 |
63 | ##########
64 | # Drupal #
65 | ##########
66 | ~/Sites/git/drupal/drupal/vendor
67 |
--------------------------------------------------------------------------------
/app/orchestration/files/README-import.txt:
--------------------------------------------------------------------------------
1 | Read more at https://github.com/anavarre/drucker/wiki/Importing-an-existing-site-to-drucker
2 |
--------------------------------------------------------------------------------
/app/orchestration/files/apache-template.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 | ServerName SITENAME.local
4 | ServerAlias SITENAME.local
5 | ServerAdmin admin@SITENAME.local
6 | DocumentRoot /var/www/html/SITENAME/docroot
7 |
8 |
9 | Options Indexes FollowSymLinks
10 | AllowOverride All
11 | Require all granted
12 |
13 |
14 | ErrorLog ${APACHE_LOG_DIR}/SITENAME-error.log
15 | CustomLog ${APACHE_LOG_DIR}/SITENAME-access.log combined
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/orchestration/files/apt.conf:
--------------------------------------------------------------------------------
1 | Acquire::http { Proxy "http://HOST:PORT"; };
2 |
--------------------------------------------------------------------------------
/app/orchestration/files/composer-dev-template.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "anavarre/drucker",
3 | "description": "drucker build.",
4 | "type": "project",
5 | "license": "GPL-2.0-or-later",
6 | "minimum-stability": "dev",
7 | "prefer-stable": true,
8 | "repositories": [
9 | {
10 | "type": "composer",
11 | "url": "https://packages.drupal.org/8"
12 | },
13 | {
14 | "type": "composer",
15 | "url": "https://asset-packagist.org"
16 | }
17 | ],
18 | "require": {
19 | "composer/installers": "^1.5",
20 | "drupal-composer/drupal-scaffold": "^2.4",
21 | "cweagans/composer-patches": "^1.6",
22 | "drupal/core": "^8.7",
23 | "drush/drush": "^9.0",
24 | "drupal/console": "^1.0"
25 | },
26 | "require-dev": {
27 | "behat/mink": "1.7.x-dev",
28 | "behat/mink-goutte-driver": "^1.2",
29 | "behat/mink-selenium2-driver": "1.3.x-dev",
30 | "drupal/coder": "^8.2.12",
31 | "jcalderonzumba/gastonjs": "^1.0.2",
32 | "jcalderonzumba/mink-phantomjs-driver": "^0.3.1",
33 | "mikey179/vfsStream": "^1.2",
34 | "phpunit/phpunit": "^4.8.35 || ^6.1",
35 | "phpspec/prophecy": "^1.4",
36 | "symfony/css-selector": "^3.4.0",
37 | "symfony/phpunit-bridge": "^3.4.3",
38 | "symfony/debug": "^3.4.0",
39 | "mglaman/phpstan-drupal": "^0.11.2",
40 | "phpstan/phpstan-deprecation-rules": "^0.11.0"
41 |
42 | },
43 | "conflict": {
44 | "drupal/core": "7.*"
45 | },
46 | "extra": {
47 | "installer-types": [
48 | "bower-asset",
49 | "npm-asset"
50 | ],
51 | "installer-paths": {
52 | "docroot/core": ["type:drupal-core"],
53 | "docroot/modules/contrib/{$name}/": ["type:drupal-module"],
54 | "docroot/modules/custom/{$name}/": ["type:drupal-module-custom"],
55 | "docroot/themes/contrib/{$name}/": ["type:drupal-theme"],
56 | "docroot/profiles/contrib/{$name}/": ["type:drupal-profile"],
57 | "drush/contrib/{$name}": ["type:drupal-drush"],
58 | "docroot/libraries/{$name}": [
59 | "type:bower-asset",
60 | "type:npm-asset"
61 | ]
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/orchestration/files/composer-template.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "anavarre/drucker",
3 | "description": "drucker build.",
4 | "type": "project",
5 | "license": "GPL-2.0-or-later",
6 | "minimum-stability": "dev",
7 | "prefer-stable": true,
8 | "repositories": [
9 | {
10 | "type": "composer",
11 | "url": "https://packages.drupal.org/8"
12 | },
13 | {
14 | "type": "composer",
15 | "url": "https://asset-packagist.org"
16 | }
17 | ],
18 | "require": {
19 | "composer/installers": "^1.6",
20 | "drupal-composer/drupal-scaffold": "^2.6",
21 | "cweagans/composer-patches": "^1.6",
22 | "drupal/core": "^8.8",
23 | "drush/drush": "^9.6",
24 | "drupal/console": "^1.8",
25 | "zaporylie/composer-drupal-optimizations" : "^1.1.0"
26 | },
27 | "conflict": {
28 | "drupal/core": "7.*"
29 | },
30 | "extra": {
31 | "installer-types": [
32 | "bower-asset",
33 | "npm-asset"
34 | ],
35 | "installer-paths": {
36 | "docroot/core": ["type:drupal-core"],
37 | "docroot/modules/contrib/{$name}/": ["type:drupal-module"],
38 | "docroot/modules/custom/{$name}/": ["type:drupal-module-custom"],
39 | "docroot/themes/contrib/{$name}/": ["type:drupal-theme"],
40 | "docroot/profiles/contrib/{$name}/": ["type:drupal-profile"],
41 | "drush/contrib/{$name}": ["type:drupal-drush"],
42 | "docroot/libraries/{$name}": [
43 | "type:bower-asset",
44 | "type:npm-asset"
45 | ]
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/orchestration/files/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "drucker/home",
3 | "description": "Base dependencies",
4 | "license": "GPL-2.0-or-later",
5 | "require": {
6 | "hirak/prestissimo": "^0.3.9",
7 | "symfony/yaml": "^3.4",
8 | "drush/drush": "^9.6"
9 | },
10 | "minimum-stability": "dev",
11 | "prefer-stable": true
12 | }
13 |
--------------------------------------------------------------------------------
/app/orchestration/files/db-backup.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | CREDS="root"
4 | HOST="localhost"
5 | MYSQL="$(which mysql)"
6 | MYSQLDUMP="$(which mysqldump)"
7 | BACKUP_DIR="/var/lib/mysql/backup"
8 | QUERY="SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT REGEXP 'backup|mysql|information_schema|performance_schema'"
9 | GZIP="$(which gzip)"
10 | NOW=$(date +"%Y-%m-%d_%R")
11 |
12 | DBS="$(${MYSQL} -h ${HOST} -u ${CREDS} -p${CREDS} -Bse "${QUERY}")"
13 | for DB in ${DBS}
14 | do
15 | FILE=${BACKUP_DIR}/${DB}_${NOW}.gz
16 | ${MYSQLDUMP} -h ${HOST} -u ${CREDS} -p${CREDS} ${DB} | ${GZIP} -9 > ${FILE}
17 | done
18 |
--------------------------------------------------------------------------------
/app/orchestration/files/default.vcl:
--------------------------------------------------------------------------------
1 | #
2 | # This is an example VCL file for Varnish.
3 | #
4 | # It does not do anything by default, delegating control to the
5 | # builtin VCL. The builtin VCL is called when there is no explicit
6 | # return statement.
7 | #
8 | # See the VCL chapters in the Users Guide at https://www.varnish-cache.org/docs/
9 | # and https://www.varnish-cache.org/trac/wiki/VCLExamples for more examples.
10 |
11 | # Marker to tell the VCL compiler that this VCL has been adapted to the
12 | # new 4.0 format.
13 | vcl 4.0;
14 |
15 | # Default backend definition. Set this to point to your content server.
16 | backend default {
17 | .host = "127.0.0.1";
18 | .port = "8080";
19 | .connect_timeout = 300s;
20 | .first_byte_timeout = 300s;
21 | .between_bytes_timeout = 300s;
22 | }
23 |
24 | sub vcl_recv {
25 | # Happens before we check if we have this in cache already.
26 | #
27 | # Typically you clean up the request here, removing cookies you don't need,
28 | # rewriting the request, etc.
29 | }
30 |
31 | sub vcl_backend_response {
32 | # Happens after we have read the response headers from the backend.
33 | #
34 | # Here you clean the response headers, removing silly Set-Cookie headers
35 | # and other mistakes your backend does.
36 | }
37 |
38 | sub vcl_deliver {
39 | # Happens when we have all the pieces we need, and are about to send the
40 | # response to the client.
41 | #
42 | # You can do accounting or modifying the final object here.
43 |
44 | # Indicate if the response is a HIT or MISS
45 | if (obj.hits > 0) {
46 | set resp.http.X-Cache = "HIT";
47 | } else {
48 | set resp.http.X-Cache = "MISS";
49 | }
50 |
51 | # Indicate how many HITS Varnish has recorded within the allowed TTL
52 | set resp.http.X-Cache-Hits = obj.hits;
53 | }
54 |
--------------------------------------------------------------------------------
/app/orchestration/files/drush.site.yml:
--------------------------------------------------------------------------------
1 | local:
2 | root: /var/www/html/SITENAME
3 | uri: http://SITENAME.local
4 |
--------------------------------------------------------------------------------
/app/orchestration/files/drush.yml:
--------------------------------------------------------------------------------
1 | drush:
2 | paths:
3 | alias-path:
4 | - /etc/drush
5 |
--------------------------------------------------------------------------------
/app/orchestration/files/nginx-template.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen localhost:8080;
3 | server_name drucker.local;
4 | ssl_certificate /etc/nginx/ssl/nginx.crt;
5 | ssl_certificate_key /etc/nginx/ssl/nginx.key;
6 |
7 | listen 443 ssl;
8 |
9 | #root /usr/local/www/mydomain.com;
10 |
11 | #access_log logs/drucker_access.log;
12 | #error_log logs/drucker_error.log;
13 |
14 | location / {
15 | # try_files attempts to serve a file or folder, until it reaches the fallback at the end
16 | try_files $uri @backend;
17 | }
18 |
19 | location @backend {
20 | # essentially the same as passing php requests back to apache
21 |
22 | proxy_set_header X-Real-IP $remote_addr;
23 | proxy_set_header X-Forwarded-For $remote_addr;
24 | proxy_set_header Host $host;
25 | proxy_pass http://0.0.0.0:80;
26 | proxy_connect_timeout 600;
27 | proxy_send_timeout 600;
28 | proxy_read_timeout 600;
29 | send_timeout 600;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/orchestration/files/phpstan.neon:
--------------------------------------------------------------------------------
1 | parameters:
2 | customRulesetUsed: true
3 | reportUnmatchedIgnoredErrors: false
4 | # Ignore phpstan-drupal extension's rules.
5 | ignoreErrors:
6 | - '#\Drupal calls should be avoided in classes, use dependency injection instead#'
7 | - '#Plugin definitions cannot be altered.#'
8 | - '#Missing cache backend declaration for performance.#'
9 | - '#Plugin manager has cache backend specified but does not declare cache tags.#'
10 | includes:
11 | - vendor/mglaman/phpstan-drupal/extension.neon
12 | - vendor/phpstan/phpstan-deprecation-rules/rules.neon
--------------------------------------------------------------------------------
/app/orchestration/files/solr-conf-7.x/elevate.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
18 |
19 |
20 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/orchestration/files/solr-conf-7.x/mapping-ISOLatin1Accent.txt:
--------------------------------------------------------------------------------
1 | # This file contains character mappings for the default fulltext field type.
2 | # The source characters (on the left) will be replaced by the respective target
3 | # characters before any other processing takes place.
4 | # Lines starting with a pound character # are ignored.
5 | #
6 | # For sensible defaults, use the mapping-ISOLatin1Accent.txt file distributed
7 | # with the example application of your Solr version.
8 | #
9 | # Examples:
10 | # "À" => "A"
11 | # "\u00c4" => "A"
12 | # "\u00c4" => "\u0041"
13 | # "æ" => "ae"
14 | # "\n" => " "
15 |
--------------------------------------------------------------------------------
/app/orchestration/files/solr-conf-7.x/protwords.txt:
--------------------------------------------------------------------------------
1 | #-----------------------------------------------------------------------
2 | # This file blocks words from being operated on by the stemmer and word delimiter.
3 | &
4 | <
5 | >
6 | '
7 | "
8 |
--------------------------------------------------------------------------------
/app/orchestration/files/solr-conf-7.x/schema_extra_fields.xml:
--------------------------------------------------------------------------------
1 |
7 |
22 |
--------------------------------------------------------------------------------
/app/orchestration/files/solr-conf-7.x/schema_extra_types.xml:
--------------------------------------------------------------------------------
1 |
10 |
33 |
--------------------------------------------------------------------------------
/app/orchestration/files/solr-conf-7.x/solrconfig_extra.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | default
4 | AnalyzingInfixLookupFactory
5 | DocumentDictionaryFactory
6 | spell
7 | text
8 | sm_context_tags
9 | false
10 | false
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/orchestration/files/solr-conf-7.x/solrconfig_spellcheck.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 | textSpell
12 |
13 |
14 |
17 |
18 |
19 |
20 | default
21 | spell
22 | solr.DirectSolrSpellChecker
23 |
24 | internal
25 |
26 | 0.5
27 |
28 | 2
29 |
30 | 1
31 |
32 | 5
33 |
34 | 4
35 |
36 | 0.01
37 |
40 |
41 |
42 |
43 |
44 | wordbreak
45 | solr.WordBreakSolrSpellChecker
46 | name
47 | true
48 | true
49 | 10
50 |
51 |
52 |
53 |
63 |
64 |
71 |
78 |
79 |
80 |
89 |
90 |
--------------------------------------------------------------------------------
/app/orchestration/files/solr-conf-7.x/solrcore.properties:
--------------------------------------------------------------------------------
1 | # Defines Solr properties for this specific core.
2 | solr.replication.master=false
3 | solr.replication.slave=false
4 | solr.replication.pollInterval=00:00:60
5 | solr.replication.masterUrl=http://localhost:8983/solr
6 | solr.replication.confFiles=schema.xml,mapping-ISOLatin1Accent.txt,protwords.txt,stopwords.txt,synonyms.txt,elevate.xml
7 | solr.mlt.timeAllowed=2000
8 | # You should not set your luceneMatchVersion to anything lower than your Solr
9 | # Version.
10 | solr.luceneMatchVersion=6.0
11 | solr.selectSearchHandler.timeAllowed=-1
12 | # autoCommit after 10000 docs
13 | solr.autoCommit.MaxDocs=10000
14 | # autoCommit after 2 minutes
15 | solr.autoCommit.MaxTime=120000
16 | # autoSoftCommit after 2000 docs
17 | solr.autoSoftCommit.MaxDocs=2000
18 | # autoSoftCommit after 10 seconds
19 | solr.autoSoftCommit.MaxTime=10000
20 | solr.install.dir=../../..
21 |
--------------------------------------------------------------------------------
/app/orchestration/files/solr-conf-7.x/stopwords.txt:
--------------------------------------------------------------------------------
1 | # Contains words which shouldn't be indexed for fulltext fields, e.g., because
2 | # they're too common. For documentation of the format, see
3 | # http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters#solr.StopFilterFactory
4 | # (Lines starting with a pound character # are ignored.)
5 |
--------------------------------------------------------------------------------
/app/orchestration/files/solr-conf-7.x/synonyms.txt:
--------------------------------------------------------------------------------
1 | # Contains synonyms to use for your index. For the format used, see
2 | # http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters#solr.SynonymFilterFactory
3 | # (Lines starting with a pound character # are ignored.)
4 |
--------------------------------------------------------------------------------
/app/orchestration/files/sources.list:
--------------------------------------------------------------------------------
1 | deb http://httpredir.debian.org/debian CODENAME main contrib non-free
2 | deb-src http://httpredir.debian.org/debian CODENAME main contrib non-free
3 |
4 | deb http://httpredir.debian.org/debian CODENAME-updates main contrib non-free
5 | deb-src http://httpredir.debian.org/debian CODENAME-updates main contrib non-free
6 |
7 | deb http://httpredir.debian.org/debian CODENAME-backports main
8 | deb-src http://httpredir.debian.org/debian CODENAME-backports main
9 |
10 | deb http://security.debian.org/ CODENAME/updates main contrib non-free
11 | deb-src http://security.debian.org/ CODENAME/updates main contrib non-free
12 |
--------------------------------------------------------------------------------
/app/orchestration/files/ssl/nginx.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIFpzCCA4+gAwIBAgIJALVo9DXdWjfPMA0GCSqGSIb3DQEBCwUAMGoxCzAJBgNV
3 | BAYTAlVTMRMwEQYDVQQIDApTb21lLVN0YXRlMRAwDgYDVQQKDAdkcnVja2VyMRAw
4 | DgYDVQQDDAdkcnVja2VyMSIwIAYJKoZIhvcNAQkBFhNhZG1pbkBkcnVja2VyLmxv
5 | Y2FsMB4XDTE2MTAxMDEyMDIxNFoXDTE4MTAxMDEyMDIxNFowajELMAkGA1UEBhMC
6 | VVMxEzARBgNVBAgMClNvbWUtU3RhdGUxEDAOBgNVBAoMB2RydWNrZXIxEDAOBgNV
7 | BAMMB2RydWNrZXIxIjAgBgkqhkiG9w0BCQEWE2FkbWluQGRydWNrZXIubG9jYWww
8 | ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDSHcq/kSHGEbkcrakcPBdi
9 | 2BX6qMWMPjbvA8vzoZjRSYdXS8OdMyYSp9StP39xk9zOEmPeCpOEF1GR+bq8KvOM
10 | obXncsaEzU5XIQ7x/0lPQYI0ROekzf9k/9w1eTAYNggCRw0LIPivk5moqOv/RZj0
11 | oo5tvHE5JnQd69u3Dhx4oy6fY/yqI43ICVVPJMGWwtRzVTl3dS5VcP5EAgyFh9vp
12 | +s2NxLMJfC6aQ3OchLXFdbqg9T9BUIJVlvpgqaJBTF2nW8n0ujJcs6ywrWa2f9Ij
13 | PvhIyZanJg9m+NHNW1vUNEoY/mZLiTHyhd8t39Wifx1iemzIJJk6CUnaf8sfUaJj
14 | 99xydeMoos++UvSU4tIxEavP8Qf0WZm/WtWa9/LQP12XJ8JhqB1Y/1Tkz1NkFnX5
15 | mZxXtWe4/cimx33d/Kb9WyQIlGtUi+SWYSIprlSSqScaMXRjGSJ6X8fGbvMy0U6m
16 | CYJII2grE6Mzcmq1GesNilJ+WSij23NnEo7h2JYleqEikRojeZZgp0trm4zeXDmI
17 | QAw7N/PQKN+q1Ki+keReP4VuvusiUOi6Qq+20pDH3/1srln0fLmJ4RWvrIVodgWT
18 | PKD7A92PWctphXJZBqqwq3BNT5owlID1ZYnz8Nz9EfxUwM7ral4jcrGevzKqDpYB
19 | Xfr9r1SBstsBLaVCFSNoJQIDAQABo1AwTjAdBgNVHQ4EFgQUEEeUNvDV7IsaKt7d
20 | jfFAwmTrgxIwHwYDVR0jBBgwFoAUEEeUNvDV7IsaKt7djfFAwmTrgxIwDAYDVR0T
21 | BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAU1cWZFllf1JNiF8+qvzWZUYpfds2
22 | 7PdJ5aJOVRuqo2c7TEabjS+gY4hrFcKnPlizilHKsr2vUUQoCyjgkIhEG7+apBjB
23 | Hf5zF/o76+23EM46wJOb+0tDneq6Hw0eWIL/Whm+I80qhTikrh4Pt81ybm+pSdQ8
24 | vnGtYGkgPi5xkCKzWlC2IkKI2juKssc8gzg1ULyRxbUmexYlS4knTf/C6IrGCWhQ
25 | 4oTjKdC3CnKkyJut8rYdnEQuzip2trPLM3m+kx3QWJw3jC02rPvFo+rQUY1mskqw
26 | 2HV2IHrvUmkMGLe0swDMbGYtVAkOvt2QN2E51nZ/eyz39EIkoIQKp5e/dqCMzk1s
27 | ir1X03najh0aeqlVHR7qyN17H5xE1VFn/BQAv4Kw2IbZljZgyIdQQ7yLHhdcoB/S
28 | S4Pewlw6FojuM8PNckqPyQdZh1GKe9W0+XRdWvEynBB70DRO5p0CKxmvNRMiaJe4
29 | PdyErI5hHIoKdDKTS+mIV14DE/3jL1mgdNUbX/2z9nbICmHJgSQNbDsbU8UZliGW
30 | 5BawLNF/ET1b3Z/cUEk9Q7s0rlFOn0AQfAQX3ABkRnRaDBEEw3DHs7QTmCstDhsB
31 | 51KN3tx+yHH0y6KJh8kP+qFvdYWpY3XwD0SphcqaFAw+6iuGXY6nkpYeGedVhsL6
32 | 0h6XrcbPNSNNutk=
33 | -----END CERTIFICATE-----
34 |
--------------------------------------------------------------------------------
/app/orchestration/files/ssl/nginx.key:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQDSHcq/kSHGEbkc
3 | rakcPBdi2BX6qMWMPjbvA8vzoZjRSYdXS8OdMyYSp9StP39xk9zOEmPeCpOEF1GR
4 | +bq8KvOMobXncsaEzU5XIQ7x/0lPQYI0ROekzf9k/9w1eTAYNggCRw0LIPivk5mo
5 | qOv/RZj0oo5tvHE5JnQd69u3Dhx4oy6fY/yqI43ICVVPJMGWwtRzVTl3dS5VcP5E
6 | AgyFh9vp+s2NxLMJfC6aQ3OchLXFdbqg9T9BUIJVlvpgqaJBTF2nW8n0ujJcs6yw
7 | rWa2f9IjPvhIyZanJg9m+NHNW1vUNEoY/mZLiTHyhd8t39Wifx1iemzIJJk6CUna
8 | f8sfUaJj99xydeMoos++UvSU4tIxEavP8Qf0WZm/WtWa9/LQP12XJ8JhqB1Y/1Tk
9 | z1NkFnX5mZxXtWe4/cimx33d/Kb9WyQIlGtUi+SWYSIprlSSqScaMXRjGSJ6X8fG
10 | bvMy0U6mCYJII2grE6Mzcmq1GesNilJ+WSij23NnEo7h2JYleqEikRojeZZgp0tr
11 | m4zeXDmIQAw7N/PQKN+q1Ki+keReP4VuvusiUOi6Qq+20pDH3/1srln0fLmJ4RWv
12 | rIVodgWTPKD7A92PWctphXJZBqqwq3BNT5owlID1ZYnz8Nz9EfxUwM7ral4jcrGe
13 | vzKqDpYBXfr9r1SBstsBLaVCFSNoJQIDAQABAoICAB0n8Shf9TXM48js+Bho5j3b
14 | CkG8BZ2OTIUiG7z04YW5FESyyLQZkuDn1QUtWHvkLrGRr7Xx9cJQkgsVgin2M9GB
15 | 5wH01UM8UfCZL7+40u1ig7TJEvO1egkD0ATDij7x0G6weUjgDGIgsyPKPOUxPSZF
16 | IEpt6bAqe9ZjEhv2o1DCJAgOEdNyF4x4bxQKX6qR4nUWkGDZK9LDWSUKu74Tuhpf
17 | qQJRFx7r0nOphHNlnuuFiJ4pKdvgVhWWW6vqHg+9jwlYHVAOPkrKy93AUg5k8j3d
18 | 0QoYnwUWrPB2+nXqhXWOw/Fv67XzlbC3jt6IvtZLmUI/BrVHDtQU0eC19vOjmkrQ
19 | i6Mf2jeDsXGbcIDV0ci7daeJVurigtB/3Hhldg1tpslYBwhq9JomSuVTTCx7I4e3
20 | fAwBBE6if6dNcI6akMcieDpgre7VjxyxD9Wy557bKB7b/QIvgWe5attmxy2CdQMW
21 | oCW3S7F1bLyLhi0adULRnTTWrxTnkDKU+7pbgSzulBDxZMYAeUY9fi4hHeps19bN
22 | TDfOxjhlKYa9BYZh1eRWXIuup0G/yOCBnW6SP+AINFtScsi73SL54wxVm0BOJo6t
23 | JxUhuFiXi2C7M+Kx9k++w5YQAFEfNXfNsXzDyVN1JZ+sqATdtcLoT0UbKF2YgnTy
24 | zwRAMuyRsOBAj8N74L1JAoIBAQDsPAD9dSXX5Ah1NaqMsSs4IO+JR7s/kJ8ZV2Oa
25 | nl7RSrg3SDs7S7GaooZ2V6Vuxthd4bfAlNHX0H3svLsYbSJt/nUq968I2JmWq7w/
26 | H6iiAatPORAwn2rikXUTSfiVyD+u4qdPClcCre0ZjKaIJ7ST34Yi1zctp+20zC7Y
27 | rFbPaMT5l9JBfpLVKFyHmZfSxDqxIj/lAA6UfdZd9IZRKMuGkp53Dsq0avHdtt7A
28 | IQpdTnCEejSg8vTIK1/3CDq8gQkCQfPCOvxoz5JM/Ru90kI/cgSLNF1w8zHKHg5u
29 | 8IySycX1fh0ppTAmyVtNfmP6VmkZnM79eiT+wnBavQY0WUNLAoIBAQDjslswjVT+
30 | k/UCyeLlSN5Ko9ibl1eiArxNg50okDWllI9dA7yi1s1tc0QbH3Ia7oAgxH3rscBk
31 | ATrIoSf7uIphieFOh/wd7pdjXGUjKdRi8geuYeKS1WTf1b0gz3KZlsvRfwU6y15d
32 | sNBVTNbet1HJsG/3meUzbApAXN6ZHv/Tj06+XVg4u5AmWegUyyVauJesqx5thn/k
33 | 1pnIY50bD0mjBcknLgYAhTTQ5ww3MDmYZ5vdzv6sCUZ49r9kM8PIhpmMzW0jaou8
34 | 6APZzIIzeqRwvcvnSymvyFhD1lk56Yh3vD8e3++XLtO1sQx7g/JHXjza6tkyISq/
35 | UMFtZXIbHGxPAoIBACHFfjq9uZhAgDkJYAVW+p++jZ/pgkpXCXec959ODq4K6YT1
36 | rYoPiydZHrHiW8MXaC0brKI6ZDlfE/F5FaIrT+W7n9JxsDMqi+JvUK0RgJEQfgYI
37 | WVkqISScuMj2JTR8eSYuPs7c4o1+gcvKQLBsRLNzHAD1FW1QeXoESpotIQfrqWUp
38 | ICS+zIzuhTPZcEvwQ5e5FrtNI8h0qOWrpFwL4fSuFztcAPyD4WnZz8RVtN6b7Rfz
39 | RHzR3s6S7Ngq9AKoy7nn5coZlqYBLqAU+xdK7K+XRDEGXmlcSvzjCRsxBlehwswS
40 | qGagt96DoKrWa8KJAeNoeGriQFGvSFKgfTeUnzsCggEADv3gSSsVDIn7WMqoGMaa
41 | dDmjemMVjwI1GblvsIsGLTfB1LL5SZNxBSLQuiRw49sOLpohXFJgw3TdRPZvZoB5
42 | BAELB5umeuYJq64arp0DcdxTqySgwWAxexdck3t1JS2rj8iYNI3NUcfhf6xGfXV+
43 | ehQW2yuTzrXvWtuCgHxtBaXq3lfRBjM7Q3sp76yMchOzUNgXccioRQ3oJCyC3JQ+
44 | GfC4lM7P8FrU5mhAAqY3NJSly43kcLlPnYlJgrRx0JMkKwQfinRqbO6tyjpP3EnX
45 | 5+BnO3xUa1F6lkTXrRt2M8P+N+8wnDimEdFta/h9DDvlL9jEoitS4DPV+Hj0cVqG
46 | uwKCAQBfI4vLMoIyPROY4JJpa1P7bBlAtOKV58SoMkG0FHtUmIXyYLwwavMdN0q2
47 | sOy8I6eKzapWv/EtEfVyJiSzlAj759CQazLg3+8KHaECsWQmBTCTyYEO2hNFoPbJ
48 | 4MtIe0fJrkqjep2ciDBNiBkILfTSpPqLruQqc47nPDejAScb/rklHDbdDmHEIFQ+
49 | DMga2jAWPGCc5eQR/f06q+ZnYdjii81hxM+GfkJ6Ay4j8ZIQDFmP3cvaEjvfV5v2
50 | v0Rds3tynkuoa3LwTV4kb5uSdI6F71aeGHTqwN6rrurYRjxvleGWZbNKXfujFv0i
51 | pd3xWyS6zeBjbcBMunmqR07fBNhI
52 | -----END PRIVATE KEY-----
53 |
--------------------------------------------------------------------------------
/app/orchestration/files/varnish:
--------------------------------------------------------------------------------
1 | # Configuration file for varnish
2 | #
3 | # /etc/init.d/varnish expects the variables $DAEMON_OPTS, $NFILES and $MEMLOCK
4 | # to be set from this shell script fragment.
5 | #
6 | # Note: If systemd is installed, this file is obsolete and ignored. Please see
7 | # /usr/share/doc/varnish/examples/varnish.systemd-drop-in.conf
8 |
9 | # Should we start varnishd at boot? Set to "no" to disable.
10 | START=yes
11 |
12 | # Maximum number of open files (for ulimit -n)
13 | NFILES=131072
14 |
15 | # Maximum locked memory size (for ulimit -l)
16 | # Used for locking the shared memory log in memory. If you increase log size,
17 | # you need to increase this number as well
18 | MEMLOCK=82000
19 |
20 | # Default varnish instance name is the local nodename. Can be overridden with
21 | # the -n switch, to have more instances on a single server.
22 | # You may need to uncomment this variable for alternatives 1 and 3 below.
23 | # INSTANCE=$(uname -n)
24 |
25 | # This file contains 4 alternatives, please use only one.
26 |
27 | ## Alternative 1, Minimal configuration, no VCL
28 | #
29 | # Listen on port 6081, administration on localhost:6082, and forward to
30 | # content server on localhost:8080. Use a 1GB fixed-size cache file.
31 | #
32 | # This example uses the INSTANCE variable above, which you need to uncomment.
33 | #
34 | # DAEMON_OPTS="-a :6081 \
35 | # -T localhost:6082 \
36 | # -b localhost:8080 \
37 | # -u varnish -g varnish \
38 | # -S /etc/varnish/secret \
39 | # -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"
40 |
41 |
42 | ## Alternative 2, Configuration with VCL
43 | #
44 | # Listen on port 6081, administration on localhost:6082, and forward to
45 | # one content server selected by the vcl file, based on the request.
46 | #
47 | DAEMON_OPTS="-a 0.0.0.0:80
48 | -T localhost:6082 \
49 | -f /etc/varnish/default.vcl \
50 | -S /etc/varnish/secret \
51 | -s malloc,256m \
52 | -p http_resp_hdr_len=10000"
53 |
54 | ## Alternative 3, Advanced configuration
55 | #
56 | # This example uses the INSTANCE variable above, which you need to uncomment.
57 | #
58 | # See varnishd(1) for more information.
59 | #
60 | # # Main configuration file. You probably want to change it :)
61 | # VARNISH_VCL_CONF=/etc/varnish/default.vcl
62 | #
63 | # # Default address and port to bind to
64 | # # Blank address means all IPv4 and IPv6 interfaces, otherwise specify
65 | # # a host name, an IPv4 dotted quad, or an IPv6 address in brackets.
66 | # VARNISH_LISTEN_ADDRESS=
67 | # VARNISH_LISTEN_PORT=6081
68 | #
69 | # # Telnet admin interface listen address and port
70 | # VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
71 | # VARNISH_ADMIN_LISTEN_PORT=6082
72 | #
73 | # # Cache file location
74 | # VARNISH_STORAGE_FILE=/var/lib/varnish/$INSTANCE/varnish_storage.bin
75 | #
76 | # # Cache file size: in bytes, optionally using k / M / G / T suffix,
77 | # # or in percentage of available disk space using the % suffix.
78 | # VARNISH_STORAGE_SIZE=1G
79 | #
80 | # # File containing administration secret
81 | # VARNISH_SECRET_FILE=/etc/varnish/secret
82 | #
83 | # # Backend storage specification
84 | # VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"
85 | #
86 | # # Default TTL used when the backend does not specify one
87 | # VARNISH_TTL=120
88 | #
89 | # # DAEMON_OPTS is used by the init script. If you add or remove options, make
90 | # # sure you update this section, too.
91 | # DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
92 | # -f ${VARNISH_VCL_CONF} \
93 | # -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
94 | # -t ${VARNISH_TTL} \
95 | # -S ${VARNISH_SECRET_FILE} \
96 | # -s ${VARNISH_STORAGE}"
97 | #
98 |
99 |
100 | ## Alternative 4, Do It Yourself
101 | #
102 | # DAEMON_OPTS=""
103 |
--------------------------------------------------------------------------------
/app/orchestration/handlers.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Restart SSH
3 | service:
4 | name: ssh
5 | state: restarted
6 |
7 | - name: Restart Apache
8 | service:
9 | name: apache2
10 | state: restarted
11 |
12 | - name: Start Apache
13 | service:
14 | name: apache2
15 | state: started
16 |
17 | - name: Reload Apache
18 | service:
19 | name: apache2
20 | state: reloaded
21 |
22 | - name: Restart PHP-FPM
23 | service:
24 | name: php{{ default_php_version }}-fpm
25 | state: restarted
26 |
27 | - name: Restart MySQL
28 | service:
29 | name: mysql
30 | state: restarted
31 |
32 | - name: Restart Varnish
33 | service:
34 | name: varnish
35 | state: restarted
36 |
37 | - name: Start nginx
38 | service:
39 | name: nginx
40 | state: started
41 |
42 | - name: Reload nginx
43 | service:
44 | name: nginx
45 | state: reloaded
46 |
47 | - name: Restart Solr
48 | shell: "{{ solr_binary }} restart"
49 | become: yes
50 | become_user: solr
51 |
--------------------------------------------------------------------------------
/app/orchestration/hosts:
--------------------------------------------------------------------------------
1 | [drucker_base]
2 | 203.0.113.99
3 |
4 | [drucker_mirror]
5 | 203.0.113.50
6 |
7 | [drucker_edge]
8 | 203.0.113.2
9 |
10 | [drucker_web]
11 | 203.0.113.10
12 |
13 | [drucker_db]
14 | 203.0.113.12
15 |
16 | [drucker_search]
17 | 203.0.113.13
18 |
--------------------------------------------------------------------------------
/app/orchestration/plays/app/delete.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "DELETE: Delete database"
3 | mysql_db:
4 | login_user: "{{ db_creds }}"
5 | login_password: "{{ db_creds }}"
6 | login_host: "{{ db_ip }}"
7 | login_port: "{{ db_port }}"
8 | config_file: "{{ db_config }}"
9 | name: "{{ sitename }}"
10 | state: absent
11 |
12 | - name: "DELETE: Check if docroot exists"
13 | stat:
14 | path: "{{ drupal_root }}"
15 | register: docroot_check
16 | ignore_errors: True
17 |
18 | - name: "DELETE: Delete docroot"
19 | file:
20 | path: "{{ drupal_root }}"
21 | state: absent
22 | force: yes
23 | when: docroot_check.stat.exists == true and sitename != 'import'
24 |
25 | - name: "DELETE: Check if vHost exists"
26 | stat:
27 | path: "{{ sites_enabled }}/{{ sitename }}.conf"
28 | register: apache_conf
29 | ignore_errors: True
30 |
31 | - name: "DELETE: Delete vHost"
32 | file:
33 | path: "{{ item }}"
34 | state: absent
35 | with_items:
36 | - "{{ sites_available }}/{{ sitename }}.conf"
37 | - "{{ sites_enabled }}/{{ sitename }}.conf"
38 | when: apache_conf.stat.exists == true
39 |
40 | - name: "DELETE: Delete Apache log files"
41 | file:
42 | path: "{{ log_dir }}/{{ item }}"
43 | state: absent
44 | with_items:
45 | - "{{ sitename }}-access.log"
46 | - "{{ sitename }}-error.log"
47 | when: apache_conf.stat.exists == true
48 |
49 | - name: "DELETE: Delete Apache log files"
50 | file:
51 | path: "{{ log_dir }}/{{ item }}"
52 | state: absent
53 | with_items:
54 | - "{{ sitename }}-access.log"
55 | - "{{ sitename }}-error.log"
56 | when: apache_conf.stat.exists == true
57 |
58 | # Docker provides the container with a custom /etc/hosts file so we have to hack
59 | # our way through modifying it.
60 | - name: "DELETE: Copy hosts file"
61 | command: cp {{ hosts_file }} {{ tmp_hosts_file }}
62 | when: apache_conf.stat.exists == true
63 |
64 | - name: "DELETE: Remove hosts entry"
65 | lineinfile:
66 | dest: "{{ tmp_hosts_file }}"
67 | line: "{{ web_ip }}\t{{ sitename }}.{{ tld }}"
68 | state: absent
69 | when: apache_conf.stat.exists == true
70 |
71 | - name: "DELETE: Replace hosts file"
72 | command: cp {{ tmp_hosts_file }} {{ hosts_file }}
73 | when: apache_conf.stat.exists == true
74 |
75 | - name: "DELETE: Check if Drush alias exist"
76 | stat:
77 | path: "{{ drush_alias_path }}/{{ sitename }}.{{ drush_alias_extension }}"
78 | register: sitename_alias
79 |
80 | - name: "DELETE: Delete Drush alias"
81 | file:
82 | path: "{{ drush_alias_path }}/{{ sitename }}.{{ drush_alias_extension }}"
83 | state: absent
84 | when: sitename_alias.stat.exists == true
85 |
86 | - import_tasks: ../common/app-registry.yml
87 |
--------------------------------------------------------------------------------
/app/orchestration/plays/app/drupal.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "DRUPAL: Check if new site exists"
3 | stat:
4 | path: "{{ drupal_root }}"
5 | register: new_site
6 | ignore_errors: True
7 |
8 | - name: "DRUPAL: Check if new database exists"
9 | stat:
10 | path: "{{ db_data }}/{{ sitename }}"
11 | register: new_db
12 |
13 | - name: "DRUPAL: Create new site architecture"
14 | file:
15 | path: "{{ drupal_root }}"
16 | state: directory
17 | become: yes
18 | become_user: "{{ user }}"
19 | when: new_site.stat.exists == false
20 |
21 | - name: "DRUPAL: Deploy default composer.json template"
22 | copy:
23 | src: "{{ composer_json_template_file }}"
24 | dest: "{{ drupal_composer_json }}"
25 | mode: 0644
26 | become: yes
27 | become_user: "{{ user }}"
28 | when: new_site.stat.exists == false
29 |
30 | - name: "DRUPAL: Pin Drupal version to specific Git tag"
31 | replace:
32 | dest: "{{ drupal_composer_json }}"
33 | regexp: '^(.*)"drupal/core": "\^8.7"(.*)$'
34 | replace: '\1"drupal/core": "{{ git_tag }}"\2'
35 | when: new_site.stat.exists == false and git_tag is defined
36 |
37 | - name: "DRUPAL: Install vendor dependencies from composer.json file (this can take a while)"
38 | composer:
39 | command: install
40 | working_dir: "{{ drupal_root }}"
41 | become: yes
42 | become_user: "{{ user }}"
43 |
44 | - import_tasks: ../common/drupal-common.yml
45 |
46 | - name: "DRUPAL: Install Drupal"
47 | command: drush --root={{ drupal_root }} site-install standard install_configure_form.enable_update_status_module=NULL -qy --db-url=mysql://{{ db_creds }}:{{ db_creds }}@{{ db_ip }}:{{ db_port }}/{{ sitename }} --site-name={{ sitename }} --site-mail={{ drupal_creds }}@{{ sitename }}.{{ tld }} --account-name={{ drupal_creds }} --account-pass={{ drupal_creds }} --account-mail={{ drupal_creds }}@{{ sitename }}.{{ tld }}
48 | become: yes
49 | become_user: "{{ user }}"
50 | when: new_alias.stat.exists == false
51 |
52 | - name: "DRUPAL: Check if .gitignore exists"
53 | stat:
54 | path: "{{ drupal_root }}/.gitignore"
55 | register: gitignore_check
56 | ignore_errors: True
57 |
58 | - name: "DRUPAL: Create .gitignore file"
59 | copy:
60 | src: "{{ gitignore_source_file }}"
61 | dest: "{{ drupal_root }}"
62 | mode: 0644
63 | become: yes
64 | become_user: "{{ user }}"
65 | when: gitignore_check.stat.exists == false
66 |
67 | - name: "DRUPAL: Initialize Git repository"
68 | shell: git -C {{ drupal_root }} init
69 | args:
70 | warn: no
71 | register: initial_commit
72 | become: yes
73 | become_user: "{{ user }}"
74 | when: gitignore_check.stat.exists == false
75 |
76 | - name: "DRUPAL: Add all new files under version control"
77 | shell: git -C {{ drupal_root }} add --all . && git -C {{ drupal_root }} commit -m "Initial commit"
78 | become: yes
79 | become_user: "{{ user }}"
80 | when: gitignore_check.stat.exists == false
81 |
82 | - name: "DRUPAL: Make sure files dir ownership is correct"
83 | file:
84 | path: "{{ drupal_docroot }}/{{ default_site }}/files"
85 | owner: "{{ user }}"
86 | group: "{{ apache_user }}"
87 | recurse: yes
88 | when: new_site.stat.exists == false or new_db.stat.exists == false
89 |
90 | - name: "DRUPAL: Make sure files dir ownership is correct"
91 | file:
92 | path: "{{ drupal_docroot }}/{{ default_site }}/files"
93 | owner: "{{ user }}"
94 | group: "{{ apache_user }}"
95 | recurse: yes
96 | when: new_site.stat.exists == false or new_db.stat.exists == false
97 |
98 | - import_tasks: ../common/app-registry.yml
99 |
--------------------------------------------------------------------------------
/app/orchestration/plays/app/lightning.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "LIGHTNING: Check if new site exists"
3 | stat:
4 | path: "{{ drupal_root }}"
5 | register: new_site
6 | ignore_errors: True
7 |
8 | - name: "LIGHTNING: Check if new database exists"
9 | stat:
10 | path: "{{ db_data }}/{{ sitename }}"
11 | register: new_db
12 |
13 | # We're using the shell command here, because using the composer command leaves us
14 | # with missing vendor dependencies, for some reason.
15 | - name: "LIGHTNING: Create project with vendor dependencies (this can take a while)"
16 | shell: cd {{ webroot }} && composer create-project acquia/lightning-project {{ sitename }} ^8.6 --no-interaction
17 | become: yes
18 | become_user: "{{ user }}"
19 |
20 | - import_tasks: ../common/drupal-common.yml
21 |
22 | - name: "LIGHTNING: Install Drupal"
23 | command: drush --root={{ drupal_docroot }} site-install lightning install_configure_form.enable_update_status_module=NULL -qy --db-url=mysql://{{ db_creds }}:{{ db_creds }}@{{ db_ip }}:{{ db_port }}/{{ sitename }} --site-name={{ sitename }} --site-mail={{ drupal_creds }}@{{ sitename }}.{{ tld }} --account-name={{ drupal_creds }} --account-pass={{ drupal_creds }} --account-mail={{ drupal_creds }}@{{ sitename }}.{{ tld }}
24 | become: yes
25 | become_user: "{{ user }}"
26 | when: new_alias.stat.exists == false
27 |
28 | - name: "LIGHTNING: Check if phpunit.xml file exists"
29 | stat:
30 | path: "{{ drupal_docroot }}/core/phpunit.xml"
31 | register: lightning_phpunit
32 |
33 | - name: "LIGHTNING: Deploy phpunit.xml file"
34 | copy:
35 | src: "{{ phpunit_source_file }}"
36 | dest: "{{ drupal_docroot }}/core/"
37 | mode: 0644
38 | become: yes
39 | become_user: "{{ user }}"
40 | when: lightning_phpunit.stat.exists == false
41 |
42 | - name: "LIGHTNING: Modify phpunit.xml file"
43 | replace:
44 | dest: "{{ drupal_docroot }}/core/phpunit.xml"
45 | regexp: '^(.*)SITENAME(.*)$'
46 | replace: '\1{{ sitename }}\2'
47 | when: lightning_phpunit.stat.exists == false
48 |
49 | - name: "LIGHTNING: Make sure we're down one level for the PHPUnit path"
50 | replace:
51 | dest: "{{ drupal_docroot }}/core/phpunit.xml"
52 | regexp: '^(.*){{ drupal_root }}(.*)$'
53 | replace: '\1{{ drupal_root }}/docroot\2'
54 | when: lightning_phpunit.stat.exists == false
55 |
56 | - name: "LIGHTNING: Check if .gitignore exists"
57 | stat:
58 | path: "{{ drupal_root }}/.gitignore"
59 | register: lightning_gitignore
60 | ignore_errors: True
61 |
62 | - name: "LIGHTNING: Create .gitignore file"
63 | copy:
64 | src: "{{ gitignore_source_file }}"
65 | dest: "{{ drupal_root }}"
66 | mode: 0644
67 | become: yes
68 | become_user: "{{ user }}"
69 | when: lightning_gitignore.stat.exists == false
70 |
71 | - name: "LIGHTNING: Check if Git repository exists"
72 | stat:
73 | path: "{{ drupal_root }}/.git"
74 | register: lightning_git_repo
75 | ignore_errors: True
76 |
77 | - name: "LIGHTNING: Initialize Git repository"
78 | shell: git -C {{ drupal_root }} init
79 | args:
80 | warn: no
81 | register: initial_commit
82 | become: yes
83 | become_user: "{{ user }}"
84 | when: lightning_git_repo.stat.exists == false
85 |
86 | - name: "LIGHTNING: Add all new files under version control"
87 | shell: git -C {{ drupal_root }} add --all . && git -C {{ drupal_root }} commit -m "Initial commit"
88 | become: yes
89 | become_user: "{{ user }}"
90 | when: lightning_git_repo.stat.exists == false
91 |
92 | - name: "LIGHTNING: Make sure files dir ownership is correct"
93 | file:
94 | path: "{{ drupal_root }}/{{ default_site }}/files"
95 | owner: "{{ user }}"
96 | group: "{{ apache_user }}"
97 | state: directory
98 | recurse: yes
99 | when: new_site.stat.exists == false or new_db.stat.exists == false
100 |
101 | - import_tasks: ../common/app-registry.yml
102 |
--------------------------------------------------------------------------------
/app/orchestration/plays/app/prod.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PROD: Disable settings.local.php"
3 | blockinfile:
4 | dest: "{{ deployed_settings_php }}"
5 | block: |
6 | if (file_exists(__DIR__ . '/settings.local.php')) {
7 | include __DIR__ . '/settings.local.php';
8 | }
9 |
10 | state: absent
11 | marker: "# {mark} MANAGED SETTINGS.LOCAL.PHP BLOCK"
12 |
13 | - name: "PROD: Check if services.yml exists"
14 | stat:
15 | path: "{{ deployed_services_yml }}"
16 | register: deployed_services_yml_prod
17 | ignore_errors: True
18 |
19 | - name: "PROD: Turn off Twig debugging"
20 | replace:
21 | dest: "{{ deployed_services_yml }}"
22 | regexp: '^(.*) debug: true(.*)$'
23 | replace: '\1 debug: false\2'
24 | register: turn_off_twig_debugging
25 | when: deployed_services_yml_prod.stat.exists == true
26 |
27 | - name: "PROD: Turn off Twig auto_reload"
28 | replace:
29 | dest: "{{ deployed_services_yml }}"
30 | regexp: '^(.*) auto_reload: true(.*)$'
31 | replace: '\1 auto_reload: null\2'
32 | when: deployed_services_yml_prod.stat.exists == true
33 |
34 | - name: "PROD: Turn on Twig caching"
35 | replace:
36 | dest: "{{ deployed_services_yml }}"
37 | regexp: '^(.*) cache: false(.*)$'
38 | replace: '\1 cache: true\2'
39 | when: deployed_services_yml_prod.stat.exists == true
40 |
41 | - name: "PROD: Check if the Testing module is installed"
42 | shell: drush --root={{ drupal_root }} pm-list --type=module --status=enabled | grep simpletest | awk '{print $4}'
43 | register: testing_module_check
44 |
45 | - name: "PROD: Uninstall the Testing module"
46 | command: drush --root={{ drupal_root }} pm-uninstall -y simpletest
47 | when: testing_module_check.stdout == "Enabled"
48 |
49 | - name: "PROD: Delete composer.lock file"
50 | file:
51 | path: "{{ drupal_composer_lock }}"
52 | state: absent
53 | force: yes
54 |
55 | - name: "PROD: Deploy composer.json template"
56 | copy:
57 | src: "{{ composer_json_template_file }}"
58 | dest: "{{ drupal_composer_json }}"
59 | mode: 0644
60 | become: yes
61 | become_user: "{{ user }}"
62 |
63 | # We're using the shell command here, because using the composer command leaves us
64 | # with missing vendor dependencies, for some reason.
65 | - name: "PROD: Remove require-dev vendor dependencies (this can take a while)"
66 | shell: composer install
67 | args:
68 | chdir: "{{ drupal_root }}"
69 | become: yes
70 | become_user: "{{ user }}"
71 |
72 | - name: "PROD: Check if phpstan.neon exists"
73 | stat:
74 | path: "{{ phpstan_neon }}"
75 | register: phpstan
76 | ignore_errors: True
77 |
78 | - name: "PROD: Delete phpstan.neon"
79 | file:
80 | path: "{{ phpstan_neon }}"
81 | state: absent
82 | when: phpstan.stat.exists == true
83 |
84 | - name: "PROD: Rebuild Drupal cache"
85 | command: drush --root={{ drupal_root }} cache-rebuild
86 | when: turn_off_twig_debugging.changed
87 |
88 | - name: "PROD: Check the Zend assertions status"
89 | shell: grep "^zend.assertions = 1" "{{ default_php_ini }}" || echo "off"
90 | register: zend_assertions_disable
91 | changed_when: zend_assertions_disable.stdout != "off"
92 |
93 | - name: "PROD: Turn off Zend assertions"
94 | replace:
95 | dest: "{{ default_php_ini }}"
96 | regexp: '^(.*)zend.assertions = 1(.*)$'
97 | replace: '\1zend.assertions = -1\2'
98 | when: zend_assertions_disable.stdout != "off"
99 |
100 | - name: "PROD: Prevent errors from showing up on screen"
101 | replace:
102 | dest: "{{ default_php_ini }}"
103 | regexp: '^(.*)display_errors = On(.*)$'
104 | replace: '\1display_errors = Off\2'
105 | notify: Restart Apache
106 |
--------------------------------------------------------------------------------
/app/orchestration/plays/common/apache-installation.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "APACHE: Check if server is installed"
3 | stat:
4 | path: "{{ apache_security_conf }}"
5 | register: apache
6 | ignore_errors: True
7 |
8 | - name: "APACHE: Install server and web tools"
9 | package:
10 | name: "{{ item }}"
11 | state: present
12 | with_items:
13 | - apache2
14 | - apache2-utils
15 | - goaccess
16 | when: apache.stat.exists == false
17 |
18 | - name: "APACHE: Enable required modules"
19 | apache2_module:
20 | name: "{{ item }}"
21 | state: present
22 | with_items:
23 | - actions
24 | - rewrite
25 | - proxy_http
26 | when: apache.stat.exists == false
27 |
28 | - name: "APACHE: Ensure APACHE_RUN_USER is set to the expected user"
29 | lineinfile:
30 | dest: "{{ apache_envvars }}"
31 | regexp: "export APACHE_RUN_USER=www-data"
32 | line: "export APACHE_RUN_USER={{ user }}"
33 | when: apache.stat.exists == false
34 |
35 | - name: "APACHE: Fix the POODLE SSL v3 vulnerability"
36 | lineinfile:
37 | dest: "{{ apache_ssl_mod }}"
38 | regexp: "SSLProtocol all"
39 | line: "\tSSLProtocol all -SSLv2 -SSLv3"
40 | when: apache.stat.exists == false
41 |
42 | - name: "APACHE: Delete default vHost"
43 | file:
44 | path: "{{ default_vhost }}"
45 | state: absent
46 | when: apache.stat.exists == false
47 |
48 | - name: "APACHE: Delete default vHost symlink"
49 | file:
50 | path: "{{ default_vhost }}"
51 | state: absent
52 | when: apache.stat.exists == false
53 |
54 | - name: "APACHE: Ensure Apache is started"
55 | service:
56 | name: apache2
57 | enabled: yes
58 | state: started
59 |
--------------------------------------------------------------------------------
/app/orchestration/plays/common/apache-vhost-fcgi.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PHP: Store PHP version variable"
3 | shell: cat {{ default_php_version_file }}
4 | register: phpfcgi_read_version
5 |
6 | - name: "PHP: Add support for php-fpm Fast-CGI"
7 | blockinfile:
8 | dest: "{{ sites_available }}/{{ sitename }}.conf"
9 | block: |6
10 | ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/var/run/php/php{{ phpfcgi_read_version.stdout }}-fpm.sock|fcgi://127.0.0.1:9000/var/www/html/{{ sitename }}/docroot/
11 | insertafter: '^(.*)DocumentRoot(.*)$'
12 | marker: "# {mark} MANAGED PHP-FPM FAST-CGI BLOCK"
13 | when: new_vhost_check.stat.exists == false
14 |
--------------------------------------------------------------------------------
/app/orchestration/plays/common/apache-vhost.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "APACHE: Check if new vHost exists"
3 | stat:
4 | path: "{{ sites_enabled }}/{{ sitename }}.conf"
5 | register: new_vhost_check
6 | ignore_errors: True
7 |
8 | - name: "APACHE: Deploy default vHost template"
9 | copy:
10 | src: "{{ apache_template_source_file }}"
11 | dest: "{{ sites_available }}"
12 | mode: 0644
13 | when: new_vhost_check.stat.exists == false
14 |
15 | - name: "APACHE: Rename default vHost template"
16 | command: mv {{ vhost_template }} {{ sites_available }}/{{ sitename }}.conf
17 | when: new_vhost_check.stat.exists == false
18 |
19 | - name: "APACHE: Modify new vHost"
20 | replace:
21 | dest: "{{ sites_available }}/{{ sitename }}.conf"
22 | regexp: '^(.*)SITENAME(.*)$'
23 | replace: '\1{{ sitename }}\2'
24 | when: new_vhost_check.stat.exists == false
25 |
26 | - import_tasks: apache-vhost-fcgi.yml
27 |
28 | - name: "APACHE: Enable new vHost"
29 | file:
30 | src: ../sites-available/{{ sitename }}.conf
31 | dest: "{{ sites_enabled }}/{{ sitename }}.conf"
32 | state: link
33 | force: yes
34 | register: test
35 | notify: Reload Apache
36 | when: new_vhost_check.stat.exists == false
37 |
38 | # Docker provides the container with a custom /etc/hosts file so we have to hack
39 | # our way through modifying it.
40 | - name: "SYSTEM: Copy hosts file"
41 | command: cp {{ hosts_file }} {{ tmp_hosts_file }}
42 | when: new_vhost_check.stat.exists == false
43 |
44 | - name: "SYSTEM: Add new entry"
45 | lineinfile:
46 | dest: "{{ tmp_hosts_file }}"
47 | line: "{{ web_ip }}\t{{ sitename }}.{{ tld }}"
48 | when: new_vhost_check.stat.exists == false
49 |
50 | - name: "SYSTEM: Replace hosts file"
51 | command: cp {{ tmp_hosts_file }} {{ hosts_file }}
52 | when: new_vhost_check.stat.exists == false
53 |
--------------------------------------------------------------------------------
/app/orchestration/plays/common/app-registry.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "APP REGISTRY: Check if app registry file exists"
3 | stat:
4 | path: "{{ app_registry }}"
5 | register: app_registry_file
6 | ignore_errors: True
7 |
8 | - name: "APP REGISTRY: Create app registry file"
9 | copy:
10 | content: ""
11 | dest: "{{ app_registry }}"
12 | force: no
13 | mode: 02444
14 | owner: "{{ user }}"
15 | group: "{{ apache_user }}"
16 | when: app_registry_file.stat.exists == false
17 |
18 | - name: "APP REGISTRY: Register app"
19 | lineinfile:
20 | dest: "{{ app_registry }}"
21 | line: "{{ sitename}} ({{ app }})"
22 | when: app is defined and app != "delete"
23 |
24 | - name: "APP REGISTRY: Unregister app"
25 | lineinfile:
26 | dest: "{{ app_registry }}"
27 | regexp: '^{{ sitename}}'
28 | line: "{{ sitename}} ({{ app }})"
29 | state: absent
30 | when: app is defined and app == "delete"
31 |
--------------------------------------------------------------------------------
/app/orchestration/plays/common/apt-repos.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PHP: Check if deb.sury.org repository exists"
3 | stat:
4 | path: "{{ sury_repo }}"
5 | register: sury_repo_check
6 | changed_when: sury_repo_check.stat.exists == false
7 |
8 | - name: "PHP: Add deb.sury.org GPG signature"
9 | apt_key:
10 | url: "{{ sury_gpg }}"
11 | state: present
12 | validate_certs: no
13 | when: sury_repo_check.stat.exists == false
14 |
15 | - name: "PHP: Add deb.sury.org repository"
16 | apt_repository:
17 | repo: "{{ sury_deb }}"
18 | state: present
19 | changed_when: sury_repo_check.stat.exists == false
20 |
--------------------------------------------------------------------------------
/app/orchestration/plays/common/apt-update.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "SYSTEM: Check if APT cache needs to be updated"
3 | apt:
4 | update_cache: yes
5 | cache_valid_time: 86400
6 | register: apt_cache_check
7 | changed_when: apt_cache_check.cache_updated == true
8 | ignore_errors: true
9 |
10 | - name: "SYSTEM: Update APT cache and upgrade the container"
11 | apt:
12 | upgrade: safe
13 | update_cache: yes
14 | when: apt_cache_check.cache_updated == true
15 | ignore_errors: true
--------------------------------------------------------------------------------
/app/orchestration/plays/common/database.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "MYSQL: Ensure database is wiped before installing"
3 | mysql_db:
4 | login_user: "{{ db_creds }}"
5 | login_password: "{{ db_creds }}"
6 | login_host: "{{ db_ip }}"
7 | login_port: "{{ db_port }}"
8 | name: "{{ sitename }}"
9 | config_file: "{{ db_config }}"
10 | state: absent
11 | when: new_site.stat.exists == false
12 |
13 | - name: "MYSQL: Create new database"
14 | mysql_db:
15 | login_user: "{{ db_creds }}"
16 | login_password: "{{ db_creds }}"
17 | login_host: "{{ db_ip }}"
18 | login_port: "{{ db_port }}"
19 | name: "{{ sitename }}"
20 | config_file: "{{ db_config }}"
21 | state: present
22 | when: new_site.stat.exists == false or new_db.stat.exists == false
23 |
--------------------------------------------------------------------------------
/app/orchestration/plays/common/drucker-config.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "DRUCKER: Check if import directories exist"
3 | stat:
4 | path: "{{ item }}"
5 | with_items:
6 | - "{{ import_dir }}"
7 | - "{{ archives_dir }}"
8 | register: import_directories
9 | ignore_errors: True
10 |
11 | - name: "DRUCKER Create import directories"
12 | file:
13 | path: "{{ item }}"
14 | state: directory
15 | mode: 0755
16 | owner: "{{ user }}"
17 | group: "{{ apache_user }}"
18 | with_items:
19 | - "{{ import_dir }}"
20 | - "{{ archives_dir }}"
21 | when: import_directories.results[0]['item'] or import_directories.results[1]['item']
22 |
23 | - name: "DRUCKER: Check if README file exists"
24 | stat:
25 | path: "{{ imported_readme }}"
26 | register: readme_import
27 |
28 | - name: "DRUCKER: Deploy README file"
29 | copy:
30 | src: "{{ readme_import_source_file }}"
31 | dest: "{{ imported_readme }}"
32 | mode: 0644
33 | owner: "{{ user }}"
34 | group: "{{ apache_user }}"
35 | when: readme_import.stat.exists == false
36 |
--------------------------------------------------------------------------------
/app/orchestration/plays/common/drush-aliases.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "DRUSH: Check if new alias exist"
3 | stat:
4 | path: "{{ drush_alias_path }}/{{ sitename }}.{{ drush_alias_extension }}"
5 | register: new_alias
6 |
7 | - name: "DRUSH: Deploy new alias"
8 | copy:
9 | src: "{{ drush_alias_source_file }}"
10 | dest: "{{ drush_alias_path }}"
11 | mode: 0644
12 | when: new_alias.stat.exists == false
13 | ignore_errors: true
14 |
15 | - name: "DRUSH: Rename default alias"
16 | command: mv {{ drush_alias_filepath }} {{ drush_alias_path }}/{{ sitename }}.{{ drush_alias_extension }}
17 | when: new_alias.stat.exists == false
18 |
19 | - name: "DRUSH: Modify alias"
20 | replace:
21 | dest: "{{ drush_alias_path }}/{{ sitename }}.{{ drush_alias_extension }}"
22 | regexp: '^(.*)SITENAME(.*)$'
23 | replace: '\1{{ sitename }}\2'
24 | when: new_alias.stat.exists == false
25 |
--------------------------------------------------------------------------------
/app/orchestration/plays/common/mirror-deploy.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "MIRROR: Check if apt.conf exists"
3 | stat:
4 | path: "{{ mirror_apt_conf_file }}"
5 | register: apt_conf_exists
6 |
7 | - name: "MIRROR: Deploy apt.conf file"
8 | copy:
9 | src: "{{ mirror_source_file }}"
10 | dest: /etc/apt
11 | mode: 0644
12 | when: apt_conf_exists.stat.exists == false
13 |
14 | - name: "MIRROR: Update apt.conf file with expected values"
15 | replace:
16 | dest: "{{ mirror_apt_conf_file }}"
17 | regexp: '^(.*)HOST:PORT(.*)$'
18 | replace: '\1{{ mirror_host }}:{{ mirror_port }}\2'
19 | when: apt_conf_exists.stat.exists == false
20 |
21 | - name: "MIRROR: Check if the APT mirror hostname is configured"
22 | shell: grep -o "{{ mirror_ip }}" {{ hosts_file }} || echo "absent"
23 | register: mirror_hostname
24 | changed_when: mirror_hostname.stdout == "absent"
25 |
26 | - name: "MIRROR: Make sure the container can talk to the APT mirror proxy"
27 | shell: echo "{{ mirror_ip }} {{ mirror_host }}" >> {{ hosts_file }}
28 | when: mirror_hostname.stdout == "absent"
29 |
--------------------------------------------------------------------------------
/app/orchestration/plays/common/permissions.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PREP: Check if /var/www exists"
3 | stat:
4 | path: "{{ www_dir }}"
5 | register: www_dir_exists
6 |
7 | - name: "PREP: Check /var/www permissions recursively"
8 | command: find "{{ www_dir }}" -not -user "{{ user }}" -o -not -group "{{ apache_user }}"
9 | register: var_www_permissions
10 | when: www_dir_exists.stat.exists == true
11 | changed_when: var_www_permissions.stdout != ""
12 |
13 | - name: "PREP: Ensure /var/www has correct permissions recursively"
14 | file:
15 | path: "{{ www_dir }}"
16 | owner: "{{ user }}"
17 | group: "{{ apache_user }}"
18 | mode: g+s
19 | recurse: yes
20 | when: www_dir_exists.stat.exists == true and var_www_permissions.stdout != ""
21 |
--------------------------------------------------------------------------------
/app/orchestration/plays/db/adminer.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "ADMINER: Check if software is installed"
3 | stat:
4 | path: "{{ adminer_index }}"
5 | register: adminer
6 | ignore_errors: True
7 |
8 | - name: "ADMINER: Check version"
9 | shell: grep -o "version {{ adminer_stable_release }}" {{ adminer_index }} || echo "update"
10 | register: adminer_release
11 | when: adminer.stat.exists == true
12 | changed_when: adminer_release == "update"
13 |
14 | - name: "ADMINER: Create adminer directory"
15 | file:
16 | path: "{{ adminer_root }}"
17 | state: directory
18 | mode: 0755
19 | owner: "{{ user }}"
20 | group: "{{ apache_user }}"
21 | when: adminer.stat.exists == false
22 |
23 | - name: "ADMINER: Copy latest release from mirror"
24 | get_url:
25 | url: "{{ adminer_mirror_download_link }}"
26 | dest: "{{ adminer_root }}"
27 | validate_certs: no
28 | register: adminer_get_url_result
29 | until: "'OK' in adminer_get_url_result.msg"
30 | retries: 3
31 | delay: 10
32 | when: adminer.stat.exists == false or adminer_release.stdout == "update"
33 |
34 | - name: "ADMINER: Rename file"
35 | command: mv {{ adminer_root }}/adminer-{{ adminer_stable_release }}-en.php {{ adminer_index }}
36 | when: adminer.stat.exists == false or adminer_release.stdout == "update"
37 |
38 | - name: "ADMINER: Ensure permissions are correct"
39 | file:
40 | path: "{{ adminer_index }}"
41 | owner: "{{ user }}"
42 | group: "{{ apache_user }}"
43 | when: adminer.stat.exists == false or adminer_release.stdout == "update"
44 |
45 | - name: "ADMINER: Check if vHost exists"
46 | stat:
47 | path: "{{ adminer_vhost }}"
48 | register: adminer_conf
49 | ignore_errors: True
50 |
51 | - name: "ADMINER: Deploy default vHost template"
52 | copy:
53 | src: "{{ source_file_dir}}/apache-template.conf"
54 | dest: "{{ sites_available }}"
55 | mode: 0644
56 | when: adminer_conf.stat.exists == false
57 |
58 | - name: "ADMINER: Rename default vHost template"
59 | command: mv {{ vhost_template }} {{ adminer_available_vhost }}
60 | when: adminer_conf.stat.exists == false
61 |
62 | - name: "ADMINER: Add support for php-fpm Fast-CGI"
63 | blockinfile:
64 | dest: "{{ adminer_available_vhost }}"
65 | block: |6
66 | ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/var/run/php/php{{ default_php_version }}-fpm.sock|fcgi://127.0.0.1:9000/var/www/html/adminer/
67 | insertafter: '^(.*)DocumentRoot(.*)$'
68 | marker: "# {mark} MANAGED PHP-FPM FAST-CGI BLOCK"
69 | when: adminer_conf.stat.exists == false
70 |
71 | - name: "ADMINER: Modify vHost 1/2"
72 | replace:
73 | dest: "{{ adminer_available_vhost }}"
74 | regexp: '^(.*)SITENAME\/docroot(.*)$'
75 | replace: '\1adminer\2'
76 | when: adminer_conf.stat.exists == false
77 |
78 | - name: "ADMINER: Modify vHost 2/2"
79 | replace:
80 | dest: "{{ adminer_available_vhost }}"
81 | regexp: '^(.*)SITENAME(.*)$'
82 | replace: '\1adminer\2'
83 | when: adminer_conf.stat.exists == false
84 |
85 | - name: "ADMINER: Enable vHost"
86 | file:
87 | src: ../sites-available/adminer.conf
88 | dest: "{{ adminer_vhost }}"
89 | state: link
90 | notify: Reload Apache
91 | when: adminer_conf.stat.exists == false
92 |
--------------------------------------------------------------------------------
/app/orchestration/plays/db/db-tools.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "MEMCACHED: Install libmemcached-tools package"
3 | package:
4 | # Provides memcstat.
5 | name: libmemcached-tools
6 | state: present
7 |
8 | - name: "MYSQL: Ensure we can manage remote MySQL databases"
9 | package:
10 | name: "{{ item }}"
11 | state: present
12 | with_items:
13 | - python-mysqldb
14 | - mysql-client
15 |
16 | - import_tasks: phpmyadmin.yml
17 | - import_tasks: adminer.yml
18 |
--------------------------------------------------------------------------------
/app/orchestration/plays/db/memcached.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "MEMCACHED: Install software"
3 | package:
4 | name: "{{ item }}"
5 | state: present
6 | with_items:
7 | - memcached
8 |
9 | - name: "MEMCACHED: Check if daemon is started"
10 | shell: pgrep memcached || echo "not started"
11 | register: memcached_status
12 | changed_when: memcached_status.stdout == "not started"
13 |
14 | - name: "MEMCACHED: Start the daemon"
15 | command: memcached -d -u nobody -m 64 -p 11211 127.0.0.1
16 | when: memcached_status.stdout == "not started"
17 |
--------------------------------------------------------------------------------
/app/orchestration/plays/db/mysql-backup.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "MYSQL: Check if backup directory exists"
3 | stat:
4 | path: "{{ db_backup_dir }}"
5 | register: backup_dir
6 | changed_when: backup_dir.stat.exists == false
7 |
8 | - name: "MYSQL: Create backup directory"
9 | file:
10 | path: "{{ db_backup_dir }}"
11 | state: directory
12 | when: backup_dir.stat.exists == false
13 |
14 | - name: "MYSQL: Check if backup script exists"
15 | stat:
16 | path: "{{ db_backup_path }}"
17 | register: mysql_backup_check
18 | changed_when: mysql_backup_check.stat.exists == false
19 |
20 | - name: "MYSQL: Deploy backup script"
21 | copy:
22 | src: "{{ db_backup_source_file }}"
23 | dest: "{{ user_programs_path }}"
24 | mode: 0755
25 | when: mysql_backup_check.stat.exists == false
26 |
27 | - name: "MYSQL: Schedule periodic backups"
28 | cron:
29 | name: "Hourly MySQL backup for all databases"
30 | job: "{{ db_backup_path }}"
31 | user: root
32 | minute: "02"
33 | state: present
34 |
35 | - name: "MYSQL: Schedule periodic backup cleanup"
36 | cron:
37 | name: "Clean up MySQL backups every 3 hours"
38 | job: /usr/bin/find {{ db_backup_dir }} -mmin +180 -name "*.gz" -exec rm -f {} \;
39 | user: root
40 | minute: "05"
41 | state: present
42 |
43 | - name: "MYSQL: Restart cron to take into account new crontab"
44 | service:
45 | name: cron
46 | enabled: yes
47 | state: restarted
48 |
--------------------------------------------------------------------------------
/app/orchestration/plays/db/mysql.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "MYSQL: Check if server is installed"
3 | stat:
4 | path: "{{ db_config }}"
5 | register: mariadb
6 | ignore_errors: True
7 |
8 | - name: "MYSQL: Clean up data directory"
9 | shell: rm -Rf {{ db_data }}/*
10 | args:
11 | warn: no
12 | when: mariadb.stat.exists == false
13 |
14 | - name: "MYSQL: Install server and utilities"
15 | package:
16 | name: "{{ item }}"
17 | state: present
18 | force: yes
19 | with_items:
20 | - mariadb-server
21 | - python-mysqldb
22 | when: mariadb.stat.exists == false
23 |
24 | - name: "MYSQL: Set innodb_file_per_table"
25 | blockinfile:
26 | dest: "{{ db_config }}"
27 | block: |
28 | innodb_file_per_table = 1
29 | insertafter: '^\[mysqld\]'
30 | marker: "# {mark} MANAGED INNODB BLOCK"
31 | when: mariadb.stat.exists == false
32 |
33 | - name: "MYSQL: Check if server is configured to allow remote access"
34 | shell: grep -o "0.0.0.0" {{ db_config }} || echo "denied"
35 | register: db_config_remote_access
36 | changed_when: db_config_remote_access == "denied"
37 |
38 | - name: "MYSQL: Configure server to allow remote access"
39 | replace:
40 | dest: "{{ db_config }}"
41 | regexp: '^(.*)127.0.0.1(.*)$'
42 | replace: '\1 0.0.0.0\2'
43 | when: db_config_remote_access.stdout == "denied"
44 |
45 | # Permissions can randomly be messed up so we're fixing them every time we get
46 | # the chance.
47 | - name: "MYSQL: Set correct permissions and ownership"
48 | file:
49 | path: "{{ db_data }}"
50 | owner: mysql
51 | group: mysql
52 | mode: 0755
53 |
54 | - name: "MYSQL: Start server"
55 | service:
56 | name: "{{ item }}"
57 | state: started
58 | enabled: yes
59 | with_items:
60 | - mysql
61 | when: mariadb.stat.exists == false
62 |
63 | - name: "MYSQL: Set root user password"
64 | mysql_user:
65 | login_user: "{{ db_creds }}"
66 | login_password: "{{ db_creds }}"
67 | name: "{{ db_creds }}"
68 | password: "{{ db_creds }}"
69 | check_implicit_admin: yes
70 | state: present
71 | when: mariadb.stat.exists == false
72 |
73 | - name: "MYSQL: Ensure server is started"
74 | service:
75 | name: mysql
76 | enabled: yes
77 | state: started
78 |
79 | - name: "MYSQL: Grant remote user access to all databases"
80 | mysql_user:
81 | login_user: "{{ db_creds }}"
82 | login_password: "{{ db_creds }}"
83 | login_host: localhost
84 | name: "{{ db_creds }}"
85 | password: "{{ db_creds }}"
86 | priv: "*.*:ALL"
87 | host: "{{ web_ip }}"
88 | state: present
89 |
90 | - name: "MYSQL: Ensure server is restarted"
91 | service:
92 | name: mysql
93 | enabled: yes
94 | state: restarted
95 |
--------------------------------------------------------------------------------
/app/orchestration/plays/drupal/drupal-create.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_web
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - vars.yml
8 | handlers:
9 | - import_tasks: handlers.yml
10 | tasks:
11 | - import_tasks: plays/drupal/drupal-create.yml
12 |
--------------------------------------------------------------------------------
/app/orchestration/plays/drupal/drupal-tools.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - import_tasks: ../tools/drush.yml
3 | - import_tasks: ../tools/drupal-console.yml
4 |
--------------------------------------------------------------------------------
/app/orchestration/plays/drupal/drupal.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - import_tasks: ../app/drupal.yml
3 | vars:
4 | sitename: "drucker"
5 |
--------------------------------------------------------------------------------
/app/orchestration/plays/edge/nginx.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "NGINX: Check if server is installed"
3 | stat:
4 | path: "{{ nginx_conf }}"
5 | register: nginx
6 | ignore_errors: True
7 |
8 | - name: "NGINX: Install server"
9 | package:
10 | name: "{{ item }}"
11 | state: present
12 | update_cache: yes
13 | with_items:
14 | - nginx
15 | when: nginx.stat.exists == false
16 |
17 | - name: "NGINX: Check if default site exists"
18 | stat:
19 | path: "{{ nginx_default_site }}"
20 | register: nginx_default
21 | ignore_errors: True
22 |
23 | - name: "NGINX: Delete default site"
24 | file:
25 | path: "{{ nginx_default_site }}"
26 | state: absent
27 | when: nginx_default.stat.exists == true
28 |
29 | - name: "NGINX: Check if default site configuration exists"
30 | stat:
31 | path: "{{ nginx_default_conf }}"
32 | register: nginx_default_configuration
33 | ignore_errors: True
34 |
35 | - name: "NGINX: Delete default site configuration"
36 | file:
37 | path: "{{ nginx_default_conf }}"
38 | state: absent
39 | when: nginx_default_configuration.stat.exists == true
40 |
41 | - name: "NGINX: Check if drucker host exists"
42 | stat:
43 | path: "{{ drucker_nginx_vhost }}"
44 | register: nginx_drucker_host
45 | ignore_errors: True
46 |
47 | - name: "NGINX: Deploy template"
48 | copy:
49 | src: "{{ nginx_template_source_file }}"
50 | dest: "{{ nginx_conf_dir }}"
51 | mode: 0644
52 | when: nginx_drucker_host.stat.exists == false
53 |
54 | - name: "NGINX: Rename template"
55 | command: mv {{ nginx_default_template }} {{ drucker_nginx_vhost }}
56 | when: nginx_drucker_host.stat.exists == false
57 |
58 | - name: "NGINX: Modify proxy_pass"
59 | replace:
60 | dest: "{{ drucker_nginx_vhost }}"
61 | regexp: '^(.*)proxy_pass http://0.0.0.0:{{ edge_port }};(.*)$'
62 | replace: '\1proxy_pass http://{{ web_ip }}:{{ edge_port }};\2'
63 | when: nginx_drucker_host.stat.exists == false
64 |
65 | - name: "NGINX: Increase client_max_body_size"
66 | lineinfile:
67 | dest: "{{ nginx_conf }}"
68 | insertafter: '^(.*)sendfile on;(.*)$'
69 | line: " client_max_body_size {{ client_max_body_size }};"
70 |
71 | - name: "NGINX: Support fake SSL"
72 | copy:
73 | src: "{{ ssl_source_dir }}"
74 | dest: "{{ nginx_conf_dir }}"
75 | mode: 0755
76 | when: nginx_drucker_host.stat.exists == false
77 |
78 | - name: "NGINX: Ensure server starts on boot"
79 | service:
80 | name: nginx
81 | enabled: yes
82 | when: nginx_drucker_host.stat.exists == false
83 |
84 | - name: "NGINX: Check if server is started"
85 | shell: pgrep nginx || echo 'down'
86 | register: check_nginx_up
87 | changed_when: check_nginx_up.stdout == "down"
88 |
89 | - name: "NGINX: Ensure server is started"
90 | command: /etc/init.d/nginx start
91 | become: yes
92 | when: check_nginx_up.stdout == "down"
93 |
--------------------------------------------------------------------------------
/app/orchestration/plays/edge/varnish.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "VARNISH: Check if server is installed"
3 | stat:
4 | path: "{{ varnish_config }}"
5 | register: varnish
6 | ignore_errors: True
7 |
8 | - name: "VARNISH: Install server"
9 | package:
10 | name: "{{ item }}"
11 | state: present
12 | update_cache: yes
13 | with_items:
14 | - varnish
15 | when: varnish.stat.exists == false
16 |
17 | - name: "VARNISH: Deploy configuration template"
18 | copy:
19 | src: "{{ varnish_conf_source_file }}"
20 | dest: /etc/default/
21 | mode: 0644
22 | when: varnish.stat.exists == false
23 |
24 | - name: "VARNISH: Deploy default VCL template"
25 | copy:
26 | src: "{{ varnish_default_vcl_source_file}}"
27 | dest: "{{ varnish_default_path }}"
28 | mode: 0644
29 | when: varnish.stat.exists == false
30 |
31 | - name: "VARNISH: Ensure server is started"
32 | service:
33 | name: varnish
34 | enabled: yes
35 | state: started
36 |
--------------------------------------------------------------------------------
/app/orchestration/plays/mirror/mirror-setup.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "APT-CACHER-NG: Check if APT cache mirror exists"
3 | stat:
4 | path: "{{ mirror_cache_dir }}"
5 | register: mirror_cache_dir_check
6 | changed_when: mirror_cache_dir_check.stat.exists == false
7 |
8 | - name: "APT-CACHER-NG: Install APT cache mirror"
9 | package:
10 | name: apt-cacher-ng
11 | state: present
12 | force: yes
13 | when: mirror_cache_dir_check.stat.exists == false
14 |
15 | - name: "APT-CACHER-NG: Check if the APT mirror is configured to allow remote access"
16 | shell: grep -o "BindAddress:\ 0.0.0.0" {{ mirror_config }} || echo "denied"
17 | register: mirror_remote_access
18 | changed_when: mirror_remote_access.stdout == "denied"
19 |
20 | - name: "APT-CACHER-NG: Configure the APT mirror to allow remote access"
21 | lineinfile:
22 | dest: "{{ mirror_config }}"
23 | line: "BindAddress: 0.0.0.0"
24 | insertafter: EOF
25 | when: mirror_remote_access.stdout == "denied"
26 |
27 | - name: "APT-CACHER-NG: Check if the APT mirror is configured to run as a service"
28 | shell: grep -o "# PidFile" {{ mirror_config }} || echo "configured"
29 | register: mirror_service
30 | changed_when: mirror_service.stdout != "configured"
31 |
32 | - name: "APT-CACHER-NG: Enable the APT mirror to run as a service"
33 | lineinfile:
34 | dest: "{{ mirror_config }}"
35 | regexp: "# PidFile: /var/run/apt-cacher-ng/pid"
36 | line: "PidFile: /var/run/apt-cacher-ng/pid"
37 | when: mirror_service.stdout != "configured"
38 |
39 | - name: "APT-CACHER-NG: Check if the APT mirror is configured to run as a service"
40 | shell: grep -E "^PassThroughPattern:\ .*" {{ mirror_config }} || echo "not configured"
41 | register: passthrough
42 | changed_when: passthrough.stdout == "not configured"
43 |
44 | - name: "APT-CACHER-NG: Enable SSL/TLS support"
45 | lineinfile:
46 | dest: "{{ mirror_config }}"
47 | line: "PassThroughPattern: .*"
48 | insertafter: "^# PassThroughPattern: .* # this would allow CONNECT to everything"
49 | when: passthrough.stdout == "not configured"
50 |
51 | - name: "APT-CACHER-NG: Restart APT mirror service"
52 | service:
53 | name: apt-cacher-ng
54 | enabled: yes
55 | state: restarted
56 | when: mirror_cache_dir_check.stat.exists == false
57 |
58 | - import_tasks: ../common/apt-update.yml
59 |
60 | - name: "SYSTEM: Ensure Apache is started"
61 | service:
62 | name: apache2
63 | enabled: yes
64 | state: started
65 |
66 | - name: "APT-CACHER-NG: Ensure APT mirror service is started"
67 | service:
68 | name: apt-cacher-ng
69 | enabled: yes
70 | state: started
71 |
--------------------------------------------------------------------------------
/app/orchestration/plays/mirror/mirror-vhost.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "APACHE: Check if new vHost exists"
3 | stat:
4 | path: "{{ sites_enabled }}/{{ mirror_conf }}"
5 | register: mirror_vhost_check
6 | ignore_errors: True
7 |
8 | - name: "APACHE: Delete default vHost"
9 | file:
10 | path: "{{ item }}"
11 | state: absent
12 | with_items:
13 | - "{{ default_vhost }}"
14 | - "{{ default_available_vhost }}"
15 | when: mirror_vhost_check.stat.exists == false
16 |
17 | - name: "APACHE: Deploy default vHost template"
18 | copy:
19 | src: "{{ apache_template_source_file }}"
20 | dest: "{{ sites_available }}"
21 | mode: 0644
22 | when: mirror_vhost_check.stat.exists == false
23 |
24 | - name: "APACHE: Rename default vHost template"
25 | command: mv {{ vhost_template }} {{ sites_available }}/{{ mirror_conf }}
26 | when: mirror_vhost_check.stat.exists == false
27 |
28 | - name: "APACHE: Modify new vHost 1/2"
29 | replace:
30 | dest: "{{ sites_available }}/{{ mirror_conf }}"
31 | regexp: '^(.*)/var/www/html/SITENAME/docroot(.*)$'
32 | replace: '\1{{ mirror_archives_dir }}\2'
33 | when: mirror_vhost_check.stat.exists == false
34 |
35 | - name: "APACHE: Modify new vHost 2/2"
36 | replace:
37 | dest: "{{ sites_available }}/{{ mirror_conf }}"
38 | regexp: '^(.*)SITENAME(.*)$'
39 | replace: '\1mirror\2'
40 | when: mirror_vhost_check.stat.exists == false
41 |
42 | - name: "APACHE: Enable new vHost"
43 | file:
44 | src: ../sites-available/{{ mirror_conf }}
45 | dest: "{{ sites_enabled }}/{{ mirror_conf }}"
46 | state: link
47 | force: yes
48 | register: test
49 | notify: Reload Apache
50 | when: mirror_vhost_check.stat.exists == false
51 |
--------------------------------------------------------------------------------
/app/orchestration/plays/php/default-php.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PHP: Check if the version file exists"
3 | stat:
4 | path: "{{ default_php_version_file }}"
5 | register: php_version_file_check
6 |
7 | - name: "PHP: Check which PHP version is currently running"
8 | shell: grep -o "{{ default_php_version }}" {{ default_php_version_file }} || echo "Different version"
9 | register: current_php
10 | when: php_version_file_check.stat.exists == true
11 |
12 | - name: "PHP: Check if PHP {{ default_php_version }} is installed"
13 | stat:
14 | path: "{{ default_php_ini }}"
15 | register: default_phpfpm
16 |
17 | - name: "PHP: Install PHP {{ default_php_version }} core packages"
18 | package:
19 | name: "{{ item }}"
20 | state: present
21 | with_items:
22 | - php{{ default_php_version }}-fpm
23 | - php{{ default_php_version }}-cli
24 | - php{{ default_php_version }}-common
25 | - php{{ default_php_version }}-dev
26 | when: default_phpfpm.stat.exists == false
27 |
28 | - name: "PHP: Write default PHP version to file"
29 | copy:
30 | content: "{{ default_php_version }}"
31 | dest: "{{ default_php_version_file }}"
32 | when: php_version_file_check.stat.exists == false
33 |
34 | - name: "PHP: Install PHP {{ default_php_version }} extensions"
35 | package:
36 | name: "{{ item }}"
37 | state: present
38 | with_items:
39 | - php-imagick
40 | - php-memcached
41 | - php{{ default_php_version }}-apcu
42 | - php{{ default_php_version }}-curl
43 | - php{{ default_php_version }}-gd
44 | - php{{ default_php_version }}-mbstring
45 | - php{{ default_php_version }}-mysql
46 | - php{{ default_php_version }}-xmlrpc
47 | - php{{ default_php_version }}-xsl
48 | - php{{ default_php_version }}-bz2
49 | - php{{ default_php_version }}-sqlite3
50 | when: default_phpfpm.stat.exists == false
51 |
52 | - name: "PHP: Ensure PHP {{ default_php_version }} extensions directory exists"
53 | file:
54 | path: "{{ default_php_extensions }}"
55 | state: directory
56 | when: default_phpfpm.stat.exists == false
57 |
58 | - import_tasks: php_version_and_vhost_check.yml
59 |
60 | - name: "PHP: Update PHP FPM version in vHosts"
61 | replace:
62 | dest: "{{ item }}"
63 | regexp: '^(.*)php{{ php_read_version.stdout }}-fpm.sock(.*)$'
64 | replace: '\1php{{ default_php_version }}-fpm.sock\2'
65 | with_items:
66 | - "{{ apache_vhosts_list.stdout_lines }}"
67 | when: apache_vhosts_list.stdout != 'no vHost'
68 |
69 | - name: "PHP: Switch PHP CLI version"
70 | command: update-alternatives --set php /usr/bin/php{{ default_php_version }}
71 |
72 | - import_tasks: phpfpm_process_check.yml
73 |
74 | - name: "PHP: Start PHP {{ default_php_version }} FPM"
75 | command: /etc/init.d/php{{ default_php_version }}-fpm start
76 | when: default_php_version != php_read_version.stdout or phpfpm_is_started.stdout == 'stopped'
77 |
78 | - name: "PHP: Ensure PHP {{ default_php_version }} is started"
79 | shell: pgrep -ln php-fpm | awk '{print $NF}'
80 | register: default_phpfpm_is_started
81 | notify: Restart Apache
82 |
83 | - name: "PHP: Write new version to file"
84 | copy:
85 | content: "{{ default_php_version }}"
86 | dest: "{{ default_php_version_file }}"
87 |
88 | - import_tasks: default_php_ini.yml
89 |
--------------------------------------------------------------------------------
/app/orchestration/plays/php/default_php_ini.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PHP: Increase max_input_time"
3 | lineinfile:
4 | dest: "{{ default_php_ini }}"
5 | regexp: "max_input_time = 60"
6 | line: "max_input_time = {{ max_input_time }}"
7 | when: default_phpfpm.stat.exists == false
8 |
9 | - name: "PHP: Increase max_execution_time"
10 | lineinfile:
11 | dest: "{{ default_php_ini }}"
12 | regexp: "max_execution_time = 30"
13 | line: "max_execution_time = {{ max_execution_time }}"
14 | when: default_phpfpm.stat.exists == false
15 |
16 | - name: "PHP: Increase memory_limit"
17 | lineinfile:
18 | dest: "{{ default_php_ini }}"
19 | regexp: "memory_limit = 128M"
20 | line: "memory_limit = {{ memory_limit }}"
21 | when: default_phpfpm.stat.exists == false
22 |
23 | - name: "PHP: Increase upload_max_filesize"
24 | lineinfile:
25 | dest: "{{ default_php_ini }}"
26 | regexp: "upload_max_filesize = 2M"
27 | line: "upload_max_filesize = {{ upload_max_filesize }}"
28 | when: default_phpfpm.stat.exists == false
29 |
30 | - name: "PHP: Increase max_file_uploads"
31 | lineinfile:
32 | dest: "{{ default_php_ini }}"
33 | regexp: "max_file_uploads = 20"
34 | line: "max_file_uploads = {{ max_file_uploads }}"
35 | when: default_phpfpm.stat.exists == false
36 |
37 | - name: "PHP: Increase post_max_size"
38 | lineinfile:
39 | dest: "{{ default_php_ini }}"
40 | regexp: "post_max_size = 8M"
41 | line: "post_max_size = {{ post_max_size }}"
42 | when: default_phpfpm.stat.exists == false
43 |
44 | - name: "PHP: Increase opcache.max_accelerated_files"
45 | lineinfile:
46 | dest: "{{ default_php_ini }}"
47 | regexp: ";opcache.max_accelerated_files=2000"
48 | line: "opcache.max_accelerated_files={{ opcache_max_accelerated_files }}"
49 | when: default_phpfpm.stat.exists == false
50 |
51 | - name: "PHP: Turn off Zend assertions"
52 | replace:
53 | dest: "{{ default_php_ini }}"
54 | regexp: '^(.*)zend.assertions = 1(.*)$'
55 | replace: '\1zend.assertions = -1\2'
56 | when: default_phpfpm.stat.exists == false
57 |
58 | - name: "PHP: Add default timezone"
59 | lineinfile:
60 | dest: "{{ default_php_ini_cli }}"
61 | regexp: ";date.timezone ="
62 | line: "date.timezone = {{ timezone }}"
63 | notify: Restart Apache
64 | when: default_phpfpm.stat.exists == false
65 |
--------------------------------------------------------------------------------
/app/orchestration/plays/php/legacy-php.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PHP: Check if the version file exists"
3 | stat:
4 | path: "{{ default_php_version_file }}"
5 | register: php_version_file_check
6 |
7 | - name: "PHP: Check which PHP version is currently running"
8 | shell: grep -o "{{ legacy_php_version }}" {{ default_php_version_file }} || echo "Different version"
9 | when: php_version_file_check.stat.exists == true
10 | register: current_php
11 |
12 | - name: "PHP: Check if PHP {{ legacy_php_version}} is installed"
13 | stat:
14 | path: "{{ legacy_php_ini }}"
15 | register: legacy_phpfpm
16 |
17 | - name: "PHP: Install PHP {{ legacy_php_version}} core packages"
18 | package:
19 | name: "{{ item }}"
20 | state: present
21 | with_items:
22 | - php{{ legacy_php_version }}-fpm
23 | - php{{ legacy_php_version }}-cli
24 | - php{{ legacy_php_version }}-common
25 | - php{{ legacy_php_version }}-dev
26 | when: legacy_phpfpm.stat.exists == false
27 |
28 | - name: "PHP: Install PHP {{ legacy_php_version}} extensions"
29 | package:
30 | name: "{{ item }}"
31 | state: present
32 | with_items:
33 | - php-imagick
34 | - php-memcached
35 | - php{{ legacy_php_version }}-apcu
36 | - php{{ legacy_php_version }}-curl
37 | - php{{ legacy_php_version }}-gd
38 | - php{{ legacy_php_version }}-mbstring
39 | - php{{ legacy_php_version }}-mysql
40 | - php{{ legacy_php_version }}-xmlrpc
41 | - php{{ legacy_php_version }}-xsl
42 | - php{{ legacy_php_version }}-bz2
43 | - php{{ legacy_php_version }}-sqlite3
44 | when: legacy_phpfpm.stat.exists == false
45 |
46 | - name: "PHP: Ensure PHP {{ legacy_php_version }} extensions directory exists"
47 | file:
48 | path: "{{ legacy_php_extensions }}"
49 | state: directory
50 | when: legacy_phpfpm.stat.exists == false
51 |
52 | - import_tasks: php_version_and_vhost_check.yml
53 |
54 | - name: "PHP: Update PHP FPM version in vHosts"
55 | replace:
56 | dest: "{{ item }}"
57 | regexp: '^(.*)php{{ php_read_version.stdout }}-fpm.sock(.*)$'
58 | replace: '\1php{{ legacy_php_version }}-fpm.sock\2'
59 | with_items:
60 | - "{{ apache_vhosts_list.stdout_lines }}"
61 | when: apache_vhosts_list.stdout != 'no vHost'
62 |
63 | - name: "PHP: Switch PHP CLI version"
64 | command: update-alternatives --set php /usr/bin/php{{ legacy_php_version }}
65 |
66 | - import_tasks: phpfpm_process_check.yml
67 |
68 | - name: "PHP: Start PHP {{ legacy_php_version}} FPM"
69 | command: /etc/init.d/php{{ legacy_php_version }}-fpm start
70 | when: legacy_php_version != php_read_version.stdout or phpfpm_is_started.stdout == 'stopped'
71 |
72 | - name: "PHP: Ensure PHP {{ legacy_php_version}} FPM is started"
73 | shell: pgrep -ln php-fpm | awk '{print $NF}'
74 | register: legacy_phpfpm_is_started
75 | notify: Restart Apache
76 |
77 | - name: "PHP: Write new PHP version to file"
78 | copy:
79 | content: "{{ legacy_php_version }}"
80 | dest: "{{ default_php_version_file }}"
81 | when: legacy_phpfpm_is_started.changed
82 |
83 | - import_tasks: legacy_php_ini.yml
84 |
--------------------------------------------------------------------------------
/app/orchestration/plays/php/legacy_php_ini.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PHP: Increase max_input_time"
3 | lineinfile:
4 | dest: "{{ legacy_php_ini }}"
5 | regexp: "max_input_time = 60"
6 | line: "max_input_time = {{ max_input_time }}"
7 | when: legacy_phpfpm.stat.exists == false
8 |
9 | - name: "PHP: Increase max_execution_time"
10 | lineinfile:
11 | dest: "{{ legacy_php_ini }}"
12 | regexp: "max_execution_time = 30"
13 | line: "max_execution_time = {{ max_execution_time }}"
14 | when: legacy_phpfpm.stat.exists == false
15 |
16 | - name: "PHP: Increase memory_limit"
17 | lineinfile:
18 | dest: "{{ legacy_php_ini }}"
19 | regexp: "memory_limit = 128M"
20 | line: "memory_limit = {{ memory_limit }}"
21 | when: legacy_phpfpm.stat.exists == false
22 |
23 | - name: "PHP: Increase upload_max_filesize"
24 | lineinfile:
25 | dest: "{{ legacy_php_ini }}"
26 | regexp: "upload_max_filesize = 2M"
27 | line: "upload_max_filesize = {{ upload_max_filesize }}"
28 | when: legacy_phpfpm.stat.exists == false
29 |
30 | - name: "PHP: Increase max_file_uploads"
31 | lineinfile:
32 | dest: "{{ legacy_php_ini }}"
33 | regexp: "max_file_uploads = 20"
34 | line: "max_file_uploads = {{ max_file_uploads }}"
35 | when: legacy_phpfpm.stat.exists == false
36 |
37 | - name: "PHP: Increase post_max_size"
38 | lineinfile:
39 | dest: "{{ legacy_php_ini }}"
40 | regexp: "post_max_size = 8M"
41 | line: "post_max_size = {{ post_max_size }}"
42 | when: legacy_phpfpm.stat.exists == false
43 |
44 | - name: "PHP: Increase opcache.max_accelerated_files"
45 | lineinfile:
46 | dest: "{{ legacy_php_ini }}"
47 | regexp: ";opcache.max_accelerated_files=2000"
48 | line: "opcache.max_accelerated_files={{ opcache_max_accelerated_files }}"
49 | when: legacy_phpfpm.stat.exists == false
50 |
51 | - name: "PHP: Add default timezone"
52 | lineinfile:
53 | dest: "{{ legacy_php_ini_cli }}"
54 | regexp: ";date.timezone ="
55 | line: "date.timezone = {{ timezone }}"
56 | notify: Restart Apache
57 | when: legacy_phpfpm.stat.exists == false
58 |
--------------------------------------------------------------------------------
/app/orchestration/plays/php/libyaml.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "LIBYAML: Install required build tools"
3 | package:
4 | name: "{{ item }}"
5 | state: present
6 | with_items:
7 | - build-essential
8 | - autogen
9 | - autoconf
10 | - libtool
11 |
12 | - name: "LIBYAML: Check if archive exists"
13 | stat:
14 | path: "{{ libyaml_archive_path }}"
15 | register: libyaml_archive
16 |
17 | - name: "LIBYAML: Copy latest release from mirror"
18 | get_url:
19 | url: "{{ libyaml_mirror_download_link }}"
20 | dest: "{{ download_dir }}"
21 | validate_certs: no
22 | register: libyaml_get_url_result
23 | until: "'OK' in libyaml_get_url_result.msg"
24 | retries: 3
25 | delay: 10
26 | when: libyaml_archive.stat.exists == false
27 | changed_when: libyaml_archive.stat.exists == false
28 |
29 | - name: "LIBYAML: Extract files"
30 | unarchive:
31 | src: "{{ libyaml_archive_path }}"
32 | dest: "{{ download_dir }}"
33 | copy: no
34 | when: libyaml_archive.stat.exists == false
35 |
36 | - name: "LIBYAML: Compile parser"
37 | command: "{{ item }} chdir={{ libyaml_temp_path }}"
38 | with_items:
39 | - ./bootstrap
40 | - ./configure
41 | - /usr/bin/make
42 | - /usr/bin/make install
43 | when: libyaml_archive.stat.exists == false
44 |
45 | - name: "LIBYAML: Delete temporary parser directory"
46 | file:
47 | path: "{{ libyaml_temp_path }}"
48 | state: absent
49 | when: libyaml_archive.stat.exists == false
50 |
--------------------------------------------------------------------------------
/app/orchestration/plays/php/pecl-yaml.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # See change record: https://www.drupal.org/node/2769555
3 | - name: "PECL YAML: Check if the extension is installed"
4 | stat:
5 | path: "{{ pecl_yaml_extension_path }}"
6 | register: pecl_yaml_extension_check
7 |
8 | - name: "PECL YAML: Copy latest release from mirror"
9 | get_url:
10 | url: "{{ pecl_yaml_mirror_download_link }}"
11 | dest: "{{ download_dir }}"
12 | validate_certs: no
13 | register: pecl_yaml_get_url_result
14 | until: "'OK' in pecl_yaml_get_url_result.msg"
15 | retries: 3
16 | delay: 10
17 | when: pecl_yaml_extension_check.stat.exists == false
18 |
19 | - name: "PECL YAML: Extract files"
20 | unarchive:
21 | src: "{{ pecl_yaml_archive }}"
22 | dest: "{{ download_dir }}"
23 | copy: no
24 | when: pecl_yaml_extension_check.stat.exists == false
25 |
26 | - name: "PECL YAML: Compile extension"
27 | command: "{{ item }} chdir={{ pecl_yaml_temp_path }}"
28 | with_items:
29 | - /usr/bin/phpize
30 | - ./configure
31 | - /usr/bin/make
32 | - /usr/bin/make install
33 | when: pecl_yaml_extension_check.stat.exists == false
34 |
35 | - name: "PECL YAML: Copy compiled extension"
36 | command: cp {{ pecl_yaml_temp_path }}/modules/{{ pecl_yaml_extension_name }} {{ default_php_extensions }}
37 | when: pecl_yaml_extension_check.stat.exists == false
38 |
39 | - name: "PECL YAML: Make sure permissions are correct"
40 | file:
41 | path: "{{ pecl_yaml_extension_path }}"
42 | mode: 0644
43 | when: pecl_yaml_extension_check.stat.exists == false
44 |
45 | - name: "PECL YAML: Delete temporary directory"
46 | file:
47 | path: "{{ pecl_yaml_temp_path }}"
48 | state: absent
49 | when: pecl_yaml_extension_check.stat.exists == false
50 |
51 | - name: "PECL YAML: Check config in php.ini"
52 | shell: grep -o "{{ pecl_yaml_extension_name }}" {{ default_php_ini }} || echo "absent"
53 | register: pecl_yaml_config
54 | changed_when: pecl_yaml_config.stdout == "absent"
55 |
56 | - name: "PECL YAML: Configure extension in php.ini"
57 | lineinfile:
58 | dest: "{{ default_php_ini }}"
59 | line: "extension={{ pecl_yaml_extension_path }}"
60 | when: pecl_yaml_config.stdout == "absent"
61 |
62 | - name: "PECL YAML: Ensure Apache is restarted to load the extension"
63 | service:
64 | name: apache2
65 | enabled: yes
66 | state: restarted
67 |
68 | - name: "PECL YAML: Ensure PHP-FPM is restarted to load the extension"
69 | service:
70 | name: php{{ default_php_version }}-fpm
71 | enabled: yes
72 | state: restarted
73 |
--------------------------------------------------------------------------------
/app/orchestration/plays/php/php.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PHP: Check if PHP is installed"
3 | stat:
4 | path: "{{ default_php_ini }}"
5 | register: phpfpm_is_installed
6 |
7 | - name: "PHP: Add deb.sury.org GPG signature"
8 | apt_key:
9 | url: "{{ sury_gpg }}"
10 | state: present
11 | validate_certs: no
12 | when: phpfpm_is_installed.stat.exists == false
13 |
14 | - name: "PHP: Add deb.sury.org repository"
15 | apt_repository:
16 | repo: "{{ sury_deb }}"
17 | state: present
18 | when: phpfpm_is_installed.stat.exists == false
19 |
20 | - name: "PHP: Update APT cache to load new repository"
21 | apt:
22 | update_cache: yes
23 | when: phpfpm_is_installed.stat.exists == false
24 |
25 | - import_tasks: default-php.yml
26 |
27 | - name: "PHP: Check if php7 module is enabled"
28 | stat:
29 | path: "{{ apache_php_mod }}"
30 | register: php7_module
31 |
32 | - name: "PHP: Disable php7 module"
33 | apache2_module:
34 | state: absent
35 | name: php7
36 | notify: Restart PHP-FPM
37 | when: php7_module.stat.exists == true
38 |
39 | - name: "PHP: Check if proxy_fcgi module is enabled"
40 | stat:
41 | path: "{{ apache_proxy_fcgi_mod }}"
42 | register: proxy_fcgi_module
43 |
44 | # php-fpm Fast-CGI support
45 | - name: "PHP: Enable proxy_fcgi module"
46 | apache2_module:
47 | state: present
48 | name: proxy_fcgi
49 | notify: Restart PHP-FPM
50 | when: proxy_fcgi_module.stat.exists == false
51 |
52 | - name: "PHP: Check if PHP FPM is started"
53 | shell: pgrep php-fpm || echo 'down'
54 | register: check_phpfpm_up
55 | changed_when: check_phpfpm_up.stdout == "down"
56 |
57 | - name: "PHP: Ensure PHP FPM is started"
58 | command: /etc/init.d/php{{ default_php_version }}-fpm start
59 | become: yes
60 | when: check_phpfpm_up.stdout == "down"
61 |
--------------------------------------------------------------------------------
/app/orchestration/plays/php/php_version_and_vhost_check.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PHP: Store PHP version variable"
3 | shell: cat {{ default_php_version_file }}
4 | register: php_read_version
5 |
6 | - name: "APACHE: Retrieve existing vHosts"
7 | shell: ls {{ sites_available }}/*.conf | grep -Ev '(000-default|default-ssl.conf)' || echo 'no vHost'
8 | register: apache_vhosts_list
9 |
--------------------------------------------------------------------------------
/app/orchestration/plays/php/phpfpm_process_check.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PHP: Check if PHP FPM is already started"
3 | shell: pgrep -ln php-fpm | awk '{print $NF}' || echo 'stopped'
4 | register: phpfpm_is_started
5 |
6 | - name: "PHP: Stop current PHP FPM process"
7 | command: /etc/init.d/php{{ php_read_version.stdout }}-fpm stop
8 | when: phpfpm_is_started.stdout != 'stopped'
9 |
--------------------------------------------------------------------------------
/app/orchestration/plays/php/previous-php.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PHP: Check if the version file exists"
3 | stat:
4 | path: "{{ default_php_version_file }}"
5 | register: php_version_file_check
6 |
7 | - name: "PHP: Check which PHP version is currently running"
8 | shell: grep -o "{{ previous_php_version }}" {{ default_php_version_file }} || echo "Different version"
9 | when: php_version_file_check.stat.exists == true
10 | register: current_php
11 |
12 | - name: "PHP: Check if PHP {{ previous_php_version}} is installed"
13 | stat:
14 | path: "{{ previous_php_ini }}"
15 | register: previous_phpfpm
16 |
17 | - name: "PHP: Install PHP {{ previous_php_version}} core packages"
18 | package:
19 | name: "{{ item }}"
20 | state: present
21 | with_items:
22 | - php{{ previous_php_version }}-fpm
23 | - php{{ previous_php_version }}-cli
24 | - php{{ previous_php_version }}-common
25 | - php{{ previous_php_version }}-dev
26 | when: previous_phpfpm.stat.exists == false
27 |
28 | - name: "PHP: Install PHP {{ previous_php_version}} extensions"
29 | package:
30 | name: "{{ item }}"
31 | state: present
32 | with_items:
33 | - php-imagick
34 | - php-memcached
35 | - php{{ previous_php_version }}-apcu
36 | - php{{ previous_php_version }}-curl
37 | - php{{ previous_php_version }}-gd
38 | - php{{ previous_php_version }}-mbstring
39 | - php{{ previous_php_version }}-mysql
40 | - php{{ previous_php_version }}-xmlrpc
41 | - php{{ previous_php_version }}-xsl
42 | - php{{ previous_php_version }}-bz2
43 | - php{{ previous_php_version }}-sqlite3
44 | when: previous_phpfpm.stat.exists == false
45 |
46 | - name: "PHP: Ensure PHP {{ previous_php_version }} extensions directory exists"
47 | file:
48 | path: "{{ previous_php_extensions }}"
49 | state: directory
50 | when: previous_phpfpm.stat.exists == false
51 |
52 | - import_tasks: php_version_and_vhost_check.yml
53 |
54 | - name: "PHP: Update PHP FPM version in vHosts"
55 | replace:
56 | dest: "{{ item }}"
57 | regexp: '^(.*)php{{ php_read_version.stdout }}-fpm.sock(.*)$'
58 | replace: '\1php{{ previous_php_version }}-fpm.sock\2'
59 | with_items:
60 | - "{{ apache_vhosts_list.stdout_lines }}"
61 | when: apache_vhosts_list.stdout != 'no vHost'
62 |
63 | - name: "PHP: Switch PHP CLI version"
64 | command: update-alternatives --set php /usr/bin/php{{ previous_php_version }}
65 |
66 | - import_tasks: phpfpm_process_check.yml
67 |
68 | - name: "PHP: Start PHP {{ previous_php_version}} FPM"
69 | command: /etc/init.d/php{{ previous_php_version }}-fpm start
70 | when: previous_php_version != php_read_version.stdout or phpfpm_is_started.stdout == 'stopped'
71 |
72 | - name: "PHP: Ensure PHP {{ previous_php_version}} FPM is started"
73 | shell: pgrep -ln php-fpm | awk '{print $NF}'
74 | register: previous_phpfpm_is_started
75 | notify: Restart Apache
76 |
77 | - name: "PHP: Write new PHP version to file"
78 | copy:
79 | content: "{{ previous_php_version }}"
80 | dest: "{{ default_php_version_file }}"
81 | when: previous_phpfpm_is_started.changed
82 |
83 | - import_tasks: previous_php_ini.yml
84 |
--------------------------------------------------------------------------------
/app/orchestration/plays/php/previous_php_ini.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PHP: Increase max_input_time"
3 | lineinfile:
4 | dest: "{{ previous_php_ini }}"
5 | regexp: "max_input_time = 60"
6 | line: "max_input_time = {{ max_input_time }}"
7 | when: previous_phpfpm.stat.exists == false
8 |
9 | - name: "PHP: Increase max_execution_time"
10 | lineinfile:
11 | dest: "{{ previous_php_ini }}"
12 | regexp: "max_execution_time = 30"
13 | line: "max_execution_time = {{ max_execution_time }}"
14 | when: previous_phpfpm.stat.exists == false
15 |
16 | - name: "PHP: Increase memory_limit"
17 | lineinfile:
18 | dest: "{{ previous_php_ini }}"
19 | regexp: "memory_limit = 128M"
20 | line: "memory_limit = {{ memory_limit }}"
21 | when: previous_phpfpm.stat.exists == false
22 |
23 | - name: "PHP: Increase upload_max_filesize"
24 | lineinfile:
25 | dest: "{{ previous_php_ini }}"
26 | regexp: "upload_max_filesize = 2M"
27 | line: "upload_max_filesize = {{ upload_max_filesize }}"
28 | when: previous_phpfpm.stat.exists == false
29 |
30 | - name: "PHP: Increase max_file_uploads"
31 | lineinfile:
32 | dest: "{{ previous_php_ini }}"
33 | regexp: "max_file_uploads = 20"
34 | line: "max_file_uploads = {{ max_file_uploads }}"
35 | when: previous_phpfpm.stat.exists == false
36 |
37 | - name: "PHP: Increase post_max_size"
38 | lineinfile:
39 | dest: "{{ previous_php_ini }}"
40 | regexp: "post_max_size = 8M"
41 | line: "post_max_size = {{ post_max_size }}"
42 | when: previous_phpfpm.stat.exists == false
43 |
44 | - name: "PHP: Increase opcache.max_accelerated_files"
45 | lineinfile:
46 | dest: "{{ previous_php_ini }}"
47 | regexp: ";opcache.max_accelerated_files=2000"
48 | line: "opcache.max_accelerated_files={{ opcache_max_accelerated_files }}"
49 | when: previous_phpfpm.stat.exists == false
50 |
51 | - name: "PHP: Add default timezone"
52 | lineinfile:
53 | dest: "{{ previous_php_ini_cli }}"
54 | regexp: ";date.timezone ="
55 | line: "date.timezone = {{ timezone }}"
56 | notify: Restart Apache
57 | when: previous_phpfpm.stat.exists == false
58 |
--------------------------------------------------------------------------------
/app/orchestration/plays/post-install.yml:
--------------------------------------------------------------------------------
1 | - name: "POST-INSTALL: Check if all hostnames are configured"
2 | shell: grep -E '({{ phpmyadmin_hostname }}.{{ tld }}|{{ adminer_hostname }}.{{ tld }})' {{ hosts_file }} || echo "absent"
3 | register: additional_hostnames
4 | changed_when: additional_hostnames.stdout == "absent"
5 |
6 | - name: "POST-INSTALL: Make sure the web container can reach all hostnames"
7 | shell: echo "{{ web_ip }} {{ item }}.{{ tld }}" >> {{ hosts_file }}
8 | with_items:
9 | - "{{ phpmyadmin_hostname }}"
10 | - "{{ adminer_hostname }}"
11 | when: additional_hostnames.stdout == "absent"
12 |
13 | - name: "POST-INSTALL: Check if Solr hostname is configured"
14 | shell: grep -o "{{ search_ip }}" {{ hosts_file }} || echo "absent"
15 | register: search_hostname
16 | changed_when: search_hostname.stdout == "absent"
17 |
18 | - name: "POST-INSTALL: Make sure the web container can talk to the Solr backend"
19 | shell: echo "{{ search_ip }} search.{{ tld }}" >> {{ hosts_file }}
20 | when: search_hostname.stdout == "absent"
21 |
--------------------------------------------------------------------------------
/app/orchestration/plays/solr/java.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "JAVA: Install Open JDK"
3 | apt:
4 | name: openjdk-8-jre-headless
5 | state: present
6 | install_recommends: no
7 |
--------------------------------------------------------------------------------
/app/orchestration/plays/solr/solr.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "SOLR: Create solr group"
3 | group:
4 | name: solr
5 | gid: 8983
6 | state: present
7 |
8 | - name: "SOLR: Create solr user"
9 | user:
10 | name: solr
11 | uid: 8983
12 | home: /home/solr
13 | shell: /bin/bash
14 | groups: solr
15 |
16 | - name: "SOLR: Check if core exists"
17 | stat:
18 | path: "{{ solr_configuration_path }}"
19 | register: solr_core_check
20 | changed_when: solr_core_check.stat.exists == false
21 |
22 | - name: "SOLR: Check if archive exists"
23 | stat:
24 | path: "{{ solr_archive_path }}"
25 | register: solr_archive_path_check
26 | changed_when: solr_archive_path_check.stat.exists == false
27 |
28 | - name: "SOLR: Copy archive from mirror"
29 | get_url:
30 | url: "{{ solr_mirror_download_link }}"
31 | dest: "{{ download_dir }}"
32 | validate_certs: no
33 | register: solr_get_url_result
34 | until: "'OK' in solr_get_url_result.msg"
35 | retries: 3
36 | delay: 10
37 | when: solr_archive_path_check.stat.exists == false
38 |
39 | - name: "SOLR: Extract files"
40 | unarchive:
41 | src: "{{ solr_archive_path }}"
42 | dest: /opt
43 | copy: no
44 | when: solr_archive_path_check.stat.exists == false
45 |
46 | - name: "SOLR: Check if directory exists"
47 | stat:
48 | path: "{{ solr_installation_path }}"
49 | register: solr_installation_path_check
50 | changed_when: solr_installation_path_check.stat.exists == false
51 |
52 | - name: "SOLR: Rename unarchived directory"
53 | command: mv {{ solr_temp_unarchived_path }} {{ solr_installation_path }}
54 | when: solr_installation_path_check.stat.exists == false
55 |
56 | - name: "SOLR: Make sure install has correct permissions"
57 | file:
58 | path: "{{ solr_installation_path }}"
59 | state: directory
60 | owner: solr
61 | group: solr
62 | recurse: yes
63 | when: solr_installation_path_check.stat.exists == false
64 |
65 | - name: "SOLR: Check if server is started"
66 | stat:
67 | path: "{{ solr_installation_path }}/bin/solr-8983.pid"
68 | register: solr_pid
69 | changed_when: solr_pid.stat.exists == false
70 |
71 | - name: "SOLR: Start server"
72 | shell: "{{ solr_binary }} start"
73 | become: yes
74 | become_user: solr
75 | when: solr_pid.stat.exists == false
76 |
77 | - name: "SOLR: Create search core"
78 | shell: "{{ solr_binary }} create_core -c {{ solr_core }}"
79 | become: yes
80 | become_user: solr
81 | when: solr_core_check.stat.exists == false
82 |
83 | - name: "SOLR: Check if the schema.xml file exists"
84 | stat:
85 | path: "{{ solr_configuration_path }}/schema.xml"
86 | register: schemaxml_check
87 | changed_when: schemaxml_check.stat.exists == false
88 |
89 | - name: "SOLR: Check if schema.xml file has been configured for Search API Solr"
90 | shell: grep -o "search_api" {{ solr_configuration_path }}/schema.xml | head -n1 || echo "missing"
91 | register: solr_conf_files
92 | when: schemaxml_check.stat.exists == true
93 | changed_when: solr_conf_files.stdout != "search_api"
94 |
95 | - name: "SOLR: Deploy conf files"
96 | copy:
97 | src: "{{ solr_conf }}/"
98 | dest: "{{ solr_configuration_path }}"
99 | mode: 0644
100 | when: schemaxml_check.stat.exists == false or (solr_conf_files is defined and solr_conf_files.stdout != "search_api")
101 |
102 | - name: "SOLR: Ensure correct permissions on conf files"
103 | file:
104 | path: "{{ solr_configuration_path }}"
105 | state: directory
106 | owner: solr
107 | group: users
108 | recurse: yes
109 | when: schemaxml_check.stat.exists == false or (solr_conf_files is defined and solr_conf_files.stdout != "search_api")
110 |
111 | - name: "SOLR: Restart server"
112 | shell: "{{ solr_binary }} restart"
113 | become: yes
114 | become_user: solr
115 |
--------------------------------------------------------------------------------
/app/orchestration/plays/stack.yml:
--------------------------------------------------------------------------------
1 | - import_tasks: common/permissions.yml
2 | - import_tasks: common/apache-installation.yml
3 | - import_tasks: common/drucker-config.yml
4 | - import_tasks: php/php.yml
5 | - import_tasks: php/libyaml.yml
6 | - import_tasks: php/pecl-yaml.yml
7 | - import_tasks: tools/composer.yml
8 | - import_tasks: tools/xdebug.yml
9 | - import_tasks: tools/tideways.yml
10 | - import_tasks: tools/phantomjs.yml
11 | - import_tasks: tools/codesniffer.yml
12 | - import_tasks: tools/php-cs-fixer.yml
13 | - import_tasks: tools/coder.yml
14 | # - import_tasks: tools/phpmd.yml
15 | - import_tasks: tools/mcstat.yml
16 | - import_tasks: tools/sass.yml
17 | - import_tasks: db/db-tools.yml
18 |
--------------------------------------------------------------------------------
/app/orchestration/plays/system/ssh-keys.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Allows Drush to bootstrap a remote DB.
3 | - name: "SSH: Check if SSH key exists"
4 | stat:
5 | path: "{{ id_rsa }}"
6 | register: rsa_web
7 | ignore_errors: True
8 |
9 | - name: "SSH: Generate SSH key for remote MySQL access"
10 | shell: ssh-keygen -b 4096 -t rsa -f {{ id_rsa }} -q -N ""
11 | args:
12 | creates: "{{ id_rsa }}"
13 | when: rsa_web.stat.exists == false
14 |
15 | - name: "SSH: Make sure permissions are correct on SSH keys"
16 | file:
17 | path: "{{ item }}"
18 | owner: "{{ user }}"
19 | group: "{{ user }}"
20 | with_items:
21 | - "{{ id_rsa }}"
22 | - "{{ id_rsa_pub }}"
23 | when: rsa_web.stat.exists == false
24 |
--------------------------------------------------------------------------------
/app/orchestration/plays/system/ssh.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "SSH: Enforce hardening"
3 | lineinfile:
4 | dest: "{{ sshd_config }}"
5 | regexp: "{{ item.regexp }}"
6 | line: "{{ item.line }}"
7 | state: present
8 | with_items:
9 | - {
10 | regexp: "^PasswordAuthentication",
11 | line: "PasswordAuthentication no"
12 | }
13 | - {
14 | regexp: "^PermitRootLogin",
15 | line: "PermitRootLogin no"
16 | }
17 | notify: Restart SSH
18 |
19 | - name: "SSH: Check if Docker-specific sudo TTY workaround file exists"
20 | stat:
21 | path: "{{ sudo_tty_workaround_file }}"
22 | register: sudo_tty_workaround
23 |
24 | - name: "SSH: Create Docker-specific sudo TTY workaround file"
25 | file:
26 | path: "{{ sudo_tty_workaround_file }}"
27 | state: touch
28 | mode: 0440
29 | when: sudo_tty_workaround.stat.exists == false
30 |
31 | - name: "SSH: Prevent requiring a password for sudo"
32 | lineinfile:
33 | dest: "{{ sudo_tty_workaround_file }}"
34 | line: "%sudo ALL=(ALL:ALL) NOPASSWD:ALL"
35 | when: sudo_tty_workaround.stat.exists == false
36 |
--------------------------------------------------------------------------------
/app/orchestration/plays/system/system-setup.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Docker is supposed to copy over the local /etc/resolv.conf file. Sometimes it
3 | # fails, so we have to hack our way through modifying it.
4 | - name: "SYSTEM: Copy DNS settings"
5 | command: "cp {{ resolvconf_path }} {{ tmp_resolvconf_path }}"
6 |
7 | - name: "SYSTEM: Update DNS settings"
8 | lineinfile:
9 | dest: "{{ tmp_resolvconf_path }}"
10 | line: "nameserver {{ nameserver }}"
11 | state: present
12 |
13 | - name: "SYSTEM: Replace DNS settings"
14 | command: "cp {{ tmp_resolvconf_path }} {{ resolvconf_path}}"
15 |
16 | - name: "SYSTEM: Clean up system packages"
17 | package:
18 | name: "{{ item }}"
19 | state: absent
20 | purge: yes
21 | with_items:
22 | - vim-tiny
23 |
24 | - name: "SYSTEM: Deploy sources.list template with contrib and non-free repositories"
25 | copy:
26 | src: "{{ sources_list_source_file }}"
27 | dest: "{{ sources_list }}"
28 | mode: 0644
29 |
30 | - name: "SYSTEM: Add Debian codename to sources.list template"
31 | replace:
32 | dest: "{{ sources_list }}"
33 | regexp: '^(.*)CODENAME(.*)$'
34 | replace: '\1{{ codename }}\2'
35 |
36 | - name: "SYSTEM: Refresh APT"
37 | apt:
38 | update_cache: yes
39 |
40 | - name: "SYSTEM: Install system packages"
41 | package:
42 | name: "{{ item }}"
43 | state: present
44 | with_items:
45 | # Useful to run commands as a non-privileged user.
46 | # E.g. /opt/solr/bin/solr start
47 | # See https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user
48 | - acl
49 | # Needed for Ansible's APT module to perform upgrades.
50 | # See https://github.com/ansible/ansible/issues/22673
51 | - aptitude
52 | - ack-grep
53 | # Can be removed in Debian 10.
54 | # See https://packages.debian.org/buster/apt-transport-https
55 | - apt-transport-https
56 | - curl
57 | # Provides dig command.
58 | - dnsutils
59 | - dstat
60 | - exuberant-ctags
61 | - git
62 | - htop
63 | # syslog
64 | - inetutils-syslogd
65 | - iputils-ping
66 | # phantomjs secret dependency
67 | - libfontconfig1
68 | - logrotate
69 | - lsof
70 | - ncdu
71 | - netcat
72 | - net-tools
73 | - ntp
74 | - patchutils
75 | - silversearcher-ag
76 | - strace
77 | - sysstat
78 | - telnet
79 | - tcpdump
80 | - time
81 | - neovim
82 | - wget
83 | # Allows to resize (/usr/bin/resize) the prompt if $COLUMNS and $LINES are
84 | # suddenly messed up, e.g. in a tmux session.
85 | - xterm
86 |
87 | - name: "SYSTEM: Ensure NTP is running"
88 | service:
89 | name: ntp
90 | state: started
91 | enabled: yes
92 |
93 | - name: "SYSTEM: Deploy .bash_aliases"
94 | copy:
95 | src: "{{ bash_aliases_source_file}}"
96 | dest: "{{ home }}"
97 | mode: 0644
98 | owner: "{{ user }}"
99 | group: "{{ user }}"
100 | become: yes
101 | become_user: "{{ user }}"
102 |
103 | - name: "SYSTEM: Add www-data group to drucker account"
104 | user:
105 | name: "{{ user }}"
106 | groups: "{{ apache_user}}"
107 | append: yes
108 |
--------------------------------------------------------------------------------
/app/orchestration/plays/tools/coder.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "CODER: Check if software is installed"
3 | stat:
4 | path: "{{ coder_binary }}"
5 | register: coder
6 |
7 | - name: "CODER: Install software"
8 | composer:
9 | command: require
10 | arguments: "{{ coder_composer_package }} {{ coder_stable_release }}"
11 | working_dir: "{{ composer_dir_path }}"
12 | become: yes
13 | become_user: "{{ user }}"
14 | when: coder.stat.exists == false
15 |
16 | - name: "CODER: Check if software is up-to-date"
17 | shell: grep -o "{{ coder_stable_release }}" {{ composer_dir_path }}/composer.json || echo "outdated"
18 | register: coder_stable_release_check
19 | changed_when: coder_stable_release_check.stdout != coder_stable_release
20 |
21 | - name: "CODER: Update software"
22 | composer:
23 | command: require
24 | arguments: "{{ coder_composer_package }} {{ coder_stable_release }}"
25 | working_dir: "{{ composer_dir_path }}"
26 | become: yes
27 | become_user: "{{ user }}"
28 | when: coder.stat.exists == true and coder_stable_release_check.stdout != coder_stable_release
29 |
30 | - name: "CODER: Check if bash aliases exist"
31 | shell: grep -o 'MANAGED CODE SNIFFER BLOCK' {{ bashrc }} || echo "absent"
32 | register: coder_aliases
33 | changed_when: coder_aliases == "absent"
34 |
35 | - name: "CODER: Add Code Sniffer aliases"
36 | blockinfile:
37 | dest: "{{ bashrc }}"
38 | block: |
39 | alias drupalcs="phpcs --standard=Drupal --extensions='php,module,inc,install,test,profile,theme,css,info,txt,md'"
40 | alias drupalcsp="phpcs --standard=DrupalPractice --extensions='php,module,inc,install,test,profile,theme,css,info,txt,md'"
41 | alias drupalcbf="phpcbf --standard=Drupal --extensions='php,module,inc,install,test,profile,theme,css,info,txt,md'"
42 | insertafter: EOF
43 | marker: "# {mark} MANAGED CODE SNIFFER BLOCK"
44 | when: coder_aliases.stdout == 'absent'
45 |
46 | - name: "CODER: Register Drupal and DrupalPractice with PHPCS"
47 | command: phpcs --config-set installed_paths {{ codesniffer_binary }}
48 | when: coder.stat.exists == false
49 |
--------------------------------------------------------------------------------
/app/orchestration/plays/tools/codesniffer.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "CODE SNIFFER: Check if phpcs is globally installed"
3 | stat:
4 | path: "{{ phpcs_binary }}"
5 | register: phpcs
6 |
7 | - name: "CODE SNIFFER: Check if phpcbf is globally installed"
8 | stat:
9 | path: "{{ phpcbf_binary }}"
10 | register: phpcbf
11 |
12 | - name: "CODE SNIFFER: Check phpcs version"
13 | shell: phpcs --version | awk '{print $3}'
14 | register: phpcs_version
15 | when: phpcs.stat.exists == true
16 | changed_when: phpcs_version.stdout != phpcs_stable_release
17 |
18 | - name: "CODE SNIFFER: Check phpcbf version"
19 | shell: phpcbf --version | awk '{print $3}'
20 | register: phpcbf_version
21 | when: phpcbf.stat.exists == true
22 | changed_when: phpcbf_version.stdout != phpcbf_stable_release
23 |
24 | - name: "CODE SNIFFER: Copy latest phpcs release from mirror"
25 | get_url:
26 | url: "{{ phpcs_mirror_download_link }}"
27 | dest: "{{ download_dir }}"
28 | mode: 0755
29 | validate_certs: no
30 | register: phpcs_get_url_result
31 | until: "'OK' in phpcs_get_url_result.msg"
32 | retries: 3
33 | delay: 10
34 | when: phpcs.stat.exists == false or phpcs_version.stdout != phpcs_stable_release
35 |
36 | - name: "CODE SNIFFER: Rename phpcs PHAR file"
37 | command: mv {{ phpcs_temp_phar }} {{ phpcs_temp_path }}
38 | when: phpcs.stat.exists == false or phpcs_version.stdout != phpcs_stable_release
39 |
40 | - name: "CODE SNIFFER: Install phpcs globally"
41 | command: mv {{ phpcs_temp_path }} {{ user_programs_path }}
42 | when: phpcs.stat.exists == false or phpcs_version.stdout != phpcs_stable_release
43 |
44 | - name: "CODE SNIFFER: Copy latest phpcbf release from mirror"
45 | get_url:
46 | url: "{{ phpcbf_mirror_download_link }}"
47 | dest: "{{ download_dir }}"
48 | mode: 0755
49 | validate_certs: no
50 | register: phpcbf_get_url_result
51 | until: "'OK' in phpcbf_get_url_result.msg"
52 | retries: 3
53 | delay: 10
54 | when: phpcbf.stat.exists == false or phpcbf_version.stdout != phpcbf_stable_release
55 |
56 | - name: "CODE SNIFFER: Rename phpcbf PHAR file"
57 | command: mv {{ phpcbf_temp_phar }} {{ phpcbf_temp_path }}
58 | when: phpcbf.stat.exists == false or phpcbf_version.stdout != phpcbf_stable_release
59 |
60 | - name: "CODE SNIFFER: Install phpcbf globally"
61 | command: mv {{ phpcbf_temp_path }} {{ user_programs_path }}
62 | when: phpcbf.stat.exists == false or phpcbf_version.stdout != phpcbf_stable_release
63 |
--------------------------------------------------------------------------------
/app/orchestration/plays/tools/composer.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "COMPOSER: Check if software is installed"
3 | stat:
4 | path: "{{ composer_binary }}"
5 | register: composer
6 |
7 | - name: "COMPOSER: Check version"
8 | shell: composer --version | awk '{print $3}'
9 | register: composer_stable_release_check
10 | when: composer.stat.exists == true
11 | changed_when: composer_stable_release_check.stdout != composer_stable_release
12 |
13 | - name: "COMPOSER: Install globally"
14 | get_url:
15 | url: "{{ composer_download_link }}"
16 | dest: "{{ composer_binary }}"
17 | validate_certs: no
18 | force: yes
19 | register: composer_get_url_result
20 | until: "'OK' in composer_get_url_result.msg"
21 | retries: 3
22 | delay: 10
23 | when: composer.stat.exists == false or composer_stable_release_check.stdout != composer_stable_release
24 |
25 | - name: "COMPOSER: Make executable"
26 | file:
27 | path: "{{ composer_binary }}"
28 | mode: 0755
29 | when: composer.stat.exists == false or composer_stable_release_check.stdout != composer_stable_release
30 |
31 | - name: "COMPOSER: Check if software is in PATH"
32 | shell: grep -o "export PATH=\"\$PATH:\$HOME/.composer/vendor/bin\"" {{ bashrc }} || echo "absent"
33 | register: composer_path
34 | changed_when: composer_path.stdout == "absent"
35 |
36 | - name: "COMPOSER: Add software to PATH"
37 | lineinfile:
38 | dest: "{{ bashrc }}"
39 | line: export PATH="$PATH:$HOME/.composer/vendor/bin"
40 | insertafter: EOF
41 | when: composer_path.stdout == 'absent'
42 |
43 | - name: "COMPOSER: Check if .composer directory exists"
44 | stat:
45 | path: "{{ composer_dir_path }}"
46 | register: composer_directory
47 |
48 | - name: "COMPOSER: Create .composer directory"
49 | file:
50 | path: "{{ composer_dir_path }}"
51 | state: directory
52 | owner: "{{ user }}"
53 | group: "{{ user }}"
54 | recurse: yes
55 | when: composer_directory.stat.exists == false
56 |
57 | - name: "COMPOSER: Check if composer.json file exists"
58 | stat:
59 | path: "{{ composer_json_path }}"
60 | register: composer_json
61 |
62 | - name: "COMPOSER: Deploy default composer.json file"
63 | copy:
64 | src: "{{ composer_json_source_file }}"
65 | dest: "{{ composer_dir_path }}"
66 | mode: 0644
67 | become: yes
68 | become_user: "{{ user }}"
69 | when: composer_json.stat.exists == false
70 |
71 | - name: "COMPOSER: Make sure permissions are correct for the .composer directory"
72 | file:
73 | path: "{{ composer_dir_path }}"
74 | owner: "{{ user }}"
75 | group: "{{ user }}"
76 | recurse: yes
77 |
78 | - name: "COMPOSER: Install packages"
79 | composer:
80 | command: install
81 | arguments: --prefer-dist
82 | working_dir: "{{ composer_dir_path }}"
83 | become: yes
84 | become_user: "{{ user }}"
85 |
--------------------------------------------------------------------------------
/app/orchestration/plays/tools/drupal-console.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Drupal Console Launcher
3 | - name: "DRUPAL CONSOLE: Check if Launcher is installed"
4 | stat:
5 | path: "{{ drupal_console_binary }}"
6 | register: drupal_console_launcher
7 | changed_when: drupal_console_launcher.stat.exists == false
8 |
9 | - name: "DRUPAL CONSOLE: Check Launcher version"
10 | shell: drupal --version | head -n1 | awk '{print $NF}'
11 | register: drupal_console_launcher_check
12 | when: drupal_console_launcher.stat.exists == true
13 | changed_when: drupal_console_launcher_check.stdout != drupal_console_launcher_stable_release
14 |
15 | - name: "DRUPAL CONSOLE: Copy latest Launcher release from mirror"
16 | get_url:
17 | url: "{{ drupal_console_mirror_download_link }}"
18 | dest: "{{ drupal_console_binary }}"
19 | mode: 0755
20 | validate_certs: no
21 | force: yes
22 | register: drupal_console_get_url_result
23 | until: "'OK' in drupal_console_get_url_result.msg"
24 | retries: 3
25 | delay: 10
26 | when: drupal_console_launcher.stat.exists == false or drupal_console_launcher_check.stdout != drupal_console_launcher_stable_release
27 |
28 | - name: "DRUPAL CONSOLE: Update Launcher"
29 | command: drupal self-update
30 | become: yes
31 | when: drupal_console_launcher.stat.exists == true and drupal_console_launcher_check.stdout != drupal_console_launcher_stable_release
32 |
--------------------------------------------------------------------------------
/app/orchestration/plays/tools/drush.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Drush Launcher
3 | - name: "DRUSH: Check if Launcher is installed"
4 | stat:
5 | path: "{{ drush_launcher }}"
6 | register: drush_launcher
7 | changed_when: drush_launcher.stat.exists == false
8 |
9 | - name: "DRUSH: Check if Launcher needs to be updated"
10 | shell: drush --version| head -n1 | awk '{print $NF}'
11 | register: drush_launcher_stable_release_check
12 | when: drush_launcher.stat.exists == true
13 | changed_when: drush_launcher_stable_release_check.stdout != drush_launcher_stable_release
14 |
15 | - name: "DRUSH: Copy latest Launcher release from mirror"
16 | get_url:
17 | url: "{{ drush_launcher_mirror_download_link }}"
18 | dest: "{{ user_programs_path }}"
19 | mode: 0755
20 | validate_certs: no
21 | register: drush_launcher_get_url_result
22 | until: "'OK' in drush_launcher_get_url_result.msg"
23 | retries: 3
24 | delay: 10
25 | when: drush_launcher.stat.exists == false or drush_launcher_stable_release_check.stdout != drush_launcher_stable_release
26 |
27 | - name: "DRUSH: Rename Launcher PHAR file"
28 | command: mv {{ user_programs_path }}/{{ drush_launcher_archive_file }} {{ user_programs_path }}/drush
29 | when: drush_launcher.stat.exists == false or drush_launcher_stable_release_check.stdout != drush_launcher_stable_release
30 |
31 | # Drush (installed globally)
32 | - name: "DRUSH: Check if the global Drush is installed"
33 | stat:
34 | path: "{{ global_drush }}"
35 | register: global_drush_check
36 | changed_when: global_drush_check.stat.exists == false
37 |
38 | - name: "DRUSH: Copy global-drush to $PATH"
39 | file:
40 | src: "{{ composer_dir_path }}/vendor/drush/drush/drush"
41 | dest: "{{ global_drush }}"
42 | state: link
43 | when: global_drush_check.stat.exists == false
44 |
45 | - name: "DRUSH: Make sure the Launcher falls back to the global Drush"
46 | blockinfile:
47 | dest: "{{ bashrc }}"
48 | block: |
49 | export DRUSH_LAUNCHER_FALLBACK=`which global-drush`
50 | insertafter: EOF
51 | marker: "# {mark} MANAGED DRUSH LAUNCHER FALLBACK BLOCK"
52 |
53 | - name: "DRUSH: Check if Drush's etc directory exists"
54 | stat:
55 | path: "{{ drush_etc_path }}"
56 | register: drush_etc_check
57 | changed_when: drush_etc_check.stat.exists == false
58 |
59 | - name: "DRUSH: Create Drush's etc directory"
60 | file:
61 | path: "{{ drush_etc_path }}"
62 | state: directory
63 | when: drush_etc_check.stat.exists == false
64 |
65 | - name: "DRUSH: Check if sites-aliases directory exists"
66 | stat:
67 | path: "{{ drush_alias_path }}"
68 | register: site_alias_check
69 | changed_when: site_alias_check.stat.exists == false
70 |
71 | - name: "DRUSH: Create site-aliases directory"
72 | file:
73 | path: "{{ drush_alias_path }}"
74 | state: directory
75 | when: site_alias_check.stat.exists == false
76 |
77 | - name: "DRUSH: Create .drush directory"
78 | file:
79 | path: "{{ drush_dir }}"
80 | state: directory
81 | mode: 0755
82 | owner: "{{ user }}"
83 | group: "{{ user }}"
84 | when: site_alias_check.stat.exists == false
85 |
86 | - name: "DRUSH: Check if drush.yml file exists"
87 | stat:
88 | path: "{{ drush_yml_source_file }}"
89 | register: drush_yml_check
90 | changed_when: drush_yml_check.stat.exists == false
91 |
92 | - name: "DRUSH: Deploy drush.yml file"
93 | copy:
94 | src: "{{ drush_yml_source_file }}"
95 | dest: "{{ drush_dir }}"
96 | mode: 0644
97 | when: drush_yml_check.stat.exists == false
98 | ignore_errors: true
99 |
--------------------------------------------------------------------------------
/app/orchestration/plays/tools/mcstat.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "MCSTAT: Check if software is installed"
3 | stat:
4 | path: "{{ mcstat_binary }}"
5 | register: mcstat_check
6 | ignore_errors: True
7 |
8 | - name: "MCSTAT: Check if archive exists"
9 | stat:
10 | path: "{{ mcstat_archive_file }}"
11 | register: mcstat_archive
12 |
13 | - name: "MCSTAT: Copy latest release from mirror"
14 | get_url:
15 | url: "{{ mcstat_mirror_download_link }}"
16 | dest: "{{ download_dir }}"
17 | validate_certs: no
18 | register: mcstat_get_url_result
19 | until: "'OK' in mcstat_get_url_result.msg"
20 | retries: 3
21 | delay: 10
22 | when: mcstat_check.stat.exists == false and mcstat_archive.stat.exists == false
23 |
24 | - name: "MCSTAT: Extract files"
25 | unarchive:
26 | src: "{{ mcstat_archive_path }}"
27 | dest: "{{ user_programs_path }}"
28 | copy: no
29 | when: mcstat_check.stat.exists == false and mcstat_archive.stat.exists == false
30 |
31 | - name: "MCSTAT: Create symlink"
32 | file:
33 | src: "{{ mcstat_unarchived_directory }}/mcstat"
34 | dest: "{{ mcstat_binary }}"
35 | state: link
36 | when: mcstat_check.stat.exists == false and mcstat_archive.stat.exists == false
37 |
--------------------------------------------------------------------------------
/app/orchestration/plays/tools/phantomjs.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "GOOGLE CHROME: Download .deb package from the Google repository."
3 | apt:
4 | deb: https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
5 |
6 | - name: "PHANTOMJS: Check if software is installed"
7 | stat:
8 | path: "{{ phantomjs_binary }}"
9 | register: phantomjs
10 |
11 | - name: "PHANTOMJS: Check if software can be updated"
12 | command: phantomjs --version
13 | register: phantomjs_update
14 | when: phantomjs.stat.exists == true
15 | changed_when: phantomjs_update.stdout != phantomjs_stable_version
16 |
17 | - name: "PHANTOMJS: Check if archive exists"
18 | stat:
19 | path: phantomjs-{{ phantomjs_stable_version }}-linux-x86_64.tar.bz2
20 | register: phantomjs_archive
21 |
22 | - name: "PHANTOMJS: Copy latest release from mirror"
23 | get_url:
24 | url: "{{ phantomjs_mirror_download_link }}"
25 | dest: "{{ download_dir }}"
26 | validate_certs: no
27 | register: phantomjs_get_url_result
28 | until: "'OK' in phantomjs_get_url_result.msg"
29 | retries: 3
30 | delay: 10
31 | when: phantomjs.stat.exists == false or phantomjs_update.stdout != phantomjs_stable_version and phantomjs_archive.stat.exists == false
32 |
33 | - name: "PHANTOMJS: Extract files"
34 | unarchive:
35 | src: "{{ phantomjs_archive_path }}"
36 | dest: "{{ download_dir }}"
37 | copy: no
38 | when: phantomjs.stat.exists == false or phantomjs_update.stdout != phantomjs_stable_version
39 |
40 | - name: "PHANTOMJS: Delete outdated executable"
41 | file:
42 | path: "{{ phantomjs_binary }}"
43 | state: absent
44 | when: phantomjs.stat.exists == true and phantomjs_update.stdout != phantomjs_stable_version
45 |
46 | - name: "PHANTOMJS: Install software globally"
47 | command: mv {{ phantomjs_temp_path }}/bin/phantomjs {{ user_programs_path }}
48 | when: phantomjs.stat.exists == false or phantomjs_update.stdout != phantomjs_stable_version
49 |
50 | - name: "PHANTOMJS: Make binary executable"
51 | file:
52 | path: "{{ phantomjs_binary }}"
53 | mode: 0755
54 | when: phantomjs.stat.exists == false or phantomjs_update.stdout != phantomjs_stable_version
55 |
56 | - name: "PHANTOMJS: Delete temporary directory"
57 | file:
58 | path: "{{ item }}"
59 | state: absent
60 | with_items:
61 | - "{{ phantomjs_temp_path }}"
62 | - "{{ phantomjs_archive_path }}"
63 | when: phantomjs.stat.exists == false or phantomjs_update.stdout != phantomjs_stable_version
64 |
65 | # At some point we should think about transitioning over to Chromium's web
66 | # driver. PhantomJS would thus no longer be needed.
67 | - name: "SYSTEM: Install Chromium's web driver"
68 | package:
69 | name: chromium-driver
70 | state: present
71 | force: yes
72 |
--------------------------------------------------------------------------------
/app/orchestration/plays/tools/php-cs-fixer.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PHP-CS-FIXER: Check if software is installed"
3 | stat:
4 | path: "{{ php_cs_fixer_binary }}"
5 | register: php_cs_fixer
6 |
7 | - name: "PHP-CS-FIXER: Check version"
8 | shell: php-cs-fixer --version | awk '{print $5}'
9 | register: php_cs_fixer_version
10 | when: php_cs_fixer.stat.exists == true
11 | changed_when: php_cs_fixer_version.stdout != php_cs_fixer_stable_release
12 |
13 | - name: "PHP-CS-FIXER: Copy latest release from mirror"
14 | get_url:
15 | url: "{{ php_cs_fixer_mirror_download_link }}"
16 | dest: "{{ download_dir }}"
17 | mode: 0755
18 | validate_certs: no
19 | register: php_cs_fixer_get_url_result
20 | until: "'OK' in php_cs_fixer_get_url_result.msg"
21 | retries: 3
22 | delay: 10
23 | when: php_cs_fixer.stat.exists == false or php_cs_fixer_version.stdout != php_cs_fixer_stable_release
24 |
25 | - name: "PHP-CS-FIXER: Rename PHAR file"
26 | command: mv {{ php_cs_fixer_temp_phar }} {{ php_cs_fixer_temp_path }}
27 | when: php_cs_fixer.stat.exists == false or php_cs_fixer_version.stdout != php_cs_fixer_stable_release
28 |
29 | - name: "PHP-CS-FIXER: Install globally"
30 | command: mv {{ php_cs_fixer_temp_path }} {{ user_programs_path }}
31 | when: php_cs_fixer.stat.exists == false or php_cs_fixer_version.stdout != php_cs_fixer_stable_release
32 |
--------------------------------------------------------------------------------
/app/orchestration/plays/tools/phpmd.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "PHPMD: Check if software is installed"
3 | stat:
4 | path: "{{ phpmd_binary }}"
5 | register: phpmd
6 |
7 | - name: "PHPMD: Check if software needs to be updated"
8 | shell: phpmd --version | awk '{print $NF}'
9 | register: phpmd_stable_release_check
10 | when: phpmd.stat.exists == true
11 | changed_when: phpmd_stable_release_check.stdout != phpmd_stable_version
12 |
13 | - name: "PHPMD: Copy latest release from mirror"
14 | get_url:
15 | url: "{{ phpmd_mirror_download_link }}"
16 | dest: "{{ phpmd_binary }}"
17 | mode: 0755
18 | validate_certs: no
19 | force: yes
20 | register: phpmd_get_url_result
21 | until: "'OK' in phpmd_get_url_result.msg"
22 | retries: 3
23 | delay: 10
24 | when: phpmd.stat.exists == false or phpmd_stable_release_check.stdout != phpmd_stable_version
25 |
26 | - name: "PHPMD: Check if bash alias exists"
27 | shell: grep -o 'MANAGED PHPMD BLOCK' {{ bashrc }} || echo "absent"
28 | register: phpmd_alias
29 | changed_when: phpmd_alias == "absent"
30 |
31 | - name: "PHPMD: Add alias"
32 | blockinfile:
33 | dest: "{{ bashrc }}"
34 | block: |
35 | function phpmd { /usr/local/bin/phpmd "$1" text cleancode,codesize,controversial,design,naming,unusedcode; }
36 | export -f phpmd
37 | insertafter: EOF
38 | marker: "# {mark} MANAGED PHPMD BLOCK"
39 | when: phpmd_alias.stdout == 'absent'
40 |
--------------------------------------------------------------------------------
/app/orchestration/plays/tools/sass.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "SASS: Install compass"
3 | package:
4 | name: "{{ item }}"
5 | state: present
6 | with_items:
7 | - ruby-compass
8 | - ruby-sass
9 |
--------------------------------------------------------------------------------
/app/orchestration/plays/tools/tideways.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "TIDEWAYS: Check if the extension is installed"
3 | stat:
4 | path: "{{ tideways_extension_path }}"
5 | register: tideways
6 |
7 | - name: "TIDEWAYS: Check if the extension can be updated"
8 | shell: php -c {{ default_php_ini }} -i | grep 'tideways' | grep -o '{{ tideways_stable_release }}' || echo 'update'
9 | register: tideways_version_check
10 | changed_when: tideways_version_check.stdout == "update"
11 |
12 | - name: "TIDEWAYS: Copy latest release from mirror"
13 | get_url:
14 | url: "{{ tideways_mirror_download_link }}"
15 | dest: "{{ download_dir }}"
16 | validate_certs: no
17 | register: tideways_get_url_result
18 | until: "'OK' in tideways_get_url_result.msg"
19 | retries: 3
20 | delay: 10
21 | when: tideways.stat.exists == false or tideways_version_check.stdout != tideways_stable_release
22 |
23 | - name: "TIDEWAYS: Extract files"
24 | unarchive:
25 | src: "{{ tideways_archive }}"
26 | dest: "{{ download_dir }}"
27 | copy: no
28 | when: tideways.stat.exists == false or tideways_version_check.stdout != tideways_stable_release
29 |
30 | - name: "TIDEWAYS: Compile extension"
31 | command: "{{ item }} chdir={{ tideways_temp_dir }}"
32 | with_items:
33 | - /usr/bin/phpize
34 | - ./configure
35 | - /usr/bin/make
36 | - /usr/bin/make install
37 | register: compile_tideways
38 | when: tideways.stat.exists == false or tideways_version_check.stdout != tideways_stable_release
39 |
40 | - name: "TIDEWAYS: Copy compiled extension"
41 | command: cp {{ tideways_temp_dir }}/modules/{{ tideways_extension_name }} {{ default_php_extensions }}
42 | when: tideways.stat.exists == false or tideways_version_check.stdout != tideways_stable_release
43 |
44 | - name: "TIDEWAYS: Make sure permissions are correct"
45 | file:
46 | path: "{{ tideways_extension_path }}"
47 | mode: 0644
48 | when: tideways.stat.exists == false or tideways_version_check.stdout != tideways_stable_release
49 |
50 | - name: "TIDEWAYS: Delete temporary directory"
51 | file:
52 | path: "{{ tideways_temp_dir }}"
53 | state: absent
54 | when: tideways.stat.exists == false or tideways_version_check.stdout != tideways_stable_release
55 |
56 | - name: "TIDEWAYS: Check config in php.ini"
57 | shell: grep -o "{{ tideways_extension_name }}" {{ default_php_ini }} || echo "absent"
58 | register: tideways_config
59 | changed_when: tideways_config == "absent"
60 |
61 | - name: "TIDEWAYS: Create output directory"
62 | file:
63 | path: "{{ tideways_output_dir }}"
64 | state: directory
65 | mode: 0777
66 | when: tideways_config.stdout == "absent"
67 |
68 | - name: "TIDEWAYS: Configure extension in php.ini"
69 | blockinfile:
70 | dest: "{{ default_php_ini }}"
71 | block: |
72 | extension={{ tideways_extension_path }}
73 | tideways.output_dir={{ tideways_output_dir }}
74 | marker: ; {mark} MANAGED TIDEWAYS BLOCK
75 | when: tideways_config.stdout == "absent"
76 |
77 | - name: "TIDEWAYS: Ensure Apache is restarted to load the extension"
78 | service:
79 | name: apache2
80 | enabled: yes
81 | state: restarted
82 |
83 | - name: "TIDEWAYS: Ensure PHP-FPM is restarted to load the extension"
84 | service:
85 | name: php{{ default_php_version }}-fpm
86 | enabled: yes
87 | state: restarted
88 |
--------------------------------------------------------------------------------
/app/orchestration/plays/tools/xdebug.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: "XDEBUG: Check if the extension is installed"
3 | stat:
4 | path: "{{ xdebug_extension_path }}"
5 | register: xdebug
6 |
7 | - name: "XDEBUG: Check if the extension can be updated"
8 | shell: ls {{ xdebug_archive_path }} | grep -o {{ xdebug_stable_release }} || echo "absent"
9 | register: xdebug_update
10 | when: xdebug.stat.exists == true
11 | changed_when: xdebug_update.stdout == "absent"
12 |
13 | - name: "XDEBUG: Copy latest release from mirror"
14 | get_url:
15 | url: "{{ xdebug_mirror_download_link }}"
16 | dest: "{{ download_dir }}"
17 | validate_certs: no
18 | register: xdebug_get_url_result
19 | until: "'OK' in xdebug_get_url_result.msg"
20 | retries: 3
21 | delay: 10
22 | when: xdebug.stat.exists == false or xdebug_update.stdout != xdebug_stable_release
23 |
24 | - name: "XDEBUG: Extract files"
25 | unarchive:
26 | src: "{{ xdebug_archive_path }}"
27 | dest: "{{ download_dir }}"
28 | copy: no
29 | when: xdebug.stat.exists == false or xdebug_update.stdout != xdebug_stable_release
30 |
31 | - name: "XDEBUG: Compile the extension"
32 | command: "{{ item }} chdir={{ xdebug_unarchived_path }}"
33 | with_items:
34 | - /usr/bin/phpize
35 | - ./configure
36 | - /usr/bin/make
37 | register: compile_xdebug
38 | when: xdebug.stat.exists == false or xdebug_update.stdout != xdebug_stable_release
39 |
40 | - name: "XDEBUG: Copy compiled extension"
41 | command: cp {{ xdebug_unarchived_path }}/modules/{{ xdebug_extension_name }} {{ default_php_extensions }}
42 | when: xdebug.stat.exists == false or xdebug_update.stdout != xdebug_stable_release
43 |
44 | - name: "XDEBUG: Make sure permissions are correct"
45 | file:
46 | path: "{{ xdebug_extension_path }}"
47 | mode: 0644
48 | when: xdebug.stat.exists == false or xdebug_update.stdout != xdebug_stable_release
49 |
50 | - name: "XDEBUG: Delete temporary directory"
51 | file:
52 | path: "{{ xdebug_unarchived_path }}"
53 | state: absent
54 | when: xdebug.stat.exists == false or xdebug_update.stdout != xdebug_stable_release
55 |
56 | - name: "XDEBUG: Check config in php.ini"
57 | shell: grep -o "{{ xdebug_extension_name }}" {{ default_php_ini }} || echo "absent"
58 | register: xdebug_config
59 | changed_when: xdebug_config.stdout == "absent"
60 |
61 | - name: "XDEBUG: Configure extension in php.ini"
62 | blockinfile:
63 | dest: "{{ default_php_ini }}"
64 | block: |
65 | zend_extension = {{ xdebug_extension_path }}
66 | xdebug.remote_host={{ xdebug_remote_host }}
67 | xdebug.remote_port=9000
68 | xdebug.remote_enable=1
69 | xdebug.max_nesting_level=256
70 | marker: ; {mark} MANAGED XDEBUG BLOCK
71 | when: xdebug_config.stdout == "absent"
72 |
--------------------------------------------------------------------------------
/app/orchestration/provisioning/base.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_base
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/system/ssh.yml
12 | - import_tasks: ../plays/system/system-setup.yml
13 | - import_tasks: ../plays/system/git.yml
14 |
--------------------------------------------------------------------------------
/app/orchestration/provisioning/db.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_db
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/common/mirror-deploy.yml
12 | - import_tasks: ../plays/common/apt-update.yml
13 | - import_tasks: ../plays/db/mysql.yml
14 | - import_tasks: ../plays/db/memcached.yml
15 | - import_tasks: ../plays/db/mysql-backup.yml
16 |
--------------------------------------------------------------------------------
/app/orchestration/provisioning/edge.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_edge
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/common/mirror-deploy.yml
12 | - import_tasks: ../plays/common/apt-update.yml
13 | - import_tasks: ../plays/edge/varnish.yml
14 | - import_tasks: ../plays/edge/nginx.yml
15 |
--------------------------------------------------------------------------------
/app/orchestration/provisioning/mirror.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_mirror
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/common/apache-installation.yml
12 | - import_tasks: ../plays/mirror/mirror-vhost.yml
13 | - import_tasks: ../plays/common/apt-repos.yml
14 | - import_tasks: ../plays/common/mirror-downloads.yml
15 | - import_tasks: ../plays/mirror/mirror-setup.yml
16 |
--------------------------------------------------------------------------------
/app/orchestration/provisioning/search.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_search
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/common/mirror-deploy.yml
12 | - import_tasks: ../plays/common/apt-update.yml
13 | - import_tasks: ../plays/solr/java.yml
14 | - import_tasks: ../plays/solr/solr.yml
15 |
--------------------------------------------------------------------------------
/app/orchestration/provisioning/ssh.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_web
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/system/ssh-keys.yml
12 |
--------------------------------------------------------------------------------
/app/orchestration/provisioning/web.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: drucker_web
3 | become: yes
4 |
5 | gather_facts: yes
6 | vars_files:
7 | - ../vars.yml
8 | handlers:
9 | - import_tasks: ../handlers.yml
10 | tasks:
11 | - import_tasks: ../plays/common/mirror-deploy.yml
12 | - import_tasks: ../plays/common/apt-update.yml
13 | - import_tasks: ../plays/stack.yml
14 | - import_tasks: ../plays/post-install.yml
15 |
--------------------------------------------------------------------------------
/app/requirements.txt:
--------------------------------------------------------------------------------
1 | colorful
2 | docker
3 |
--------------------------------------------------------------------------------
/app/services.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """Checks if services are correctly running in containers"""
3 |
4 | import subprocess
5 | import colorful
6 |
7 |
8 | def check(container, service, name):
9 | """Starts common services if they're down"""
10 | if not subprocess.getoutput(
11 | "docker exec -it %s pgrep %s | head -1" % (container, service)
12 | ):
13 | print(colorful.red("!!! %s is down." % (name)) + " Starting...")
14 | subprocess.getoutput(
15 | "docker exec -it %s service %s start" % (container, service)
16 | )
17 | else:
18 | print("- %s is up" % (name))
19 |
20 |
21 | def phpfpm(drucker):
22 | """Starts PHP-FPM if it's down"""
23 | if not subprocess.getoutput(
24 | "docker exec -it %s pgrep php-fpm%s | head -1"
25 | % (drucker.vars.WEB_CONTAINER, drucker.vars.DEFAULT_PHP)
26 | ):
27 | print(colorful.red("!!! PHP-FPM is down.") + " Starting...")
28 | subprocess.getoutput(
29 | "docker exec -it %s service php%s-fpm start"
30 | % (drucker.vars.WEB_CONTAINER, drucker.vars.DEFAULT_PHP)
31 | )
32 | else:
33 | print("- PHP-FPM is up")
34 |
35 |
36 | def memcached(container):
37 | """Starts memcached if it's down"""
38 | if not subprocess.getoutput("docker exec -it %s pgrep memcached" % (container)):
39 | print(colorful.red("!!! memcached is down.") + " Starting...")
40 | subprocess.getoutput(
41 | "docker exec -it %s memcached -d -u nobody -m 64 -p 11211 127.0.0.1"
42 | % (container)
43 | )
44 | else:
45 | print("- memcached is up")
46 |
47 |
48 | def solr(container):
49 | """Starts Apache Solr if it's down"""
50 | if not subprocess.getoutput("docker exec -it %s pgrep java" % (container)):
51 | print(colorful.red("!!! Apache Solr is down.") + " Starting...")
52 | subprocess.getoutput(
53 | "docker exec -it -u solr %s /opt/solr/bin/solr start" % (container)
54 | )
55 | else:
56 | print("- Apache Solr is up")
57 |
--------------------------------------------------------------------------------
/app/variables.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """Common variables used across the app"""
3 |
4 | import os
5 | from pathlib import Path
6 |
7 |
8 | APP = "drucker"
9 | APP_VERSION = "dev"
10 | APP_ROOT = os.path.dirname(os.path.dirname(__file__))
11 | APP_DIR = "%s/app" % (APP_ROOT)
12 | HOME = str(Path.home())
13 |
14 | EXECUTABLES = ["docker", "ansible"]
15 | EXITCODE_FAIL = 1
16 | EXITCODE_OK = 0
17 | DOMAINS = "drucker.local phpmyadmin.local adminer.local\
18 | lightning.local blt.local"
19 | HOSTS = "/etc/hosts"
20 | TEST_GROUPS = ["system", "mirror", "edge", "db", "search", "web"]
21 |
22 | # SSH
23 | SSH_CONFIG = "%s/.ssh/config" % (HOME)
24 |
25 | # IP addresses
26 | BASE_IP = "203.0.113.99"
27 | MIRROR_IP = "203.0.113.50"
28 | EDGE_IP = "203.0.113.2"
29 | DB_IP = "203.0.113.12"
30 | WEB_IP = "203.0.113.10"
31 | SEARCH_IP = "203.0.113.13"
32 |
33 | # config file
34 | DEFAULT_CONFIG = APP_ROOT + "/config"
35 | DEFAULT_PUBKEY = "%s/.ssh/id_rsa.pub" % (HOME)
36 | DEFAULT_HTML_PATH = "/var/www/html"
37 | DEFAULT_DB_PATH = "/var/lib/mysql"
38 | KEY_PLACEHOLDER = "key_path"
39 | HTML_PLACEHOLDER = "html_path"
40 | DB_PLACEHOLDER = "db_path"
41 |
42 | # Docker networking
43 | SUBNET = "203.0.113.0/24"
44 | GATEWAY = "203.0.113.254"
45 | CHECK_BRIDGE = "docker network ls | awk '{print $2}' | grep '%s'" % (APP)
46 | CREATE_BRIDGE = """
47 | docker network create --subnet \"%s\" --gateway \"%s\" \"%s\"
48 | """ % (
49 | SUBNET,
50 | GATEWAY,
51 | APP,
52 | )
53 |
54 | # Docker images
55 | DISTRO_IMAGE = "debian:stretch"
56 | INIT_IMAGE = "%s:init" % (APP)
57 | BASE_IMAGE = "%s:base" % (APP)
58 | MIRROR_IMAGE = "%s:mirror" % (APP)
59 | EDGE_IMAGE = "%s:edge" % (APP)
60 | DB_IMAGE = "%s:db" % (APP)
61 | WEB_IMAGE = "%s:web" % (APP)
62 | SEARCH_IMAGE = "%s:search" % (APP)
63 | CHECK_DISTRO_IMAGE = 'docker images | awk \'{print $1":"$2}\' | grep "%s"' % (
64 | DISTRO_IMAGE
65 | )
66 | CHECK_INIT_IMAGE = "docker images | awk '{print $1\":\"$2}' | grep %s" % (INIT_IMAGE)
67 | CHECK_BASE_IMAGE = "docker images | awk '{print $1\":\"$2}' | grep %s" % (BASE_IMAGE)
68 | CHECK_SEARCH_IMAGE = 'docker images | awk \'{print $1":"$2}\' | grep "%s"' % (
69 | SEARCH_IMAGE
70 | )
71 | UPDATE_DISTRO_IMAGE = """
72 | docker images | awk '{print $1\":\"$2}' | grep \"%s\" | xargs -L1 docker pull
73 | """ % (
74 | DISTRO_IMAGE
75 | )
76 | PULL_DISTRO_IMAGE = "docker pull %s" % (DISTRO_IMAGE)
77 |
78 | # Docker containers
79 | BASE_CONTAINER = "%s_base" % (APP)
80 | MIRROR_CONTAINER = "%s_mirror" % (APP)
81 | EDGE_CONTAINER = "%s_edge" % (APP)
82 | DB_CONTAINER = "%s_db" % (APP)
83 | WEB_CONTAINER = "%s_web" % (APP)
84 | SEARCH_CONTAINER = "%s_search" % (APP)
85 |
86 | CONTAINERS = [
87 | MIRROR_CONTAINER,
88 | EDGE_CONTAINER,
89 | DB_CONTAINER,
90 | WEB_CONTAINER,
91 | SEARCH_CONTAINER,
92 | ]
93 |
94 | # Hostnames
95 | TLD = "local"
96 | MIRROR_HOSTNAME = "mirror.%s" % (TLD)
97 | EDGE_HOSTNAME = "edge.%s" % (TLD)
98 | WEB_HOSTNAME = "web.%s" % (TLD)
99 | DB_HOSTNAME = "db.%s" % (TLD)
100 | SEARCH_HOSTNAME = "search.%s" % (TLD)
101 |
102 | # Ports
103 | HOST_EDGE_PORT = "81"
104 | MIRROR_PORT = "3142"
105 | EDGE_PORT = "80"
106 | HOST_WEB_PORT = "8180"
107 | HOST_DB_PORT = "3307"
108 | HOST_SEARCH_PORT = "8984"
109 | WEB_PORT = "8080"
110 | DB_PORT = "3306"
111 | SEARCH_PORT = "8983"
112 | HOST_TCP_PORT_MAPPER_WEB = "2047"
113 | TCP_PORT_MAPPER_WEB = "2049"
114 | HOST_TCP_PORT_MAPPER_DB = "2051"
115 | TCP_PORT_MAPPER_DB = "2052"
116 |
117 | # Volume mappings
118 | CONTAINER_DB_PATH = "/var/lib/mysql"
119 | CONTAINER_HTML_PATH = "/var/www/html"
120 | CONTAINER_IMPORT_PATH = "%s/import" % (CONTAINER_HTML_PATH)
121 | HOST_HTML_PATH = CONTAINER_HTML_PATH
122 |
123 | # Services
124 | DEFAULT_PHP = "7.3"
125 | PREVIOUS_PHP = "7.2"
126 | LEGACY_PHP = "7.1"
127 |
128 | # Database
129 | MYSQL_DIR_OWNERSHIP = "mysql"
130 |
--------------------------------------------------------------------------------
/config:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | export SSH_PUBKEY="key_path"
4 | export LOCAL_HTML_PATH="html_path"
5 | export LOCAL_DB_PATH="db_path"
6 |
--------------------------------------------------------------------------------
/drucker:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | """drucker main dispatcher."""
4 | import sys
5 | import colorful
6 | import app
7 |
8 |
9 | def dispatch_the_provisioner(drucker):
10 | """drucker initialization, container provisioning and orchestration."""
11 | app.init.main(drucker)
12 | app.base.main(drucker)
13 | app.mirror.main(drucker)
14 | app.edge.main(drucker)
15 | app.db.main(drucker)
16 | app.search.main(drucker)
17 | app.web.main(drucker)
18 | return drucker.vars.EXITCODE_OK
19 |
20 |
21 | if __name__ == "__main__":
22 | PARSER = app.arguments.get_parser()
23 |
24 | # Name the argparse Namespace object 'DRUCKER'. The 'DRUCKER' object
25 | # travels deep into the codebase since its passed on from here to all
26 | # dispatched code. The drucker object holds more than just CLI-arguments,
27 | # making it the central backbone object of all code:
28 | #
29 | # - DRUCKER.vars:
30 | # The app.variables module, for easy access everywhere.
31 | #
32 | # - DRUCKER.dispatched_function:
33 | # A reference to the function object that got called during
34 | # runtime. It is 'None' when Drucker ran without CLI arguments.
35 | #
36 | # - DRUCKER.app:
37 | # The 'app' argument used for orchestration functions.
38 | #
39 | DRUCKER = PARSER.parse_args()
40 | DRUCKER.vars = app.variables
41 |
42 | # Dispatch and execute Drucker from a central try/except block. We do this
43 | # to catch all exceptions in a single place, more except blocks can be
44 | # added in the future for more granular cases (e.g. 'KeyboardInterrupt').
45 | # @see https://realpython.com/python-exceptions/
46 | try:
47 | # Make sure the app can run successfully.
48 | app.requirements.main(DRUCKER)
49 | app.local_setup.main(DRUCKER)
50 |
51 | if DRUCKER.dispatched_function:
52 | EXITCODE = DRUCKER.dispatched_function(DRUCKER)
53 | else:
54 | EXITCODE = dispatch_the_provisioner(DRUCKER)
55 | sys.exit(EXITCODE)
56 |
57 | # RuntimeWarning's are non-fatal and won't stop the program.
58 | except RuntimeWarning as warning:
59 | print(colorful.orange(warning))
60 | pass
61 |
62 | # RuntimeError's are fatal and stop the program.
63 | except RuntimeError as err:
64 | print(colorful.red(err))
65 | sys.exit(DRUCKER.vars.EXITCODE_FAIL)
66 |
67 | # Catch all uncaught exceptions and re-raise it.
68 | #
69 | # When this happens its by definition a software bug in Drucker. Because
70 | # of this, we re-raise it using 'raise' so that the backtrace is printed
71 | # and a bug report can be filed.
72 | except Exception as err:
73 | print("\nTHIS UNEXPECTED ERROR OCCURED:\n%s\n\n" % colorful.red(err))
74 | raise
75 |
--------------------------------------------------------------------------------
/drucker-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anavarre/drucker/67fc709be04b113ec4576f0732fa08bd27c211e5/drucker-logo.png
--------------------------------------------------------------------------------
/util/drucker-screencast.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Run:
4 | # $ clear ; asciinema rec -t "drucker" -w 2 /tmp/drucker.json
5 | # Then, immediately after:
6 | # $ ./drucker-screencast.sh
7 | # To upload the screencast, type:
8 | # $ asciinema upload /tmp/drucker.json
9 |
10 | function recorder_check() {
11 | RECORDER="$(which asciinema)"
12 |
13 | if [[ ! ${RECORDER} ]]; then
14 | echo 'asciinema must be installed to run this script.'
15 | exit 0
16 | fi
17 | }
18 |
19 | recorder_check
20 |
21 | function wait() {
22 | sleep 2
23 | echo ---------------------------------------------
24 | sleep 3
25 | }
26 |
27 | function separator() {
28 | echo -e "\n"
29 | sleep 2
30 | }
31 |
32 | clear
33 |
34 | echo "*******************************************"
35 | echo "* *"
36 | echo "* This is a quick introduction to drucker *"
37 | echo "* https://github.com/anavarre/drucker *"
38 | echo "* *"
39 | echo "*******************************************"
40 |
41 | sleep 2
42 |
43 | separator
44 | echo "First, let's get confirmation we meet the
45 | minimum software requirements."
46 |
47 | wait
48 |
49 | docker --version |\
50 | awk '{print $3}' |\
51 | cut -c -6 |\
52 | xargs echo Docker version:
53 |
54 | ansible --version |\
55 | awk '{print $2}' |\
56 | xargs echo Ansible version: |\
57 | cut -c -24 ;
58 |
59 | separator
60 |
61 | echo "Now we can check both our Docker images and
62 | corresponding containers are alive and well."
63 |
64 | wait
65 |
66 | docker ps --format 'table {{.Names}}\t{{.Image}}'
67 |
68 | separator
69 | echo "Next up, we want to ensure our hosts file is
70 | correctly configured."
71 |
72 | wait
73 |
74 | tail -n3 /etc/hosts
75 |
76 | separator
77 | echo "To make sure SSH access will be working, we
78 | also need to confirm our config file exists"
79 |
80 | wait
81 |
82 | cat ~/.ssh/config
83 |
84 | separator
85 | echo ">>>> You can find all of the above in the README.md file."
86 |
87 | separator
88 | echo "Okay. Now, let's explore what drucker has to
89 | offer. Type 'drucker help'"
90 |
91 | wait
92 |
93 | "$HOME/Sites/git/github/drucker/drucker" --help
94 |
95 | separator
96 |
97 | echo "Assumptions are being made both with the 'dev'
98 | and 'prod' modes. Just type 'drucker' if you wish
99 | to go with the defaults only."
100 |
101 | wait
102 | separator
103 |
104 | echo "Let's go ahead and run drucker!"
105 |
106 | wait
107 |
108 | "$HOME/Sites/git/github/drucker/drucker"
109 |
110 | separator
111 | echo "That was pretty fast, right? This is because
112 | both the images and containers already exist.
113 | It'll take a good 10-15mn on average broadband
114 | when you run it for the first time."
115 |
116 | separator
117 | sleep 2
118 | echo "OK. Now let's check the headers."
119 |
120 | wait
121 |
122 | http -h drucker.local | egrep '(X-Generator:|Server:|Via:)'
123 |
124 | separator
125 | echo "Excellent. We're running Drupal 8 behind
126 | Varnish and nginx. Non-cacheable requests will be
127 | sent to the Apache backend as with a normal stack."
128 |
129 | separator
130 | echo "This is drucker in a nutshell. Hope you like it.
131 | Thanks for watching!"
132 |
--------------------------------------------------------------------------------
/util/var_usage.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ANSIBLE_VARS="../orchestration/vars.yml"
4 | PREPARE_FILE=$(awk '{print $1}' ${ANSIBLE_VARS} | grep -Ev '(#|^$)' | sed 's/.$//')
5 |
6 | arr=(${PREPARE_FILE})
7 | echo ${arr[@]}
8 |
--------------------------------------------------------------------------------