bundles/zfs: import bundle from work repository
This commit is contained in:
parent
b690ae25b0
commit
4934eb46fb
11 changed files with 841 additions and 0 deletions
33
bundles/zfs/files/check_zfs_auto_snapshot
Normal file
33
bundles/zfs/files/check_zfs_auto_snapshot
Normal 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
|
63
bundles/zfs/files/check_zfs_old_snapshots
Normal file
63
bundles/zfs/files/check_zfs_old_snapshots
Normal 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)
|
26
bundles/zfs/files/check_zfs_volumes
Normal file
26
bundles/zfs/files/check_zfs_volumes
Normal 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
|
15
bundles/zfs/files/check_zpool_online
Normal file
15
bundles/zfs/files/check_zpool_online
Normal 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
|
40
bundles/zfs/files/check_zpool_space
Normal file
40
bundles/zfs/files/check_zpool_space
Normal 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)
|
57
bundles/zfs/files/zfs-auto-snapshot
Normal file
57
bundles/zfs/files/zfs-auto-snapshot
Normal 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))
|
6
bundles/zfs/files/zfs-modprobe.conf
Normal file
6
bundles/zfs/files/zfs-modprobe.conf
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue