Newer
Older
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2017, Florent Thiery
'''
Criticality: Normal
Checks that partitions are in conformity with expected norms, and that sufficient free space is available
'''
import subprocess
import sys
import os
BS = 512
def to_gbytes(size_bytes):
def read_file(fname):
with open(fname, 'r') as f:
return f.read()
paths = [
{
'mount_point': '/',
'recommended_types': ('ext4',),
'min_size_gbytes': 14,
'min_free_size_gbytes': 5,
},
{
'mount_point': '/home/msuser/msinstance',
'recommended_types': ('ext4', 'nfsv4'),
'min_size_gbytes': 400,
'min_free_size_gbytes': 10,
},
{
'type': 'swap',
'min_size_gbytes': 1,
},
]
def get_swap_gbytes():
d = read_file('/proc/meminfo')
for l in d.split('\n'):
if 'SwapTotal'in l:
swap = l.split('SwapTotal:')[1].strip()
swap_kbytes, unit = swap.split(' ')
if unit != 'kB':
print('Warning, unexpected unit %s' % unit)
# Filesystem Type 1B-blocks Used Available Use% Mounted on
# /dev/loop2 ext4 52710469632 38253940736 11755397120 77% /
status, output = subprocess.getstatusoutput('df --output="source,fstype,size,used" -B 1 %s | tail -n 1' % path)
if status == 0:
dev, fstype, size, used = output.split()
else:
dev = fstype = size = used = None
return dev, fstype, to_gbytes(int(size)), to_gbytes(int(used))
def check_allocation(dev):
root_dev = os.path.basename(dev)[:3]
d = read_file('/proc/partitions')
dev_partitions = list()
for l in d.split('\n'):
if root_dev in l:
dev_partitions.append(l)
max_size = 0
total_size = 0
for p in dev_partitions:
major, minor, blocks, name = p.split()
size = int(blocks) * 512
if name == root_dev:
max_size = size
else:
total_size += size
unallocated = max_size - total_size
unallocated_gbytes = to_gbytes(unallocated)
if unallocated_gbytes > 1:
print('Warning, %s GB are unallocated on %s' % (unallocated_gbytes, root_dev))
return False
return True
error = False
warning = False
def check_path(p):
global error
global warning
psize = None
mount_point = p.get('mount_point')
if mount_point:
if os.path.isdir(mount_point):
dev, fstype, psize, used = get_path(p['mount_point'])
if fstype not in p.get('recommended_types'):
print('Warning, fs type %s not recommended (recommended: %s)' % (fstype, p['recommended_types']))
warning = True
if 'nfs' not in dev:
warning = not check_allocation(dev)
free_gb = psize - used
min_free_size_gbytes = p.get('min_free_size_gbytes')
if min_free_size_gbytes and free_gb < min_free_size_gbytes:
print('%s has less than %s GB free (%s GB free)' % (mount_point, min_free_size_gbytes, free_gb))
error = True
else:
print('%s not found, cannot check' % mount_point)
elif p.get('type') == 'swap':
name = 'swap'
if psize and psize < p['min_size_gbytes']:
print('%s is smaller than the minimum required size (%s GB < %s GB)' % (name, psize, p['min_size_gbytes']))
error = True
for p in paths:
check_path(p)
OK = 0
ERROR = 1
WARNING = 3
UNTESTABLE = 2
if error: