Add a timeout decorator for timing out functions that may hang
Fixes #6891
This commit is contained in:
parent
26ce8dac27
commit
eebc72ab9b
1 changed files with 44 additions and 3 deletions
|
@ -17,11 +17,13 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import array
|
import array
|
||||||
|
import errno
|
||||||
import fcntl
|
import fcntl
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import glob
|
import glob
|
||||||
import platform
|
import platform
|
||||||
import re
|
import re
|
||||||
|
import signal
|
||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
import datetime
|
import datetime
|
||||||
|
@ -40,6 +42,33 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import simplejson as json
|
import simplejson as json
|
||||||
|
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
# timeout function to make sure some fact gathering
|
||||||
|
# steps do not exceed a time limit
|
||||||
|
|
||||||
|
class TimeoutError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def timeout(seconds=10, error_message=os.strerror(errno.ETIME)):
|
||||||
|
def decorator(func):
|
||||||
|
def _handle_timeout(signum, frame):
|
||||||
|
raise TimeoutError(error_message)
|
||||||
|
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
signal.signal(signal.SIGALRM, _handle_timeout)
|
||||||
|
signal.alarm(seconds)
|
||||||
|
try:
|
||||||
|
result = func(*args, **kwargs)
|
||||||
|
finally:
|
||||||
|
signal.alarm(0)
|
||||||
|
return result
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
class Facts(object):
|
class Facts(object):
|
||||||
"""
|
"""
|
||||||
This class should only attempt to populate those facts that
|
This class should only attempt to populate those facts that
|
||||||
|
@ -498,7 +527,10 @@ class LinuxHardware(Hardware):
|
||||||
self.get_memory_facts()
|
self.get_memory_facts()
|
||||||
self.get_dmi_facts()
|
self.get_dmi_facts()
|
||||||
self.get_device_facts()
|
self.get_device_facts()
|
||||||
|
try:
|
||||||
self.get_mount_facts()
|
self.get_mount_facts()
|
||||||
|
except TimeoutError:
|
||||||
|
pass
|
||||||
return self.facts
|
return self.facts
|
||||||
|
|
||||||
def get_memory_facts(self):
|
def get_memory_facts(self):
|
||||||
|
@ -622,6 +654,7 @@ class LinuxHardware(Hardware):
|
||||||
else:
|
else:
|
||||||
self.facts[k] = 'NA'
|
self.facts[k] = 'NA'
|
||||||
|
|
||||||
|
@timeout(10)
|
||||||
def get_mount_facts(self):
|
def get_mount_facts(self):
|
||||||
self.facts['mounts'] = []
|
self.facts['mounts'] = []
|
||||||
mtab = get_file_content('/etc/mtab', '')
|
mtab = get_file_content('/etc/mtab', '')
|
||||||
|
@ -919,7 +952,10 @@ class FreeBSDHardware(Hardware):
|
||||||
self.get_memory_facts()
|
self.get_memory_facts()
|
||||||
self.get_dmi_facts()
|
self.get_dmi_facts()
|
||||||
self.get_device_facts()
|
self.get_device_facts()
|
||||||
|
try:
|
||||||
self.get_mount_facts()
|
self.get_mount_facts()
|
||||||
|
except TimeoutError:
|
||||||
|
pass
|
||||||
return self.facts
|
return self.facts
|
||||||
|
|
||||||
def get_cpu_facts(self):
|
def get_cpu_facts(self):
|
||||||
|
@ -962,6 +998,7 @@ class FreeBSDHardware(Hardware):
|
||||||
self.facts['swaptotal_mb'] = data[1]
|
self.facts['swaptotal_mb'] = data[1]
|
||||||
self.facts['swapfree_mb'] = data[3]
|
self.facts['swapfree_mb'] = data[3]
|
||||||
|
|
||||||
|
@timeout(10)
|
||||||
def get_mount_facts(self):
|
def get_mount_facts(self):
|
||||||
self.facts['mounts'] = []
|
self.facts['mounts'] = []
|
||||||
fstab = get_file_content('/etc/fstab')
|
fstab = get_file_content('/etc/fstab')
|
||||||
|
@ -1041,7 +1078,10 @@ class NetBSDHardware(Hardware):
|
||||||
def populate(self):
|
def populate(self):
|
||||||
self.get_cpu_facts()
|
self.get_cpu_facts()
|
||||||
self.get_memory_facts()
|
self.get_memory_facts()
|
||||||
|
try:
|
||||||
self.get_mount_facts()
|
self.get_mount_facts()
|
||||||
|
except TimeoutError:
|
||||||
|
pass
|
||||||
return self.facts
|
return self.facts
|
||||||
|
|
||||||
def get_cpu_facts(self):
|
def get_cpu_facts(self):
|
||||||
|
@ -1085,6 +1125,7 @@ class NetBSDHardware(Hardware):
|
||||||
val = data[1].strip().split(' ')[0]
|
val = data[1].strip().split(' ')[0]
|
||||||
self.facts["%s_mb" % key.lower()] = long(val) / 1024
|
self.facts["%s_mb" % key.lower()] = long(val) / 1024
|
||||||
|
|
||||||
|
@timeout(10)
|
||||||
def get_mount_facts(self):
|
def get_mount_facts(self):
|
||||||
self.facts['mounts'] = []
|
self.facts['mounts'] = []
|
||||||
fstab = get_file_content('/etc/fstab')
|
fstab = get_file_content('/etc/fstab')
|
||||||
|
|
Loading…
Reference in a new issue