Coverage for sm/core/util.py : 39%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""Fake util module"""
4from past.builtins import basestring
5import os
6import subprocess
7import time
8import re
9import glob
10import syslog
11import signal
12import socket
14from . import f_exceptions
16SCSI_ID_BIN = '/usr/lib/udev/scsi_id'
17ISCSI_REFDIR = '/var/run/sr-ref'
19NO_LOGGING_STAMPFILE = '/etc/xensource/no_sm_log'
20LOGGING = not os.path.exists(NO_LOGGING_STAMPFILE)
21_SM_SYSLOG_FACILITY = syslog.LOG_LOCAL2
22LOG_EMERG = syslog.LOG_EMERG
23LOG_ALERT = syslog.LOG_ALERT
24LOG_CRIT = syslog.LOG_CRIT
25LOG_ERR = syslog.LOG_ERR
26LOG_WARNING = syslog.LOG_WARNING
27LOG_NOTICE = syslog.LOG_NOTICE
28LOG_INFO = syslog.LOG_INFO
29LOG_DEBUG = syslog.LOG_DEBUG
32def doexec(args, inputtext=None):
33 """Execute a subprocess, then return its return code, stdout and stderr"""
35 proc = subprocess.Popen(args, stdin=subprocess.PIPE,
36 stdout=subprocess.PIPE,
37 stderr=subprocess.PIPE,
38 close_fds=True)
39 inputtext = inputtext.encode('utf-8') if inputtext else inputtext
40 (stdout, stderr) = proc.communicate(inputtext)
41 stdout = stdout.decode('utf-8')
42 stderr = stderr.decode('utf-8')
43 ret = proc.returncode
44 return (ret, stdout, stderr)
46def get_real_path(path):
47 "Follow symlinks to the actual file"
48 absPath = path
49 directory = ''
50 while os.path.islink(absPath):
51 directory = os.path.dirname(absPath)
52 absPath = os.readlink(absPath)
53 absPath = os.path.join(directory, absPath)
54 return absPath
57def wait_for_path(path, timeout):
58 for _ in range(timeout):
59 if len(glob.glob(path)):
60 return True
61 time.sleep(1)
62 return False
64def wait_for_nopath(path,timeout):
65 for i in range(0,timeout):
66 if not os.path.exists(path):
67 return True
68 time.sleep(1)
69 return False
72def scsi_id_sanitise(str_):
73 """scsi_id_sanitise"""
74 text = re.sub("^\s+", "", str_) # pylint: disable=W1401
75 return re.sub("\s+", "_", text) # pylint: disable=W1401
78def is_string(value):
79 """trivial"""
80 return isinstance(value, basestring)
83def pread(cmdlist, scramble=None, expect_rc=0):
84 """ported from SM util"""
85 cmdlist_for_exec = []
86 cmdlist_for_log = []
87 for item in cmdlist:
88 if is_string(item):
89 cmdlist_for_exec.append(item)
90 if scramble:
91 if item.find(scramble) != -1:
92 cmdlist_for_log.append("<filtered out>")
93 else:
94 cmdlist_for_log.append(item)
95 else:
96 cmdlist_for_log.append(item)
97 else:
98 cmdlist_for_exec.append(item[0])
99 cmdlist_for_log.append(item[1])
101 (ret, stdout, stderr) = doexec(cmdlist_for_exec)
102 if ret != expect_rc:
103 if stderr == '':
104 stderr = stdout
105 raise f_exceptions.XenError("Command", stderr.strip())
106 return stdout
109def pread2(cmdlist):
110 """Ditto"""
111 return pread(cmdlist)
114def get_scsi_id(path):
115 """Get the SCSI id of a block device
117 Input:
118 path -- (str) path to block device; can be symlink
120 Return:
121 scsi_id -- (str) the device's SCSI id
123 Raise:
124 f_exceptions.XenError
125 """
127 if not path.startswith('/dev/'):
128 path = '/dev/' + path.lstrip('/')
130 stdout = pread2([SCSI_ID_BIN, '-g', '--device', path])
132 return scsi_id_sanitise(stdout[:-1])
135def match_uuid(s):
136 regex = re.compile("^[0-9a-f]{8}-(([0-9a-f]{4})-){3}[0-9a-f]{12}")
137 return regex.search(s, 0)
140class TimeoutException(Exception):
141 pass
144def timeout_call(timeoutseconds, function, *arguments):
145 def handler(signum, frame):
146 raise TimeoutException()
147 signal.signal(signal.SIGALRM, handler)
148 signal.alarm(timeoutseconds)
149 try:
150 function(*arguments)
151 finally:
152 # Cancel the alarm signal so that it isn't fired later on
153 signal.alarm(0)
156def _incr_iscsiSR_refcount(targetIQN, uuid):
157 if not os.path.exists(ISCSI_REFDIR):
158 os.mkdir(ISCSI_REFDIR)
159 filename = os.path.join(ISCSI_REFDIR, targetIQN)
160 try:
161 f = open(filename, 'a+')
162 except:
163 raise f_exceptions.XenError('LVMRefCount',
164 message='file %s' % filename)
166 f.seek(0)
167 found = False
168 refcount = 0
169 for line in filter(match_uuid, f.readlines()):
170 refcount += 1
171 if line.find(uuid) != -1:
172 found = True
173 if not found:
174 f.write("%s\n" % uuid)
175 refcount += 1
176 f.close()
177 return refcount
180def _decr_iscsiSR_refcount(targetIQN, uuid):
181 filename = os.path.join(ISCSI_REFDIR, targetIQN)
182 if not os.path.exists(filename):
183 return 0
184 try:
185 f = open(filename, 'a+')
186 except:
187 raise f_exceptions.XenError('LVMRefCount',
188 message='file %s' % filename)
189 f.seek(0)
190 output = []
191 refcount = 0
192 for line in filter(match_uuid, f.readlines()):
193 if line.find(uuid) == -1:
194 output.append(line[:-1])
195 refcount += 1
196 if not refcount:
197 os.unlink(filename)
198 return refcount
200 # Re-open file and truncate
201 f.close()
202 f = open(filename, 'w')
203 for i in range(0,refcount):
204 f.write("%s\n" % output[i])
205 f.close()
206 return refcount
208def _logToSyslog(ident, facility, priority, message):
209 syslog.openlog(ident, 0, facility)
210 syslog.syslog(priority, "[%d] %s" % (os.getpid(), message))
211 syslog.closelog()
214def SMlog(message, ident="SM", priority=LOG_INFO):
215 if LOGGING: 215 ↛ exitline 215 didn't return from function 'SMlog', because the condition on line 215 was never false
216 for message_line in str(message).split('\n'):
217 _logToSyslog(ident, _SM_SYSLOG_FACILITY, priority, message_line)
220def retry(f, maxretry=20, period=3):
221 retries = 0
222 while True:
223 try:
224 return f()
225 except Exception as e:
226 SMlog("Got exception: %s. Retry number: %s" % (str(e),retries))
228 retries += 1
229 if retries >= maxretry:
230 break
232 time.sleep(period)
234 return f()
236def testHost(hostname, port):
237 """
238 Modified from _testHost in sm.util
239 """
240 SMlog("testHost: Testing host/port: %s,%d" % (hostname,port))
241 try:
242 sockinfo = socket.getaddrinfo(hostname, int(port))[0]
243 except:
244 SMlog('Exception occured getting IP for %s' % hostname)
245 return False
247 timeout = 10
249 sock = socket.socket(sockinfo[0], socket.SOCK_STREAM)
250 # Only allow the connect to block for up to timeout seconds
251 sock.settimeout(timeout)
252 try:
253 sock.connect(sockinfo[4])
254 # Fix for MS storage server bug
255 sock.send(b'\n')
256 sock.close()
257 return True
258 except socket.error as reason:
259 SMlog("testHost: Connect failed after %d seconds (%s) - %s" \
260 % (timeout, hostname, reason))
261 return False