add cloud-guest-utils (growpart) #43

Merged
xavi merged 2 commits from davidl-patch-1 into main 2025-01-13 08:30:35 +00:00
33 changed files with 8711 additions and 0 deletions
Showing only changes of commit 0dc26b3a88 - Show all commits

24
playbooks/delete.yml Normal file
View File

@ -0,0 +1,24 @@
- name: List all disks
hosts: all
tasks:
- name: Get info disk information 2
shell: blkid | grep LABEL | awk {'print $2'}
register: blkid
- name: Print valid labels
debug:
var: blkid
- name: Parsear stdout_lines para buscar etiquetas específicas
set_fact:
found_labels: >-
{{
blkid.stdout_lines
| map('regex_search', 'LABEL="(?P<label>[^"]+)"')
| select('defined')
| list
}}
- name: Print valid labels
debug:
var: found_labels

View File

@ -0,0 +1,22 @@
- name: Change machine-id in Debian
hosts: all
gather_facts: no
become: yes
tasks:
- name: Remove files with old machine-id
file:
path: "{{ item }}"
state: absent
loop:
- /etc/machine-id
- /var/lib/dbus/machine-id
- name: Ensure a new UUID is generated for /etc/machine-id
command:
cmd: dbus-uuidgen --ensure=/etc/machine-id
- name: Create symbolic link for /var/lib/dbus/machine-id
file:
src: /etc/machine-id
dest: /var/lib/dbus/machine-id
state: link

7
playbooks/services.yml Normal file
View File

@ -0,0 +1,7 @@
- name: Configure Directory, Time, and Database Services
hosts: all
tasks:
- name: Configure services to install in the server
import_role:
name: services

View File

@ -27,7 +27,11 @@ base_packages:
- ncdu
- debconf-utils
- net-tools
<<<<<<< HEAD
- cloud-guest-utils
=======
- rsync
>>>>>>> main
locales_present:
- en_US.UTF-8
- es_ES.UTF-8

View File

@ -0,0 +1,3 @@
[Definition]
actionstart =
actionstop =

View File

@ -13,6 +13,14 @@
group: root
mode: u=rw,g=r,o=r
notify: restart sshd
- name: Adjust action configuration to reduce noise
copy:
src: sendmail-common.local
dest: /etc/fail2ban/action.d/sendmail-common.local
owner: root
group: root
mode: u=rw,g=r,o=r
notify: restart sshd
- name: Configure fail2ban service
template:
src: jail.local

View File

