Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • antiz/infrastructure
  • okabe/infrastructure
  • eworm/infrastructure
  • polyzen/infrastructure
  • pitastrudl/infrastructure
  • sjon/infrastructure
  • torxed/infrastructure
  • jinmiaoluo/infrastructure
  • moson/infrastructure
  • serebit/infrastructure
  • ivabus/infrastructure
  • lb-wilson/infrastructure
  • gromit/infrastructure
  • matt-1-2-3/infrastructure
  • jocke-l/infrastructure
  • alucryd/infrastructure
  • maximbaz/infrastructure
  • ainola/infrastructure
  • segaja/infrastructure
  • nl6720/infrastructure
  • peanutduck/infrastructure
  • aminvakil/infrastructure
  • xenrox/infrastructure
  • felixonmars/infrastructure
  • denisse/infrastructure
  • artafinde/infrastructure
  • jleclanche/infrastructure
  • kpcyrd/infrastructure
  • metalmatze/infrastructure
  • kevr/infrastructure
  • dvzrv/infrastructure
  • dhoppe/infrastructure
  • ekkelett/infrastructure
  • seblu/infrastructure
  • lahwaacz/infrastructure
  • klausenbusk/infrastructure
  • alerque/infrastructure
  • hashworks/infrastructure
  • foxboron/infrastructure
  • shibumi/infrastructure
  • lambdaclan/infrastructure
  • ffy00/infrastructure
  • freswa/infrastructure
  • archlinux/infrastructure
