diff --git a/src/Handler.php b/src/Handler.php index 7ab602ebd090029c0769646f47075b8a4117be8b..6d9c5246bd80e1a2c3b60e1ed8cc6e1b809e3941 100644 --- a/src/Handler.php +++ b/src/Handler.php @@ -15,7 +15,7 @@ use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Yaml\Yaml; /** - * Class Handler. + * Handler for Docker4Drupal. * * @package LakeDrops\Docker4Drupal */ @@ -61,25 +61,21 @@ class Handler extends BaseHandler { ], 'ci_home' => '/home/gitlab-runner', 'docker0' => [ - 'ip' => ($this->isCiContext() || $this->isLocalDevMode()) ? - $this->getDockerGateway() : - $this->getLocalIpv4('docker0'), - 'proxy' => ($this->isCiContext() || $this->isLocalDevMode()) ? - $this->getDockerProxy() : - FALSE, + 'ip' => ($this->isCiContext() || $this->isLocalDevMode()) ? $this->getDockerGateway() : $this->getLocalIpv4('docker0'), + 'proxy' => ($this->isCiContext() || $this->isLocalDevMode()) ? $this->getDockerProxy() : FALSE, ], 'traefik' => [ 'domain' => $this->env->receive('traefik_domain', '', 'docker.localhost'), 'usessl' => $this->env->receive('traefik_usessl', '', '0'), 'port' => $this->env->receive('traefik_port', '', '8000'), 'ports' => $this->env->receive('traefik_ports', '', '8443'), - 'cert' => $this->env->receive('traefik_cert', '', ''), - 'key' => $this->env->receive('traefik_key', '', ''), + 'cert' => $this->env->receive('traefik_cert', ''), + 'key' => $this->env->receive('traefik_key', ''), 'portainer' => $this->env->receive('traefik_portainer', '', '0'), - 'hub_token' => $this->env->receive('traefik_hub_token', '', ''), + 'hub_token' => $this->env->receive('traefik_hub_token', ''), 'dns_challenge' => $this->env->receive('traefik_dns_challenge', '', '0'), - 'dns_challenge_provider' => $this->env->receive('traefik_dns_challenge_provider', '', ''), - 'dns_challenge_resolver' => $this->env->receive('traefik_dns_challenge_resolver', '', ''), + 'dns_challenge_provider' => $this->env->receive('traefik_dns_challenge_provider', ''), + 'dns_challenge_resolver' => $this->env->receive('traefik_dns_challenge_resolver', ''), 'env' => $traefik_env, ], 'live' => [ @@ -198,7 +194,7 @@ class Handler extends BaseHandler { ], 'backup' => [ 'enable' => FALSE, - 'version' => 'base-1.2.0-1.6.0', + 'version' => '1.8', 'crontime' => '50 */6 * * *', 'crontimecheck' => '30 23 1 * *', 'remoterepo' => FALSE, @@ -266,7 +262,7 @@ class Handler extends BaseHandler { } $this->config->setValue('php', $php, FALSE); - // Get ID of Docker group + // Get ID of Docker group. $docker_group_id = trim(shell_exec('stat -c "%g" /var/run/docker.sock')); $this->config->setValue('docker_group_id', $docker_group_id, FALSE); @@ -439,11 +435,11 @@ class Handler extends BaseHandler { $extraOptions = $this->config->readValue($filename); if (!empty($def['add2yaml']) && $extraOptions !== NULL) { $yaml = Yaml::parse($rendered); - /** @noinspection SlowArrayOperationsInLoopInspection */ + /* @noinspection SlowArrayOperationsInLoopInspection */ $yaml = array_merge_recursive($yaml, $extraOptions); $rendered = Yaml::dump($yaml, 9, 2); - // Render the string again so that custom content can also use variables + // Render string again so that custom content can also use variables. $rendered = $this->config->render($filename, $rendered); } elseif ($extraOptions !== NULL) { @@ -503,19 +499,20 @@ class Handler extends BaseHandler { $this->gitIgnore('tests/backstop/backstop_data/html_report'); $this->gitLFS('tests/backstop/**/*.png'); - // Ignore some Cypress directories + // Ignore some Cypress directories. $this->gitIgnore('tests/cypress/downloads'); $this->gitIgnore('tests/cypress/screenshots'); $this->gitIgnore('tests/cypress/videos'); - // Ignore some Unlighthouse directories + // Ignore some Unlighthouse directories. $this->gitIgnore('tests/unlighthouse'); if (getenv('LAKEDROPS_BUILD_NG') !== 'yes') { $this->updateTraefik(); } - // Set permissions, see https://wodby.com/stacks/drupal/docs/local/permissions + // Set permissions. + // @see https://wodby.com/stacks/drupal/docs/local/permissions exec('setfacl -dR -m u:$(whoami):rwX -m u:82:rwX -m u:100:rX -m g::rwX ' . $projectRoot . ' >/dev/null 2>&1'); exec('setfacl -R -m u:$(whoami):rwX -m u:82:rwX -m u:100:rX -m g::rwX ' . $projectRoot . ' >/dev/null 2>&1'); } @@ -536,7 +533,7 @@ class Handler extends BaseHandler { */ private function updateTraefik(): void { if (getenv('TRAEFIK_HOST') === 'yes') { - // Traefik is already available and controlled by the host. Don't touch it. + // Traefik is already available & controlled by the host. Don't touch it. return; } $traefik = new Traefik( @@ -798,10 +795,10 @@ class Handler extends BaseHandler { */ private function getLocalIpv4(string $interface = NULL) { $out = explode(PHP_EOL, shell_exec('LC_ALL=C /sbin/ifconfig')); - $local_addrs = array(); + $local_addrs = []; $ifname = 'unknown'; foreach ($out as $str) { - $matches = array(); + $matches = []; if (preg_match('/^([a-z0-9]+)(:\d{1,2})?(\s)+Link/', $str, $matches)) { $ifname = $matches[1]; if ($matches[2] !== '') { @@ -820,7 +817,10 @@ class Handler extends BaseHandler { } /** + * Get Docker gateway IP from docker inspect. + * * @return string + * The gateay IP. */ private function getDockerGateway(): string { $container = $this->readContainerConfig(); @@ -828,11 +828,18 @@ class Handler extends BaseHandler { } /** + * Get Docker Proxy IP from docker inspect. + * * @return string + * The proxy IP. */ private function getDockerProxy(): string { foreach ($this->readNetworkConfig()['Containers'] as $container) { - if (isset($container['Name']) && in_array($container['Name'], ['traefik', 'traefik_traefik_1', 'traefik-traefik-1'])) { + if (isset($container['Name']) && in_array($container['Name'], [ + 'traefik', + 'traefik_traefik_1', + 'traefik-traefik-1', + ])) { return explode('/', $container['IPv4Address'])[0]; } } @@ -840,11 +847,15 @@ class Handler extends BaseHandler { } /** - * @param $projectRoot + * Get Docker mount source from docker inspect. + * + * @param string $projectRoot + * The project root directory. * * @return string + * The mount source. */ - private function getDockerMountSource($projectRoot): string { + private function getDockerMountSource(string $projectRoot): string { $currentDir = getcwd(); $container = $this->readContainerConfig(); foreach ($container['Mounts'] as $mount) { @@ -853,7 +864,7 @@ class Handler extends BaseHandler { return $mount['Source']; } } - else if (strpos($projectRoot, $mount['Destination']) === 0) { + elseif (strpos($projectRoot, $mount['Destination']) === 0) { return $mount['Source'] . substr($projectRoot, strlen($mount['Destination'])); } } @@ -861,12 +872,15 @@ class Handler extends BaseHandler { } /** + * Get container details from docker inspect. + * * @return array + * The container details. */ private function readContainerConfig(): array { try { $testString = 'This is a test file for LakeDrops GitLab CI'; - $filename = '/tmp/' . random_int(100,999) . '.test'; + $filename = '/tmp/' . random_int(100, 999) . '.test'; file_put_contents($filename, $testString); $output = []; exec('docker ps -q', $output); @@ -898,13 +912,16 @@ class Handler extends BaseHandler { } /** + * Get network configuration from docker inspect. + * * @return array + * The network configuration. */ private function readNetworkConfig(): array { try { $output = []; exec('docker network inspect traefik-public', $output); - return json_decode(implode('', $output), TRUE)[0]; + return json_decode(implode('', $output), TRUE, 512, JSON_THROW_ON_ERROR)[0]; } catch (\Exception $ex) { // Ignore. @@ -915,7 +932,10 @@ class Handler extends BaseHandler { } /** + * Get default configuration for backstop. + * * @return array + * The default configuration for backstop. */ private function backstopDefaults(): array { return [ diff --git a/templates/backup/config.yaml.twig b/templates/backup/config.yaml.twig index 866139b2674639d223cb72913522b00b6c0f4886..aaa49f8ae08237cad017118bf7b588896ac402e4 100644 --- a/templates/backup/config.yaml.twig +++ b/templates/backup/config.yaml.twig @@ -1,58 +1,55 @@ -location: - source_directories: - - /mnt/source - repositories: - - /mnt/borg-repository +source_directories: + - /mnt/source +repositories: + - path: /mnt/borg-repository + label: local {% if backup.remoterepo|default(0) %} - - {{ backup.remoterepo }} + - path: {{ backup.remoterepo }} + label: remote {% endif %} - one_file_system: true - exclude_patterns: - - '*.log' - - '*.pyc' - - '*/.git' - - '*/.svn' - - '*/vendor/*' - - '*/node_modules/*' - exclude_caches: true - exclude_if_present: '.nobackup' +one_file_system: true +exclude_patterns: + - '*.log' + - '*.pyc' + - '*/.git' + - '*/.svn' + - '*/vendor/*' + - '*/node_modules/*' +exclude_caches: true +exclude_if_present: + - '.nobackup' -storage: - # Passphase is set in varibable $BORG_PASSPHRASE - # encryption_passphrase: "DonNotMissToChangeYourPassphrase" - compression: lz4 - archive_name_format: 'backup-{now}' - retries: 3 - retry_wait: 300 +# Passphase is set in varibable $BORG_PASSPHRASE +# encryption_passphrase: "DonNotMissToChangeYourPassphrase" +compression: lz4 +archive_name_format: 'backup-{now}' +retries: 3 +retry_wait: 300 -retention: - keep_hourly: {{ backup.retention.hourly }} - keep_daily: {{ backup.retention.daily }} - keep_weekly: {{ backup.retention.weekly }} - keep_monthly: {{ backup.retention.monthly }} - keep_yearly: {{ backup.retention.yearly }} - prefix: 'backup-' +keep_hourly: {{ backup.retention.hourly }} +keep_daily: {{ backup.retention.daily }} +keep_weekly: {{ backup.retention.weekly }} +keep_monthly: {{ backup.retention.monthly }} +keep_yearly: {{ backup.retention.yearly }} +prefix: 'backup-' -consistency: - checks: - - repository - - archives - check_last: 3 - prefix: 'backup-' +checks: + - name: repository + - name: archives +check_last: 3 -hooks: - mysql_databases: - - name: drupal - hostname: mariadb - port: 3306 - username: drupal - password: drupal - options: '--skip-comments --no-tablespaces' - before_backup: - - echo "`date` - Starting backup" - after_backup: - - echo "`date` - Finished backup" +mysql_databases: + - name: drupal + hostname: mariadb + port: 3306 + username: drupal + password: drupal + options: '--skip-comments --no-tablespaces' +before_backup: + - echo "`date` - Starting backup" +after_backup: + - echo "`date` - Finished backup" {% if alerta is defined %} - on_error: - - echo -n '{"service":["https://www.borgbase.com"],"resource":"{{ HOST_NAME|default('unknown') }}","event":"Borg {configuration_filename}","value":"{repository}","text":"Borg {configuration_filename}","rawData":"{output}"}' | nc -u -w1 alerta {{ alerta.proxy_port|default(20002) }} +on_error: + - echo -n '{"service":["https://www.borgbase.com"],"resource":"{{ HOST_NAME|default('unknown') }}","event":"Borg {configuration_filename}","value":"{repository}","text":"Borg {configuration_filename}","rawData":"{output}"}' | nc -u -w1 alerta {{ alerta.proxy_port|default(20002) }} {% endif %} diff --git a/templates/backup/crontab.txt.twig b/templates/backup/crontab.txt.twig index 98468fa9f5b26604833a15eb85f77683b364e591..a3a8bdd3cd5e855db186309627d9a730d40e3678 100644 --- a/templates/backup/crontab.txt.twig +++ b/templates/backup/crontab.txt.twig @@ -1,2 +1,2 @@ -{{ backup.crontime }} PATH=$PATH:/usr/bin /usr/bin/borgmatic --stats -v 0 2>&1 && curl -fsS --retry 5 --retry-delay 9 -o /dev/null {{ backup.healthckeck_url.backup }} -{{ backup.crontimecheck }} PATH=$PATH:/usr/bin /usr/bin/borgmatic --check -v 0 2>&1 && curl -fsS --retry 5 --retry-delay 9 -o /dev/null {{ backup.healthckeck_url.check }} +{{ backup.crontime }} PATH=$PATH:/usr/bin /usr/local/bin/borgmatic --stats -v 0 2>&1 && curl -fsS --retry 5 --retry-delay 9 -o /dev/null {{ backup.healthckeck_url.backup }} +{{ backup.crontimecheck }} PATH=$PATH:/usr/bin /usr/local/bin/borgmatic --check -v 0 2>&1 && curl -fsS --retry 5 --retry-delay 9 -o /dev/null {{ backup.healthckeck_url.check }} diff --git a/templates/docker-compose.yml.twig b/templates/docker-compose.yml.twig index c427d90408cdcf157e2b934614c2ca7607d377a9..d65e906f6644962e739d0760fe63f098ac5f3441 100644 --- a/templates/docker-compose.yml.twig +++ b/templates/docker-compose.yml.twig @@ -586,6 +586,9 @@ services: image: 'registry.lakedrops.com/docker/cypress:{{ cypress.version }}' environment: - CYPRESS_baseUrl={{ projectprotocol }}://{{ projectdomain }}{{ projectport }} +{% if mailpit.enable %} + - CYPRESS_mailpitUrl={{ projectprotocol }}://mailpit-{{ projectdomain }}{{ projectport }} +{% endif %} {% if mailhog.enable %} - CYPRESS_mailhogUrl={{ projectprotocol }}://mailhog-{{ projectdomain }}{{ projectport }} {% endif %} diff --git a/templates/tests/cypress-run.twig b/templates/tests/cypress-run.twig index f0734cb45446176611a8c23545cf5a4db53a25b1..66deb088131ecc9802826f0476ad88a48a1c96be 100755 --- a/templates/tests/cypress-run.twig +++ b/templates/tests/cypress-run.twig @@ -11,6 +11,7 @@ else docker run -u 1000:$(stat -c "%g" /var/run/docker.sock) --rm --name=${NAME} \ --network {{ projectname }}_default \ --env CYPRESS_baseUrl=http://apache \ + --env CYPRESS_mailpitUrl=http://mailpit:8025 \ --env CYPRESS_mailhogUrl=http://mailhog:8025 \ --env PHP_CONTAINER={{ projectname }}-php-1 \ -v /var/run/docker.sock:/var/run/docker.sock \