@ -0,0 +1,45 @@
samba_client_services:
- smbd
- nmbd
- winbind
dcsamba_base_packages:
- samba
- krb5-user
- winbind
- acl
mariadb_base_packages:
- mariadb-server
- mariadb-backup
- pmm2-client
mariadb_requeriments:
- curl
- apt-transport-https
certificates:
- { content: '{{ ca_mysql }}', dest: '/etc/mysql/ca.pem', mode: 'u=rw,g=r,o=r' }
- { content: '{{ cert_mysql }}', dest: '/etc/mysql/cert.pem', mode: 'u=rw,g=r,o=r' }
required_directories:
- { path: /mnt/local-backup, owner: root, group: root, mode: 'u=rwx,g=rx,o=rx' }
- { path: /mnt/mysqlbin, owner: root, group: root, mode: 'u=rwx,g=rx,o=rx' }
- { path: /mnt/mysqltmp, owner: root, group: root, mode: 'u=rwx,g=rwx,o=rwxt' }
- { path: /mnt/mysqlbin/binlog, owner: mysql, group: mysql, mode: 'u=rwx,g=,o=' }
- { path: /root/scripts, owner: root, group: root, mode: 'u=rwx,g=rx,o=rx' }
- { path: /root/mariabackup, owner: root, group: root, mode: 'u=rwx,g=rx,o=rx' }
required_files_and_mariabackup_files_and_root_scripts:
- { src: "mariadb_override.conf", dest: "/etc/systemd/system/mariadb.service.d/override.conf", mode: "u=rw,g=r,o=r" }
- { src: "mysql-flush.sh", dest: "/etc/qemu/fsfreeze-hook.d/mysql-flush.sh", mode: "u=rwx,g=rx,o=rx" }
- { src: "files/mariabackup/bacula-before.sh", dest: "/root/mariabackup/bacula-before.sh", mode: "u=rwx,g=rx,o=rx" }
- { src: "files/mariabackup/config.sh", dest: "/root/mariabackup/config.sh", mode: "u=rwx,g=rx,o=x" }
- { src: "files/mariabackup/inc-backup.sh", dest: "/root/mariabackup/inc-backup.sh", mode: "u=rwx,g=rx,o=rx" }
- { src: "files/mariabackup/my.cnf", dest: "/root/mariabackup/my.cnf", mode: "u=rw,g=,o=" }
- { src: "files/mariabackup/restore-backup.sh", dest: "/root/mariabackup/restore-backup.sh", mode: "u=rwx,g=rx,o=rx" }
- { src: "files/scripts/check-memory.sh", dest: "/root/scripts/check-memory.sh", mode: "u=rwx,g=rx,o=rx" }
- { src: "files/scripts/export-privs.sh", dest: "/root/scripts/export-privs.sh", mode: "u=rwx,g=rx,o=rx" }
- { src: "files/scripts/mysqltuner.pl", dest: "/root/scripts/mysqltuner.pl", mode: "u=rwx,g=rx,o=rx" }
- { src: "files/scripts/promote-master.sh", dest: "/root/scripts/promote-master.sh", mode: "u=rwx,g=rx,o=rx" }
- { src: "files/scripts/promote-slave.sh", dest: "/root/scripts/promote-slave.sh", mode: "u=rwx,g=rx,o=rx" }
- { src: "files/scripts/README.md", dest: "/root/scripts/README.md", mode: "u=rw,g=r,o=r" }
- { src: "files/scripts/scheduler-log.sh", dest: "/root/scripts/scheduler-log.sh", mode: "u=rwx,g=rx,o=rx" }
- { src: "files/scripts/sync-conf.sh", dest: "/root/scripts/sync-conf.sh", mode: "u=rwx,g=rx,o=rx" }
downloads:
- { url: "https://r.mariadb.com/downloads/mariadb_repo_setup", dest: "/tmp/mariadb_repo_setup", mode: "u=rwx,g=rx,o=rx" }
- { url: "https://repo.percona.com/apt/percona-release_latest.generic_all.deb", dest: "/tmp/percona-release_latest.generic_all.deb", mode: "u=rw,g=r,o=r" }

View File

@ -0,0 +1,30 @@
#!/bin/bash
# https://mariadb.com/kb/en/mariabackup/
set -e
myDir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
. "$myDir/config.sh"
todayDir="$(date +%Y-%m-%d)"
backupName="${todayDir}_$(date +"%H-%M")_full"
backupFile="$backupDir/$backupName.gz"
if [ -d "$backupDir" ]; then
rm -rf "$backupDir/"*
fi
ulimit -n 8192
mariabackup \
--defaults-extra-file="$myDir/my.cnf" \
--backup \
--extra-lsndir="$backupDir/$backupName" \
--history="$todayDir" \
2>> "$logFile" \
| gzip \
> "$backupFile"
if [ $? != "0" ]; then
echo "An error ocurred during backup, please take a look at log file: $logFile"
exit 1
fi

View File

@ -0,0 +1,20 @@
#!/bin/bash
# Destination file for backup logs
logFile=/var/log/vn-mariabackup.log
# Temporary local directory to save backups
backupDir=/mnt/local-backup
# Directory for backup history
historyDir=/mnt/backup4mariadb
# Number of days for backup rotation
cleanDays=90
# Directory for temporal restore data
restoreDir=/mnt/mysqldata/mysql-restore
# Directory of MySQL data
dataDir=/mnt/mysqldata/mysql

View File