44 results
Show changes
Showing
with 226 additions and 96 deletions
# limit rss requests to 1 r/m
limit_req_zone $binary_remote_addr zone=rsslimit:8m rate=1r/m;
# limit general requests to 20 r/s to block DoS attempts.
limit_req_zone $binary_remote_addr zone=archweblimit:10m rate=20r/s;
# limit mirrors/status/json requests to 1 r/m
limit_req_zone $binary_remote_addr zone=mirrorstatuslimit:8m rate=1r/m;
# limit general requests to 5 r/s to block DoS attempts.
limit_req_zone $binary_remote_addr zone=archweblimit:10m rate=5r/s;
limit_req_status 429;
......@@ -39,6 +42,7 @@ server {
include snippets/letsencrypt.conf;
location /.well-known/ {
include snippets/headers.conf;
add_header Access-Control-Allow-Origin *;
return 301 https://$server_name$request_uri;
}
......@@ -50,8 +54,7 @@ server {
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/listen-443.conf;
server_name {{ domain['domain'] }};
access_log /var/log/nginx/{{ archweb_domain }}/access.log reduced;
......@@ -63,6 +66,7 @@ server {
ssl_trusted_certificate /etc/letsencrypt/live/{{ archweb_domain }}/chain.pem;
location /.well-known/ {
include snippets/headers.conf;
add_header Access-Control-Allow-Origin *;
return 301 https://{{ archweb_domain }}{{ domain['redirect']|default('$request_uri') }};
}
......@@ -96,8 +100,7 @@ server {
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/listen-443.conf;
server_name {{ archweb_domain }};
access_log /var/log/nginx/{{ archweb_domain }}/access.log reduced;
......@@ -115,6 +118,7 @@ server {
location = /.well-known/matrix/client {
default_type application/json;
include snippets/headers.conf;
add_header Access-Control-Allow-Origin *;
return 200 '{"m.homeserver": {"base_url": "https://{{ matrix_domain }}"}, "m.identity_server": {"base_url": "https://matrix.org"} }';
}
......@@ -139,8 +143,8 @@ server {
alias {{ archweb_dir }}/collected_static/favicon.ico;
}
location /pacman/ {
alias {{ archweb_dir }}/archlinux.org/pacman/;
location ~ ^/pacman/(.*)$ {
return 301 https://pacman.archlinux.page/$1;
}
location /netcfg/ {
......@@ -164,6 +168,7 @@ server {
# Cache django's css, js and png files.
location /static/ {
expires 30d;
include snippets/headers.conf;
add_header Pragma public;
add_header Cache-Control "public";
alias {{ archweb_dir }}/collected_static/;
......@@ -184,11 +189,26 @@ server {
uwsgi_cache archwebcache;
uwsgi_cache_revalidate on;
include snippets/headers.conf;
add_header X-Cache-Status $upstream_cache_status;
limit_req zone=rsslimit burst=10 nodelay;
}
# Rate limit mirror status json endpoint
location /mirrors/status/json {
include uwsgi_params;
uwsgi_pass archweb;
uwsgi_cache archwebcache;
uwsgi_cache_revalidate on;
uwsgi_cache_key $cache_key;
include snippets/headers.conf;
add_header X-Cache-Status $upstream_cache_status;
limit_req zone=mirrorstatuslimit burst=10 nodelay;
}
# Temporary redirects
location /people/trusted-user-fellows/ {
return 301 /people/package-maintainer-fellows/;
......@@ -198,6 +218,16 @@ server {
return 301 /people/package-maintainers/;
}
location = /metrics {
if ($http_authorization != "Bearer {{ vault_archweb_metrics_token }}") {
return 403;
}
include uwsgi_params;
uwsgi_pass archweb;
}
location / {
access_log /var/log/nginx/{{ archweb_domain }}/access.log main;
access_log /var/log/nginx/{{ archweb_domain }}/access.log.json json_main;
......@@ -207,11 +237,9 @@ server {
uwsgi_cache archwebcache;
uwsgi_cache_revalidate on;
uwsgi_cache_key $cache_key;
include snippets/headers.conf;
add_header X-Cache-Status $upstream_cache_status;
# re-add HSTS (inheritance from sslsettings.conf broken by above header)
add_header Strict-Transport-Security $hsts_header always;
limit_req zone=archweblimit burst=10 nodelay;
}
}
archwiki_dir: '/srv/http/archwiki'
archwiki_domain: 'wiki.archlinux.org'
archwiki_nginx_conf: '/etc/nginx/nginx.d/archwiki.conf'
archwiki_nginx_challenge_value: '41ce6c6'
archwiki_user: 'archwiki'
archwiki_repository: 'https://gitlab.archlinux.org/archlinux/archwiki.git'
archwiki_version: '1.41.0-3'
archwiki_version: '1.42.3-2'
archwiki_question_answer_file: '/srv/http/archwiki/registration-question-answer.txt'
archwiki_socket: '/run/php-fpm/archwiki.socket'
......
#!/usr/bin/env python
import hashlib
import http.server
import pathlib
import socketserver
import urllib.parse
socketserver.ThreadingTCPServer.allow_reuse_address = True
class Handler(http.server.BaseHTTPRequestHandler):
def do_PURGE(self):
self.send_response(http.HTTPStatus.OK)
self.end_headers()
o = urllib.parse.urlparse(self.path)
for method in ["GET", "HEAD"]:
# Please keep in sync with "fastcgi_cache_key" in nginx.d.conf.j2
if o.query:
cache_key = f"https{method}{o.netloc}{o.path}?{o.query}"
else:
cache_key = f"https{method}{o.netloc}{o.path}"
hash = hashlib.md5(cache_key.encode("utf-8")).hexdigest()
# Please keep in sync with "fastcgi_cache_path" in nginx.d.conf.j2
pathlib.Path(
f"/var/lib/nginx/cache/{hash[-1]}/{hash[-3:-1]}/{hash}"
).unlink(missing_ok=True)
httpd = http.server.ThreadingHTTPServer(("127.0.0.1", 1080), Handler)
httpd.serve_forever()
......@@ -4,7 +4,6 @@
vars:
service_name: "wiki"
service_domain: "{{ archwiki_domain }}"
service_alternate_domains: []
service_nginx_conf: "{{ archwiki_nginx_conf }}"
when: maintenance is defined
......@@ -98,16 +97,18 @@
- name: Start and enable memcached service
systemd: name=memcached@archwiki.service state=started enabled=true daemon_reload=true
- name: Install nginx-cache-purge script
copy: src=nginx-cache-purge dest=/usr/local/bin/nginx-cache-purge owner=root group=root mode=0755
- name: Install systemd services/timers
template: src="{{ item }}.j2" dest="/etc/systemd/system/{{ item }}" owner=root group=root mode=0644
loop:
- archwiki-runjobs.service
- archwiki-runjobs-wait.service
- archwiki-runjobs.timer
- archwiki-prune-cache.service
- archwiki-prune-cache.timer
- archwiki-question-updater.service
- archwiki-question-updater.timer
- nginx-cache-purge.service
- name: Start and enable archwiki timers and services
systemd:
......@@ -117,9 +118,9 @@
daemon_reload: true
with_items:
- archwiki-runjobs.timer
- archwiki-prune-cache.timer
- archwiki-runjobs-wait.service
- archwiki-question-updater.timer
- nginx-cache-purge.service
- name: Create question answer file
systemd:
......
......@@ -76,6 +76,7 @@ $wgRightsIcon = "$wgResourceBasePath/resources/assets/licenses/gnu-fdl.png";
$wgResourceLoaderMaxQueryLength = -1;
$wgGitRepositoryViewers['https://github.com/(.*?)(.git)?'] = 'https://github.com/$1/commit/%H';
$wgGitRepositoryViewers['https://gitlab.archlinux.org/(.*?)(.git)?'] = 'https://gitlab.archlinux.org/$1/-/commit/%H';
$wgJobRunRate = 0;
$wgRunJobsAsync = 1;
......@@ -146,9 +147,9 @@ $wgMemCachedServers = [ "unix://{{ archwiki_memcached_socket }}" ];
## be publicly accessible from the web.
$wgCacheDirectory = "$IP/../cache/data";
$wgEnableSidebarCache = true;
$wgUseFileCache = true;
$wgFileCacheDirectory = "$IP/../cache/html";
$wgUseGzip = true;
$wgUseCdn = true;
$wgCdnServers = [ '127.0.0.1' ];
$wgInternalServer = 'http://wiki.archlinux.org';
# CSS-based preferences supposedly cause about 20 times slower page loads
# https://phabricator.wikimedia.org/rSVN63707
......@@ -194,9 +195,7 @@ $wgSVGNativeRendering = true;
## Skin settings
##
## Default skin: you can change the default skin. Use the internal symbolic
## names, ie 'standard', 'nostalgia', 'cologneblue', 'monobook', 'vector':
wfLoadSkin( 'MonoBook' );
wfLoadSkin( 'Timeless' );
wfLoadSkin( 'Vector' );
$wgVectorResponsive = true;
$wgVectorLanguageInMainPageHeader = true;
......
[Unit]
Description=Archwiki Prune Cache Service
[Service]
Type=oneshot
User={{ archwiki_user }}
WorkingDirectory={{ archwiki_dir }}
ExecStart=/usr/bin/php {{ archwiki_dir }}/public/maintenance/run.php pruneFileCache -q --agedays 1
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
PrivateNetwork=true
ProtectSystem=full
ProtectHome=true
ProtectControlGroups=yes
ProtectKernelModules=yes
ProtectKernelTunables=yes
[Install]
WantedBy=multi-user.target
[Unit]
Description=Archwiki Prune Cache timer
[Timer]
OnCalendar=*-*-* 04:12:00
[Install]
WantedBy=timers.target
[Unit]
Description=nginx cache PURGE service
[Service]
User=http
ProtectSystem=strict
ReadWritePaths=/var/lib/nginx/cache
ExecStart=/usr/local/bin/nginx-cache-purge
[Install]
WantedBy=multi-user.target
fastcgi_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=wiki:100m inactive=60m;
# Please keep "path" and "levels" in sync with nginx-cache-purge
fastcgi_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=wiki:100m inactive=720m;
# Please keep in sync with "cache_key" in nginx-cache-purge
fastcgi_cache_key "$scheme$request_method$host$request_uri";
# rate limit API endpoint
......@@ -13,6 +15,32 @@ upstream archwiki {
server unix://{{ archwiki_socket }};
}
# Challenge the client if the cookie "challenge" is not set to
# the value of "archwiki_nginx_challenge_value".
map $cookie_challenge $challenge_required2 {
default 1;
{{ archwiki_nginx_challenge_value }} 0;
}
# Challenge the client if it is requesting an "action view" and
# $challenge_required2 is true.
map $request_uri $challenge_required {
default 0;
~^/index\.php\? $challenge_required2;
}
geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
auto_reload 60m;
$geoip2_data_country_iso_code country iso_code;
}
# Challenge the client if it is from China and $challenge_required is
# true. This is enough to "throw off" some bots/crawlers from China.
map $geoip2_data_country_iso_code $challenge {
default 0;
CN $challenge_required;
}
server {
listen 80;
listen [::]:80;
......@@ -31,8 +59,7 @@ server {
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/listen-443.conf;
server_name {{ archwiki_domain }};
access_log /var/log/nginx/{{ archwiki_domain }}/access.log reduced;
......@@ -83,10 +110,22 @@ server {
fastcgi_index index.php;
include fastcgi.conf;
{% block wiki_cache %}
fastcgi_cache wiki;
fastcgi_cache_valid 200 10m;
# This improves the cache hit ratio[1] and ensures that there is
# only a single cache file. Without this, nginx will use the
# Vary header as an secondary cache key[2], which breaks the
# cache purge service.
# [1] https://www.fastly.com/blog/best-practices-using-vary-header/
# [2] https://github.com/nginx/nginx/commit/1332e76b20a6a1e871904525d42b17dcaed81eec
fastcgi_ignore_headers Vary;
fastcgi_cache_background_update on;
fastcgi_cache_use_stale updating;
fastcgi_cache_lock on;
include snippets/headers.conf;
add_header X-Cache $upstream_cache_status;
{% endblock %}
}
# mediawiki API endpoint
......@@ -102,6 +141,12 @@ server {
# normal PHP FastCGI handler
location ~ ^/[^/]+\.php$ {
if ($challenge) {
include snippets/headers.conf;
add_header Set-Cookie "challenge={{ archwiki_nginx_challenge_value }}; SameSite=Strict";
return 303 $scheme://$server_name/$request_uri;
}
try_files $uri =404;
access_log /var/log/nginx/{{ archwiki_domain }}/access.log main;
access_log /var/log/nginx/{{ archwiki_domain }}/access.log.json json_main;
......@@ -109,18 +154,25 @@ server {
fastcgi_index index.php;
include fastcgi.conf;
{{ self.wiki_cache() }}
# https://www.mediawiki.org/w/index.php?title=Manual:Varnish_caching&oldid=6230975#Configuring_Varnish
fastcgi_cache_bypass $http_authorization $cookie_archwiki_session $cookie_archwikiToken;
fastcgi_no_cache $http_authorization $cookie_archwiki_session $cookie_archwikiToken;
limit_req zone=archwikilimit burst=10 nodelay;
}
# MediaWiki assets
location ~ ^/(?:images|resources/(?:assets|lib|src)|(?:skins|extensions)/.+\.(?:css|js|gif|jpg|jpeg|png|svg|wasm)$) {
expires 30d;
include snippets/headers.conf;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
location /images/ {
# Add the nosniff header to the images folder (required for mw 1.40+)
include snippets/headers.conf;
add_header X-Content-Type-Options nosniff;
}
......
......@@ -8,8 +8,13 @@ aurweb_conf_dir: '/etc/aurweb'
aurweb_git_dir: "{{ aurweb_dir }}/aur.git"
aurweb_git_hook: '/usr/local/bin/aurweb-git-update'
aurweb_nginx_conf: '/etc/nginx/nginx.d/aurweb.conf'
aurweb_version: 'v6.2.9'
aurweb_pgp_keys: ['B4B759625D4633430B74877059E43E106B247368', 'DB650286BD9EAE39890D3FE6FE3DC1668CB24956', 'D5AD89388A7C6C9C22E790994A4760AB4EE15296']
aurweb_version: 'v6.2.15'
aurweb_pgp_keys: [
'2191B89431BAC0A8B96DE93D244740D17C7FD0EC', # artafinde
'DB650286BD9EAE39890D3FE6FE3DC1668CB24956', # klausenbusk
'D5AD89388A7C6C9C22E790994A4760AB4EE15296', # moson
'E499C79F53C96A54E572FEE1C06086337C50773E' # jelle
]
aurweb_db: 'aur'
aurweb_db_host: 'localhost'
......@@ -41,7 +46,7 @@ aurweb_timers:
- { name: "aurweb-github-mirror.timer", install: "{{ aurweb_environment_type == 'prod' }}", restart: "{{ aurweb_environment_type == 'prod' }}" }
aurweb_services:
- { name: "aurweb-git.service", restart: false }
# - { name: "aurweb-git.service", restart: false }
- { name: "aurweb-aurblup.service", restart: false }
- { name: "aurweb-mkpkglists.service", restart: false }
- { name: "aurweb-pkgmaint.service", restart: false }
......
User-agent: *
# block the search page from indexing, as the search is done via URL parameters
Disallow: /packages?*
# block all interactive things from being indexed, such as posting requests
Disallow: /pkgbase/*
# block all account pages from being indexed, as they require login anyways
Disallow: /account/*
# block the cgit interface except for the useful things
Disallow: /cgit/aur.git/*
Allow: /cgit/aur.git/tree
Allow: /cgit/aur.git/log
Crawl-delay: 2
......@@ -109,6 +109,9 @@
- name: Copy aurweb configuration file
copy: src={{ aurweb_dir }}/conf/config.defaults dest={{ aurweb_conf_dir }}/config.defaults remote_src=yes owner=root group=root mode=0644
- name: Configure robots.txt
copy: src=robots.txt dest="{{ aurweb_dir }}/robots.txt" owner=root group=root mode=0644
- name: Install goaurrpc configuration
template: src=goaurrpc.conf.j2 dest=/etc/goaurrpc.conf owner=root group=root mode=0644
......@@ -168,9 +171,9 @@
template: src=aurweb-git-update.sh.j2 dest=/usr/local/bin/aurweb-git-update.sh owner=root group=root mode=0755
when: release.changed
- name: Install aurweb-git-gc script
template: src=aurweb-git-gc.sh.j2 dest=/usr/local/bin/aurweb-git-gc.sh owner=root group=root mode=0755
when: release.changed
# - name: Install aurweb-git-gc script
# template: src=aurweb-git-gc.sh.j2 dest=/usr/local/bin/aurweb-git-gc.sh owner=root group=root mode=0755
# when: release.changed
- name: Generate HTML documentation
make:
......
......@@ -3,3 +3,5 @@ Match User {{ aurweb_user }}
AuthorizedKeysCommand /usr/local/bin/aurweb-git-auth.sh "%t" "%k"
AuthorizedKeysCommandUser {{ aurweb_user }}
AcceptEnv AUR_OVERWRITE
AllowTcpForwarding No
AllowAgentForwarding No
......@@ -77,3 +77,6 @@ error-token = {{ vault_aurweb_error_token }}
[fastapi]
session_secret = {{ vault_aurweb_secret }}
[tracing]
otlp_endpoint = http://{{ hostvars['monitoring.archlinux.org']['wireguard_address'] }}:4318
......@@ -35,8 +35,7 @@ server {
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/listen-443.conf;
server_name {{ aurweb_domain }};
access_log /var/log/nginx/{{ aurweb_domain }}/access.log main;
......@@ -50,6 +49,10 @@ server {
root {{ aurweb_dir }}/static;
index index.php;
location = /robots.txt {
alias {{ aurweb_dir }}/robots.txt;
}
# redirect /tu to /package-maintainer for external links
location ~ ^/tu($|/.*) {
return 301 https://aur.archlinux.org/package-maintainer$1;
......@@ -105,6 +108,7 @@ server {
location ~ \.gz$ {
root {{ aurweb_dir }}/archives;
default_type text/plain;
include snippets/headers.conf;
add_header Content-Encoding gzip;
expires 5m;
}
......@@ -113,6 +117,7 @@ server {
rewrite ^/static(/.*)$ $1 break;
expires 7d;
include snippets/headers.conf;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
......@@ -123,7 +128,7 @@ server {
proxy_set_header X-Forwarded-For $remote_addr;
}
location /rpc/metrics {
location = /rpc/metrics {
if ($http_authorization != "Bearer {{ vault_goaurrpc_metrics_token }}") {
return 403;
}
......@@ -133,13 +138,23 @@ server {
}
location / {
{% block asgi_proxy %}
# Proxy over to aurweb's ASGI application.
proxy_pass http://{{ aurweb_asgi_bind }};
proxy_set_header Host $http_host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
{% endblock %}
limit_req zone=aurweblimit burst=10 nodelay;
}
location = /metrics {
if ($http_authorization != "Bearer {{ vault_aurweb_metrics_token }}") {
return 403;
}
{{ self.asgi_proxy() }}
}
}
......@@ -7,3 +7,7 @@ backup_hosts:
dir: "~/backup/{{ inventory_hostname }}"
suffix: "-offsite"
borg_cmd: "/usr/bin/borg --remote-path=borg1"
backup_postgres_dir: /root/backup-postgres
backup_mysql_dir: /root/backup-mysql
backup_mysql_defaults: /root/.backup-my.cnf
......@@ -3,5 +3,4 @@ Description=Borg backup (offsite)
[Service]
Type=oneshot
{% include 'borg-backup-cpu-quota.j2' %}
ExecStart=/usr/local/bin/borg-backup-offsite.sh
......@@ -6,5 +6,4 @@ Before=borg-backup-offsite.service
[Service]
Type=oneshot
{% include 'borg-backup-cpu-quota.j2' %}
ExecStart=/usr/local/bin/borg-backup.sh
......@@ -27,40 +27,33 @@
template: src=borg-backup.sh.j2 dest=/usr/local/bin/borg-backup{{ item['suffix'] }}.sh owner=root group=root mode=0755
loop: "{{ backup_hosts }}"
- name: Install postgres backup script
template: src=backup-postgres.sh.j2 dest=/usr/local/bin/backup-postgres.sh owner=root group=root mode=0755
when: postgres_backup_dir is defined
- name: Set up backup helpers for PostgreSQL databases
when: "'postgresql_servers' in group_names"
block:
- name: Install postgres backup script
template: src=backup-postgres.sh.j2 dest=/usr/local/bin/backup-postgres.sh owner=root group=root mode=0755
- name: Check whether postgres user exists
command: getent passwd postgres
register: check_postgres_user
ignore_errors: true
changed_when: check_postgres_user.stdout | length > 0
- name: Make postgres backup directory
file: path={{ postgres_backup_dir }} owner=root group=root mode=0755 state=directory
when: check_postgres_user is succeeded and postgres_backup_dir is defined
- name: Make postgres backup directory
file: path={{ backup_postgres_dir }} owner=root group=root mode=0755 state=directory
- name: Install mysql backup script
template: src=backup-mysql.sh.j2 dest=/usr/local/bin/backup-mysql.sh owner=root group=root mode=0755
when: mysql_backup_dir is defined
- name: Set up backup helpers for MariaDB databases
when: "'mysql_servers' in group_names"
block:
- name: Install mysql backup script
template: src=backup-mysql.sh.j2 dest=/usr/local/bin/backup-mysql.sh owner=root group=root mode=0755
- name: Install mysql backup config
template: src=backup-my.cnf.j2 dest={{ mysql_backup_defaults }} owner=root group=root mode=0644
when: mysql_backup_defaults is defined
- name: Install mysql backup config
template: src=backup-my.cnf.j2 dest={{ backup_mysql_defaults }} owner=root group=root mode=0644
- name: Create mysql backup directory
file: path={{ mysql_backup_dir }} state=directory owner=root group=root mode=0755
when: mysql_backup_dir is defined
- name: Create mysql backup directory
file: path={{ backup_mysql_dir }} state=directory owner=root group=root mode=0755
- name: Install systemd services for backup
template: src={{ item }}.j2 dest=/etc/systemd/system/{{ item }} owner=root group=root mode=0644
- name: Install systemd timer and services for backup
copy: src={{ item }} dest=/etc/systemd/system/{{ item }} owner=root group=root mode=0644
with_items:
- borg-backup.timer
- borg-backup.service
- borg-backup-offsite.service
- name: Install systemd timer for backup
copy: src=borg-backup.timer dest=/etc/systemd/system/borg-backup.timer owner=root group=root mode=0644
- name: Activate systemd timer for backup
systemd: name=borg-backup.timer enabled=yes state=started daemon-reload=yes
#!/bin/bash
mysql_opts="--defaults-file={{mysql_backup_defaults}}"
backupdir="{{mysql_backup_dir}}"
set -e
mysql_opts="--defaults-file={{ backup_mysql_defaults }}"
backupdir="{{ backup_mysql_dir }}"
[[ ! -d "$backupdir" ]] && mkdir -p "$backupdir"
rm -rf "${backupdir:?}"/*
......