bundles/zfs: import bundle from work repository

This commit is contained in:
Franzi 2020-08-29 21:10:59 +02:00
parent b690ae25b0
commit 4934eb46fb
Signed by: kunsi
GPG key ID: 12E3D2136B818350
11 changed files with 841 additions and 0 deletions

View file

@ -0,0 +1,33 @@
#!/bin/sh
monitoring=/var/tmp/zfs-auto-snapshot.status
crit_days=1
uptime=$(cut -d. -f1 /proc/uptime)
if [ "$uptime" -lt 3600 ]
then
echo 'OK - The system has just booted'
exit 0
fi
now=$(date +%s)
timestamp=$(cat "$monitoring")
if [ -z "$timestamp" ]
then
echo 'UNKNOWN - No status info found'
exit 3
fi
if [ "$timestamp" = 0 ]
then
echo 'OK - Snapshots disabled'
exit 0
elif [ $(( now - timestamp )) -gt $(( 60 * 60 * 24 * crit_days )) ]
then
echo "CRITICAL - Status file indicates age greater than $crit_days day(s)"
exit 2
else
echo 'OK'
exit 0
fi

View file

@ -0,0 +1,63 @@
#!/usr/bin/env python3
from datetime import datetime, timedelta
from re import match
from subprocess import check_output
from sys import exit
output = check_output(['zfs', 'get', 'creation', '-Hpr', '-t', 'snapshot'])
now = int(datetime.now().timestamp())
warn_age = now - (60 * 60 * 24 * 60)
crit_age = now - (60 * 60 * 24 * 90)
warn_snapshots = set()
crit_snapshots = set()
return_code = 0
for line in output.decode('utf-8').split("\n"):
if line.strip() == '':
continue
items = line.split("\t")
# If the snapshot name contains 'zfs-auto-snap', it's probably
# really an automated snapshot and will be cleaned up eventually.
# This check only cares about manually created snapshots, though.
if 'zfs-auto-snap' in items[0]:
continue
# These are docker-internal snapshots and should not be touched by
# us.
if match(r'^tank/docker/[a-z0-9]+(-init)?@[0-9]+', items[0]):
continue
# line should be '<snapshot> creation <timestamp> -', separated by
# tabstops.
if len(items) < 3:
print('UNKNOWN - error while parsing ' + line)
exit(3)
creation_date = int(items[2])
if creation_date < crit_age:
crit_snapshots.add(items[0])
elif creation_date < warn_age:
warn_snapshots.add(items[0])
# We have to do additional loops in here to have CRITICAL items on top.
for snap in sorted(crit_snapshots):
print('CRITICAL - {} is older than 90 days'.format(snap))
for snap in sorted(warn_snapshots):
print('WARN - {} is older than 60 days'.format(snap))
if len(crit_snapshots) > 0:
return_code = 2
elif len(warn_snapshots) > 0:
return_code = 1
else:
print('OK - no snapshots are older than 60 days')
exit(return_code)

View file

@ -0,0 +1,26 @@
#!/bin/bash
# Written by jpaul, 2017-03
# Extended by El Pinguino, 2017-07
<%
datasetlist = sorted(node.metadata.get('zfs', {}).get('datasets', {}).items())
volumes = []
for dataset, options in datasetlist:
if options.get('mountpoint', 'none') != 'none':
volumes.append(dataset)
%>\
exitcode=0
% for volume in volumes:
if [[ "$(zfs get -Hp -o value mounted '${volume}')" != "yes" ]]
then
echo 'CRITICAL - ${volume} not mounted'
exitcode=2
fi
% endfor
if (( exitcode == 0 ))
then
echo OK
fi
exit $exitcode

View file

@ -0,0 +1,15 @@
#!/bin/bash
if [ $# -eq 0 ] ; then
echo "Please provide pool name as first argument, e.g. 'tank'."
exit 3
fi
if [ "$(zpool status "$1" | grep '^ state:')" = ' state: ONLINE' ]
then
echo "OK - Pool '$1' is online"
exit 0
else
echo "CRITICAL - Pool '$1' is FAULTY or NOT ONLINE"
exit 2
fi

View file

@ -0,0 +1,40 @@
#!/usr/bin/env python3
from subprocess import check_output
from sys import argv, exit
import re
def to_bytes(size):
suffixes = ['', 'K', 'M', 'G', 'T', 'P']
number, suffix = re.match(r'([0-9\.]+)([A-Z]?)', size).groups()
assert suffix in suffixes, 'Unexpected suffix "{}" in size "{}"'.format(suffix, size)
return float(number) * 1024**suffixes.index(suffix)
pool = argv[1]
critical_perc = float(argv[2])
try:
output = check_output(['zpool', 'list', '-Ho', 'size,alloc', pool])
except:
print('CRITICAL - "zpool" failed')
exit(2)
size, alloc = output.decode('UTF-8').strip().split()
try:
size_b = to_bytes(size)
alloc_b = to_bytes(alloc)
except:
print('CRITICAL - Could not process output of "zpool list": {}'.format(output))
exit(2)
percentage = alloc_b / size_b * 100
if percentage > critical_perc:
print('CRITICAL - Pool "{}" uses {:.2f}% of its space'.format(pool, percentage))
exit(2)
print('OK - Pool "{}" uses {:.2f}% of its space'.format(pool, percentage))
exit(0)

View file

@ -0,0 +1,57 @@
#!/usr/bin/env python3
import re
from datetime import datetime
from json import loads
from subprocess import check_call, check_output
from sys import argv
def create_snap_and_rotate(ds, label, retain, now, all_snapshots):
new_snap = '{}@zfs-auto-snap_{}-{}'.format(ds, label, now)
check_call(['zfs', 'snapshot', new_snap])
prefix = '{}@zfs-auto-snap_{}-'.format(ds, label)
my_candidates = []
for i in sorted(all_snapshots):
if i.startswith(prefix):
my_candidates.append(i)
my_candidates.append(new_snap)
for i in my_candidates[:-retain]:
assert '@' in i, 'BUG! Dataset "{}" has no @!'.format(i)
check_call(['zfs', 'destroy', i])
label = argv[1]
with open('/etc/zfs-snapshot-config.json', 'r') as fp:
metadata = loads(fp.read())
if 'snapshot_only' in metadata:
datasets = set(metadata['snapshot_only'])
else:
output = check_output(['zfs', 'list', '-H', '-o', 'name']).decode('UTF-8')
datasets = set(output.splitlines())
for pattern in metadata.get('snapshot_never', set()):
datasets = set(filter(lambda x: not re.search(pattern, x), datasets))
default_retain = metadata['retain_defaults'][label]
now = datetime.now().strftime('%F-%H%M')
snapshots_created = False
if datasets:
all_snapshots = check_output(['zfs', 'list', '-H', '-o', 'name', '-t', 'snap']).decode('UTF-8').splitlines()
for ds in datasets:
retain = int(metadata.get('retain_per_dataset', {}).get(ds, {}).get(label, default_retain))
if retain > 0:
create_snap_and_rotate(ds, label, retain, now, all_snapshots)
snapshots_created = True
with open('/var/tmp/zfs-auto-snapshot.status', 'w') as fp:
fp.write('{}\n'.format(datetime.now().strftime('%s') if snapshots_created else 0))

View file

@ -0,0 +1,6 @@
<%
arc_max_mb = node.metadata.get('zfs', {}).get('module_options', {}).get('zfs_arc_max_mb', 1024)
%>\
% if arc_max_mb != 0:
options zfs zfs_arc_max=${arc_max_mb * 1024 * 1024}
% endif