@ -0,0 +1,38 @@
#!/bin/bash
# https://mariadb.com/kb/en/incremental-backup-and-restore-with-mariabackup/
set -e
myDir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
. "$myDir/config.sh"
todayDir="$(date +%Y-%m-%d)"
todayPath="$historyDir/$todayDir"
pattern="$todayPath/${todayDir}_??-??_full.xb.gz.enc"
files=($pattern)
backupFile="${files[0]}"
backupBase=$(basename -- "$backupFile")
backupName="${backupBase%%.*}"
incrementalName="${todayDir}_$(date +"%H-%M")_incremental"
incrementalFile="$backupDir/${incrementalName}.xb.gz.enc"
ulimit -n 24098
mariabackup \
--defaults-extra-file="$myDir/my.cnf" \
--backup \
--incremental-basedir="$backupDir/$backupName" \
--extra-lsndir="$backupDir/$incrementalName" \
--incremental-history-name="$todayDir" \
2>> "$logFile" \
| gzip \
| openssl enc -aes-256-cbc -pbkdf2 -kfile "$myDir/xbcrypt.key" \
> "$incrementalFile"
if [ $? != "0" ]; then
echo "An error ocurred during backup, please take a look at log file: $logFile"
exit 1
fi
cp "$incrementalFile" "$todayPath"
cp -r "$backupDir/$incrementalName" "$todayPath"

View File

@ -0,0 +1,7 @@
[mariabackup]
host = localhost
user = {{ user_mariabackup }}
password = {{ password_user_mariabackup }}
use-memory = 1G
parallel = 2
stream = mbstream

View File

@ -0,0 +1,53 @@
#!/bin/bash
# https://mariadb.com/kb/en/using-encryption-and-compression-tools-with-mariabackup/
set -e
myDir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
. "$myDir/config.sh"
backupFile=$1
if [ -z "$backupFile" ]; then
echo "Backup file not defined."
exit 1
fi
if [ ! -f "$backupFile" ]; then
echo "Backup file does not exist: $backupFile"
exit 2
fi
echo "Restoring MySQL data from backup."
rm -rf "$restoreDir"
mkdir -p "$restoreDir"
echo "Decompresing backup."
gzip --decompress --stdout "$backupFile" \
| mbstream -x --directory="$restoreDir"
echo "Preparing backup."
mariabackup \
--defaults-extra-file="$myDir/my.cnf" \
--prepare \
--target-dir="$restoreDir"
echo "Stopping service."
service mariadb stop
if pgrep mariadbd; then pkill -9 mariadbd; fi
echo "Restoring data."
rm -rf "$dataDir"
mariabackup \
--defaults-extra-file="$myDir/my.cnf" \
--move-back \
--target-dir="$restoreDir" \
2>> "$logFile"
chown -R mysql:mysql "$dataDir"
rm "$dataDir/mysql/slow_log."*
rm "$dataDir/mysql/general_log."*
echo "Removing restore data."
rm -r "$restoreDir"

View File

@ -0,0 +1,3 @@
[Service]
LimitNOFILE=600000
LimitMEMLOCK=2M

View File

@ -0,0 +1,57 @@
#!/bin/sh
# https://github.com/qemu/qemu/blob/master/scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample
# Flush MySQL tables to the disk before the filesystem is frozen.
# At the same time, this keeps a read lock in order to avoid write accesses
# from the other clients until the filesystem is thawed.
MYSQL="/usr/bin/mysql"
MYSQL_OPTS="-uroot" #"-prootpassword"
FIFO=/var/run/mysql-flush.fifo
# Check mysql is installed and the server running
[ -x "$MYSQL" ] && "$MYSQL" $MYSQL_OPTS < /dev/null || exit 0
flush_and_wait() {
printf "FLUSH TABLES WITH READ LOCK \\G\n"
trap 'printf "$(date): $0 is killed\n">&2' HUP INT QUIT ALRM TERM
read < $FIFO
printf "UNLOCK TABLES \\G\n"
rm -f $FIFO
}
case "$1" in
freeze)
mkfifo $FIFO || exit 1
flush_and_wait | "$MYSQL" $MYSQL_OPTS &
# wait until every block is flushed
while [ "$(echo 'SHOW STATUS LIKE "Key_blocks_not_flushed"' |\
"$MYSQL" $MYSQL_OPTS | tail -1 | cut -f 2)" -gt 0 ]; do
sleep 1
done
# for InnoDB, wait until every log is flushed
INNODB_STATUS=$(mktemp /tmp/mysql-flush.XXXXXX)
[ $? -ne 0 ] && exit 2
trap "rm -f $INNODB_STATUS; exit 1" HUP INT QUIT ALRM TERM
while :; do
printf "SHOW ENGINE INNODB STATUS \\G" |\
"$MYSQL" $MYSQL_OPTS > $INNODB_STATUS
LOG_CURRENT=$(grep 'Log sequence number' $INNODB_STATUS |\
tr -s ' ' | cut -d' ' -f4)
LOG_FLUSHED=$(grep 'Log flushed up to' $INNODB_STATUS |\
tr -s ' ' | cut -d' ' -f5)
[ "$LOG_CURRENT" = "$LOG_FLUSHED" ] && break
sleep 1
done
rm -f $INNODB_STATUS
;;
thaw)
[ ! -p $FIFO ] && exit 1
echo > $FIFO
;;
*)
exit 1
;;
esac

