Below is the file 'client/plugins/diskinfo.py' from this revision. You can also download the file.

#!/usr/bin/env python

from phonehome import urgency

import os
import sets
import glob
import stat
import pipes
import string
import popen2
import datetime

from config import install_path

mtab_file = '/etc/mtab'
dr_path = '/dr'
dr_copy = ['/etc/fstab', '/etc/passwd', '/etc/shadow', '/etc/group', '/etc/network/interfaces']
sfdisk = '/sbin/sfdisk'
smartctl = '/usr/sbin/smartctl'

def run():
    results = []

    umask_before = os.umask(0077)

    if not os.access(sfdisk, os.X_OK):
        return [(urgency['critical'], 'sfdisk (%s) not present or executable.' % sfdisk)]

    if not os.access(dr_path, os.R_OK):
        os.mkdir(dr_path)

    # mostly a test to check sfdisk is working, but let's figure out how much disk
    # space the machine has

    disk_devices = []
    process = popen2.Popen3(sfdisk + ' -s')
    for line in process.fromchild:
        fields = [t.strip() for t in line.split(':')]
        if len(fields) != 2:
            continue
        if fields[0] == 'total':
            blocks = fields[1].split(' ')[0]
            try:
                blocks = int(blocks)
            except:
                blocks = 0
            # blocks in sfdisk are 1024 bytes
            results.append((urgency['info'], 'Estimated total physical disk space: %.2fG' % (blocks / 1048576)))
        else:
            disk_devices.append(fields[0])

    status = process.wait() >> 8
    if status != 0:
        return [(urgency['critical'], 'sfdisk -s (size summary) does not work. Exit status %d.' % status)]

    # dump out the partition table
    os.system('sfdisk -l > /dr/sfdisk_for_humans.txt 2> /dr/sfdisk_for_humans_err.txt')
    os.system('sfdisk -d > /dr/sfdisk_for_sfdisk.txt 2> /dr/sfdisk_for_sfdisk_err.txt')

    # check S.M.A.R.T. status
    if os.access(smartctl, os.X_OK):
        for device in disk_devices:
            cmd = 'smartctl -q errorsonly -H -l selftest %s' % pipes.quote(device)
            process = popen2.Popen3(cmd)
            result = process.fromchild.read()
            status = process.wait() >> 8
            # if the drive just doesn't implement this, we'll get an exit status; if there's
            # an actual problem, we get data on stdin. hence, trust stdin.
            # ... except if exit status is /exactly/ 4; that indicates the drive just doesn't do SMART
            if status != 4 and result:
                results.append((urgency['critical'], "SMART failure on disk %s: %s" % (device, result.strip())))
    else:
        results.append((urgency['warning'], 'smartctl not found at location: %s' % smartctl))

    # backup selected files into dr_path
    for fname in dr_copy:
        dest = os.path.join(dr_path, os.path.split(fname)[-1])
        open(dest, 'w').write(open(fname).read())

    # also, let's dump out the PCI device list; might be useful
    os.system('lspci > /dr/lspci.txt 2>/dr/lspci_errors.txt')

    os.umask(umask_before)
    return results