View File

@ -0,0 +1,19 @@
# Scripts to maintain MariaDB
## scheduler-log.sh
The following table should be created into MySQL/MariaDB database.
```
CREATE TABLE `eventLog` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date` datetime NOT NULL,
`event` varchar(512) NOT NULL,
`error` varchar(1024) NOT NULL,
PRIMARY KEY (`id`),
KEY `date` (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Event scheduler error log'
```
Then adjust the *$logTable* variable to the correct schema.

View File

@ -0,0 +1,9 @@
#!/bin/bash
minFree=1
memFree=$(free --gibi | awk '$1 == "Mem:" { print $7 }')
if [ "$memFree" -le "$minFree" ]; then
echo "Free memory is ${memFree}Gi, restarting mariadb service to prevent OOM killer..."
systemctl restart mariadb
fi

View File

@ -0,0 +1,25 @@
#!/bin/bash
OUTFILE=privs.sql
SCHEMA=mysql
TABLES=(
global_priv
db
tables_priv
columns_priv
procs_priv
proxies_priv
roles_mapping
)
echo "USE \`$SCHEMA\`;" > "$OUTFILE"
for TABLE in "${TABLES[@]}"
do
echo "TRUNCATE TABLE \`$SCHEMA\`.\`$TABLE\`;" >> "$OUTFILE"
done
echo "" >> "$OUTFILE"
mysqldump --no-create-info --skip-triggers "$SCHEMA" ${TABLES[@]} >> "$OUTFILE"
echo "FLUSH PRIVILEGES;" >> "$OUTFILE"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
#!/bin/bash
mysql -e "SET GLOBAL event_scheduler = OFF"
echo "SELECT db, name FROM mysql.event WHERE status = 'SLAVESIDE_DISABLED'" | mysql --raw --silent | \
awk '{
gsub("`", "``", $1);
gsub("`", "``", $2);
print "`"$1"`.`"$2"`";
}' | \
while read event; do
mysql -e "ALTER EVENT $event ENABLE"
done
mysql -e "SET GLOBAL event_scheduler = ON"

View File

@ -0,0 +1,16 @@
#!/bin/bash
mysql -e "SET GLOBAL event_scheduler = OFF"
echo "SELECT db, name FROM mysql.event WHERE status = 'ENABLED'" | mysql --raw --silent | \
awk '{
gsub("`", "``", $1);
gsub("`", "``", $2);
print "`"$1"`.`"$2"`";
}' | \
while read event; do
mysql -e "ALTER EVENT $event DISABLE ON SLAVE"
done
mysql -e "SET GLOBAL event_scheduler = ON"

View File

@ -0,0 +1,49 @@
#!/bin/bash
set -e
logFile="/var/log/mysql/error.log"
dateFile="/tmp/mysql_scheduler_log-lastdate"
logTable="util.eventLog"
purgeDays=30
quote() {
local str=${1//\'/\'\'/}
local str=${str//\\/\\\\}
echo "'$str'"
}
mysql -e "SELECT TRUE" > /dev/null 2>&1
if [ "$?" -ne "0" ]; then
exit
fi
if [ -f "$dateFile" ]; then
fromDate=$(cat "$dateFile")
else
fromDate=0
fi
lastDate=$(tail -n1 "$logFile" | awk '{print $1" "$2}')
toDate=$(date +%s -d "$lastDate")
awk -v fromDate="$fromDate" -v toDate="$toDate" '{
split($1, date, "-");
split($2, time, ":");
timestamp = mktime(date[1]" "date[2]" "date[3]" "time[1]" "time[2]" "time[3])
if (timestamp >= fromDate && timestamp < toDate && $4" "$5" "$6 == "[ERROR] Event Scheduler:") {
printf $1" "$2" "$7;
for (i=8; i<=NF; i++) printf FS $i ;
print "";
}
}' "$logFile" | \
\
while read line; do
date="$(echo "$line" | cut -d' ' -f1,2)"
event="$(echo "$line" | cut -d' ' -f3)"
error="$(echo "$line" | cut -d' ' -f4-)"
echo "INSERT INTO $logTable (date, event, error)" \
"VALUES ($(quote "$date"), $(quote "$event"), $(quote "$error"))" | mysql
done
echo -n "$toDate" > "$dateFile"
echo "DELETE FROM $logTable WHERE date < TIMESTAMPADD(DAY, -$purgeDays, NOW())" | mysql

View File

@ -0,0 +1,21 @@
#!/bin/bash
partner=root@db2.static.verdnatura.es
confDir=/etc/mysql/mariadb.conf.d
files=(
z90-vn.cnf
z95-production.cnf
)
#echo "Reloading service."
#service mariadb reload
if [ $? -eq "0" ]; then
echo "Synchronizing partner configuration."
for file in "${files[@]}"; do
scp "$confDir/$file" $partner:$confDir
done
#echo "Reloading partner service."
#ssh $partner service mariadb reload
fi

View File

@ -0,0 +1,119 @@
[mysqld]
# Docs: https://mariadb.com/kb/en/server-system-variables
lc_messages = es_ES
lc_time_names = es_ES
character-set-server = utf8
collation-server = utf8_unicode_ci
explicit_defaults_for_timestamp = ON
datadir = /var/lib/mysql
tmpdir = /mnt/mysqltmp
log_bin_trust_function_creators = 1
sql_mode = NO_ENGINE_SUBSTITUTION
bind-address = 0.0.0.0
max_password_errors = 50
#++++++++++++++++++++++++++++++++++++++++ Threads
thread_stack = 512K
join_buffer_size = 2M
sort_buffer_size = 4M
net_buffer_length = 256K
max_allowed_packet = 16M
read_buffer_size = 1M
read_rnd_buffer_size = 512K
#++++++++++++++++++++++++++++++++++++++++ Performance
thread_cache_size = 450
interactive_timeout = 1800
wait_timeout = 1800
open_files_limit = 20000
low_priority_updates = 1
table_open_cache = 40000
table_definition_cache = 10000
table_open_cache_instances = 1
key_buffer_size = 256K
max_heap_table_size = 128M
tmp_table_size = 128M
concurrent_insert = ALWAYS
group_concat_max_len = 10000
max_connect_errors = 50
#++++++++++++++++++++++++++++++++++++++++ Binary log
log-bin = /mnt/mysqlbin/binlog/bin.log
max_binlog_size = 1GB
binlog_cache_size = 16M
binlog_stmt_cache_size = 16M
binlog_row_image = noblob
binlog_format = row
relay_log = /mnt/mysqlbin/binlog/relay.log
binlog-ignore-db = tmp
binlog-ignore-db = PERCONA_SCHEMA
#++++++++++++++++++++++++++++++++++++++++ Replication
event-scheduler = ON
slave_exec_mode = STRICT
replicate-ignore-db = tmp
replicate-ignore-table = util.eventLog
replicate-ignore-table = cache.cache_calc
replicate-ignore-table = cache.available
replicate-ignore-table = cache.availableNoRaids
replicate-ignore-table = cache.cache_valid
replicate-ignore-table = cache.stock
replicate-ignore-table = cache.visible
#++++++++++++++++++++++++++++++++++++++++ InnoDB
transaction-isolation = READ-COMMITTED
idle_transaction_timeout = 60
innodb_io_capacity = 100
innodb_io_capacity_max = 100
innodb_monitor_enable = all
innodb_read_io_threads = 16
innodb_write_io_threads = 16
innodb_checksum_algorithm = crc32
innodb_adaptive_hash_index = 0
innodb_flush_method = O_DIRECT
innodb_log_buffer_size = 32M
innodb_log_file_size = 8G
innodb_purge_threads = 4
innodb_buffer_pool_dump_at_shutdown = ON
innodb_buffer_pool_load_at_startup = ON
#++++++++++++++++++++++++++++++++++++++++ Logging
log_error = /var/log/mysql/error.log
log_warnings = 1
log_output = TABLE
general_log = OFF
slow_query_log = ON
long_query_time = 2
min_examined_row_limit = 0
log_slow_admin_statements = ON
log_queries_not_using_indexes = OFF
max_error_count = 100
#++++++++++++++++++++++++++++++++++++++++ SSL
ssl-ca = /etc/mysql/ca.pem
ssl-cert = /etc/mysql/cert.pem
ssl-key = /etc/mysql/key.pem
#++++++++++++++++++++++++++++++++++++++++ Query cache
query_cache_limit = 0
query_cache_type = OFF
query_cache_size = 0
#++++++++++++++++++++++++++++++++++++++++ Performance Schema
performance_schema = ON
performance_schema_digests_size = 20000
performance-schema-consumer-events-statements-history = ON
performance_schema_consumer_events_statements_history_long = ON
userstat = ON

View File

@ -0,0 +1,6 @@
[mysqld]
port = 3306
max_connections = 1000
expire_logs_days = 7
innodb_buffer_pool_size = 64G

View File

@ -0,0 +1,7 @@
[mysqld]
server-id = 1
#bind-address = 127.0.0.1
#event-scheduler = OFF
#skip-log-bin
#skip-slave-start

View File

@ -0,0 +1,13 @@
- name: restart-chrony
systemd:
name: chrony
state: restarted
- name: reload systemd
command:
cmd: systemctl daemon-reload
- name: restart-mariadb
systemd:
name: mariadb
state: restarted

View File

@ -0,0 +1,49 @@
- name: Install adSamba packages
package:
name: "{{ dcsamba_base_packages }}"
state: present
install_recommends: no
- name: Add adsamba host to hosts file
blockinfile:
path: /etc/hosts
marker: "# {mark} ANSIBLE-MANAGED SAMBA DC ENTRY"
block: |
{{ dc1 }} dc1-test.samba-test.{{ resolv_domain }}
- name: Disable Samba client services and mask them
systemd:
name: "{{ item }}"
state: stopped
enabled: no
masked: yes
loop: "{{ samba_client_services }}"
- name: Check if server is already joined to domain
command:
cmd: samba-tool domain info localhost
register: domain_info
failed_when: domain_info.rc != 0 and 'Cannot contact' not in domain_info.stderr
changed_when: false
- name: Join domain as DC if not already joined
command:
cmd: samba-tool domain join samba."{{ resolv_domain }}" DC -U"SAMBA\\administrator" --option='idmap_ldb:use rfc2307 = yes'
when: "'Cannot contact' in domain_info.stderr"
register: domain_join
changed_when: "'Joined domain' in domain_join.stdout"
- name: Copy Kerberos configuration
copy:
src: krb5.conf
dest: /etc/krb5.conf
remote_src: true
owner: root
group: root
mode: '0644'
- name: Enable and start Samba AD DC service
systemd:
name: samba-ad-dc
state: started
enabled: yes

View File

@ -0,0 +1,6 @@
- import_tasks: timeserver.yml
tags: timeserver
- import_tasks: mariadb.yml
tags: mariadb
- import_tasks: adsamba.yml
tags: adsamba

View File

@ -0,0 +1,109 @@
# Review /root/scripts/check-memory.sh --> It's not optimal to do what this program does
# Also review the cron task /root/scripts/scheduler-log.sh
- name: Ensure Install requirements for MariaDB repository setup script
apt:
name: "{{ mariadb_requeriments }}"
state: present
install_recommends: no
- name: Download required setup files
get_url:
url: "{{ item.url }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
loop: "{{ downloads }}"
- name: Run MariaDB repository setup script
command:
cmd: "/bin/bash /tmp/mariadb_repo_setup --mariadb-server-version=10.11.10"
creates: "/etc/apt/sources.list.d/mariadb.list"
- name: Install Percona repository package
apt:
deb: "/tmp/percona-release_latest.generic_all.deb"
state: present
install_recommends: no
- name: Install MariaDB packages
apt:
name: "{{ mariadb_base_packages }}"
state: present
install_recommends: no
- name: Ensure required directories exist
file:
path: "{{ item.path }}"
state: directory
owner: "{{ item.owner }}"
group: "{{ item.group }}"
mode: "{{ item.mode }}"
loop: "{{ required_directories }}"
- name: Ensure required custom and Mariabackup files are copied to their destinations and root scripts
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: root
group: root
mode: "{{ item.mode }}"
loop: "{{ required_files_and_mariabackup_files_and_root_scripts }}"
notify: reload systemd
- name: Add tmpfs in /etc/fstab
blockinfile:
path: /etc/fstab
marker: "# {mark} ANSIBLE-MANAGED TMPFS ENTRY"
block: |
tmpfs /mnt/mysqltmp tmpfs rw,size=6144M 0 0
register: fstab
- name: Mount all filesystems from /etc/fstab
command: mount -a
when: fstab.changed
- name: Set MariaDB Cron to /etc/cron.d
template:
src: templates/cron_mariadb
dest: /etc/cron.d/vn
owner: root
group: root
mode: u=rw,g=r,o=r
- name: Insert MySQL certificates
copy:
content: "{{ item.content }}"
dest: "{{ item.dest }}"
owner: mysql
group: mysql
mode: "{{ item.mode }}"
loop: "{{ certificates }}"
notify: restart-mariadb
- name: Configure MySQL master cert
copy:
content: "{{ lookup(passbolt, 'private_mysql', folder_parent_id=passbolt_folder).description }}"
dest: /etc/mysql/key.pem
owner: mysql
group: mysql
mode: u=rw,g=,o=
- name: Set MariaDB custom configuration
copy:
src: "{{ item }}"
dest: /etc/mysql/mariadb.conf.d/
owner: root
group: root
mode: u=rw,g=r,o=r
with_fileglob:
- "files/z9*.cnf"
notify: restart-mariadb
- name: Reminder to check mount points
debug:
msg: |
Remember to check the following mount points:
- /var/lib/mysql
- /mnt/mysqlbin
- /mnt/local-backup
Make sure they are correctly configured and accessible.

View File

@ -0,0 +1,15 @@
- name: Install CHRONY packages
apt:
name: chrony
state: present
install_recommends: no
- name: Set CHRONY generic configuration
template:
src: timeserver_custom.conf
dest: /etc/chrony/conf.d/custom.conf
owner: root
group: root
mode: u=rw,g=r,o=r
notify: restart-chrony

View File

@ -0,0 +1,4 @@
MAILTO="{{ sysadmin_mail }}"
*/15 * * * * root /root/scripts/check-memory.sh
*/30 * * * * root /root/scripts/scheduler-log.sh

View File

@ -0,0 +1,17 @@
# vendor zone
{{ timeserver_vendor_zone }}
# Logging
log tracking statistics
# will serve as local NTP server
local stratum 10
# restrict clients from your subnets
allow {{ timeserver_restrict_clients_zone }}
# in case this server lost INTERNET connection
local stratum 10
# in case you wanna to broadcat time in your subnet
{{ timeserver_broadcat_subnet }}

148
scripts/backup_pve.sh Normal file
View File

@ -0,0 +1,148 @@
#!/bin/bash
# Script to automate Proxmox PVE node backups to a PBS machine.
#
# Author: Xavi Lleó
# Copyright (c) 2025 Verdnatura S.L. All rights reserved.
# Version: 1.0.3
# ¿Juan Wants add GPL License?
#
# A configuration file is required in the user's home directory who runs this command.
# The file should be sourced using CONFIG_FILE before execution.
#
# Example of a configuration file:
#
# Default values
# USER_API="root@pam!api"
# USER="root@pam"
# IP_PBS="192.168.1.250"
# POOL="backup-pool"
# BACKUP_ITEMS="etc-pve.pxar:/etc/pve,interfaces.pxar:/etc/network"
# LOG_FILE="/var/log/proxmox-backup-node-pve.log"
# KEY_FILE="mykeyfile.key" #In case you want encrypted backups
# PBS_PASSWORD='mypass or api token'
# PBS_FINGERPRINT='b0:69:24:75:f0:92:a2:72:37:7c:c1:cb:0d:ba:8e:14:EE:XX:AA:MM:PP:LL:EE:e4:2b:07:02:18:86:9a:df:45'
#
# If you prefer to use switches in a one-liner, refer to the help section (--help) for available options.
# Remember to add the port after the IP address when using an API user for authentication.
# Example: IP_PBS="192.168.1.250:8007"
CONFIG_FILE="$HOME/.backup_config.conf"
# https://pbs.proxmox.com/docs/backup-client.html#environment-variables
export PBS_PASSWORD
export PBS_FINGERPRINT
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
else
echo "Error: Configuration file not found at $CONFIG_FILE"
exit 1
fi
show_help() {
echo "Usage: $0 [options]"
echo
echo "Options:"
echo " --standard Perform a standard backup."
echo " --encrypt Perform an encrypted backup (requires a key file)."
echo " --ip Repository IP address (overrides configuration)."
echo " --pool Name of the backup pool (overrides configuration)."
echo " --items List of backup items in 'name1:source1,name2:source2' format."
echo " --user-api Specify user API credentials for backup."
echo " --user Specify user credentials for backup."
echo " --help Show this help."
exit 0
}
exit_from_repo() {
proxmox-backup-client logout --repository "$REPOSITORY" 2>>"$LOG_FILE" && echo "$(date '+%Y-%m-%d %H:%M:%S') - Logged out from repository $REPOSITORY" | tee -a "$LOG_FILE"
}
# Check if PBS_PASSWORD and PBS_FINGERPRINT are set
if [ -z "$PBS_PASSWORD" ] || [ -z "$PBS_FINGERPRINT" ]; then
echo "Error: PBS_PASSWORD or PBS_FINGERPRINT is not set."
exit 1
fi
while [[ $# -gt 0 ]]; do
case "$1" in
--standard)
MODE="standard"
;;
--encrypt)
MODE="encrypt"
;;
--ip)
IP_PBS="$2"
shift
;;
--pool)
POOL="$2"
shift
;;
--items)
BACKUP_ITEMS="$2"
shift
;;
--user-api)
USER_API="$2"
shift
;;
--user)
USER="$2"
shift
;;
--help)
show_help
;;
*)
echo "Error: Unrecognized option '$1'"
show_help
;;
esac
shift
done
if [ -z "$MODE" ]; then
echo "You must specify --standard or --encrypt."
show_help
fi
if [ -n "$USER_API" ]; then
REPOSITORY="$USER_API@$IP_PBS:$POOL"
else
REPOSITORY="$USER@$IP_PBS:$POOL"
fi
echo "$(date '+%Y-%m-%d %H:%M:%S') - Starting backup to repository $REPOSITORY" | tee -a "$LOG_FILE"
for item in $(echo "$BACKUP_ITEMS" | tr ',' '\n'); do
BACKUP_NAME=$(echo "$item" | cut -d':' -f1)
TARGET_DIR=$(echo "$item" | cut -d':' -f2)
if [ "$MODE" == "encrypt" ]; then
if [ ! -f "$KEY_FILE" ]; then
echo "The key file $KEY_FILE does not exist." | tee -a "$LOG_FILE"
exit 1
fi
proxmox-backup-client backup "$BACKUP_NAME:$TARGET_DIR" --repository "$REPOSITORY" --crypt-mode encrypt --keyfile "$KEY_FILE" --backup-type 'host' 2>>"$LOG_FILE"
else
proxmox-backup-client backup "$BACKUP_NAME:$TARGET_DIR" --repository "$REPOSITORY" --backup-type 'host' 2>>"$LOG_FILE"
fi
if [ $? -ne 0 ]; then
echo "Backup failed for $BACKUP_NAME" | tee -a "$LOG_FILE"
exit 1
fi
sleep 5
done
if [ $? -eq 0 ]; then
exit_from_repo
echo -e "$(date '+%Y-%m-%d %H:%M:%S') - Backup completed successfully. You can check the log at $LOG_FILE\n" | tee -a "$LOG_FILE"
else
exit_from_repo
echo -e "$(date '+%Y-%m-%d %H:%M:%S') - Error during backup. You can check the log at $LOG_FILE\n" | tee -a "$LOG_FILE"
exit 1
fi