D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
opt
/
imh-python
/
lib
/
python2.7
/
site-packages
/
rads
/
Filename :
ha.py
back
Copy
""" Virtuozzo HA common functions """ import platform from subprocess import CalledProcessError, check_output, Popen, PIPE import sys from rads.common import errprint from rads.exceptions import HAError def check_if_vz(): "Checks if Virtuozzo is in /etc/redhat-release" return bool("Virtuozzo" in platform.linux_distribution()[0]) def get_os_maj_version(): "Returns major version of OS" version = platform.linux_distribution()[1].split('.')[0] return version def check_vz7(): """checks if havp in name and if platform is 7""" return bool(check_if_vz() and get_os_maj_version() == "7") def is_container_running(ctid): """returns True if the container is running on this HA node, False if it isn't or if some other error occurs""" prlctl_list_cmd = ['/usr/bin/prlctl', 'list', '-H', '-o', 'status', ctid] try: prlctl_list_run = Popen(prlctl_list_cmd, stdout=PIPE, stderr=PIPE) except OSError: errprint("OSError exception running \"prlctl list -H -o status %s\"" % ctid) return False prlctl_list_out, prlctl_list_err = prlctl_list_run.communicate() if prlctl_list_run.returncode > 0: return False status = prlctl_list_out.split()[0] return bool(str(status) == "running") def get_name(ctid): """Obtain the name (aka legacy CTID) of a container. The input ctid will be either a legacy CTID or a UUID depending whether we are on VZ6 or VZ7""" prlctl_list_cmd = ['/usr/bin/prlctl', 'list', '-H', '-o', 'name', ctid] try: prlctl_list_run = Popen(prlctl_list_cmd, stdout=PIPE, stderr=PIPE) except OSError: errprint("OSError exception running \"prlctl list -H -o name %s\"" % ctid) return None prlctl_list_out, prlctl_list_err = prlctl_list_run.communicate() if prlctl_list_run.returncode > 0: errprint("Error: \"prlctl list -H -o name %s\" returned %s\n\nSTDERR:\n\n%s" % ( ctid, prlctl_list_run.returncode, prlctl_list_err) ) return None name = prlctl_list_out.split()[0] return str(name) def get_envid(ctid): """Obtain the envid of a container. This determines what the subdirectory of /vz/root and /vz/private will be. This also has to run on VZ4 which lacks the envid field or prlctl, so we just return the CTID""" try: with open('/etc/virtuozzo-release', 'r') as file_ptr: for line in file_ptr: if line.startswith('Virtuozzo release 4'): return str(ctid) except IOError: errprint("Error reading /etc/virtuozzo-release, is this a VZ server?") return None prlctl_list_cmd = ['/usr/bin/prlctl', 'list', '-H', '-o', 'envid', ctid] try: prlctl_list_run = Popen(prlctl_list_cmd, stdout=PIPE, stderr=PIPE) except OSError: errprint("OSError exception running \"prlctl list -H -o envid %s\"" % ctid) return None prlctl_list_out, prlctl_list_err = prlctl_list_run.communicate() if prlctl_list_run.returncode > 0: errprint("Error: \"prlctl list -H -o envid %s\" returned %s\n\nSTDERR:\n\n%s" % ( ctid, prlctl_list_run.returncode, prlctl_list_err) ) return None envid = prlctl_list_out.split()[0] return str(envid) def get_uuid(ctid): """Obtain the UUID of a container. Does not work on VZ4""" prlctl_list_cmd = ['/usr/bin/prlctl', 'list', '-H', '-o', 'uuid', ctid] try: prlctl_list_run = Popen(prlctl_list_cmd, stdout=PIPE, stderr=PIPE) except OSError: errprint("OSError exception running \"prlctl list -H -o uuid %s\"" % ctid) return None prlctl_list_out, prlctl_list_err = prlctl_list_run.communicate() if prlctl_list_run.returncode > 0: errprint("Error: \"prlctl list -H -o uuid %s\" returned %s\n\nSTDERR:\n\n%s" % ( ctid, prlctl_list_run.returncode, prlctl_list_err) ) return None uuid = prlctl_list_out.split()[0] uuid = uuid.strip("{}") return str(uuid) def _get_cts(*args, **kwargs): """Returns unparsed output of vzlist or prctl to list containers kwargs is used (similar to sh) for sending special --flags such as setting all=True""" # so the returned dict will match the keys requested, store the original # key in opts before mutating it to match what the subproc expects if check_if_vz(): if not check_vz7() and 'ostemplate' in args: # prlctl's ostemplate is broken and reports distro on vz6 # switch to vzlist; fix envid to veid if it was requested cmd = ['/usr/sbin/vzlist', '-H'] opts = {x: 'veid' if x == 'envid' else x for x in args} else: # prctl refers to 'ctid' as 'name' cmd = ['/usr/bin/prlctl', 'list', '-H'] opts = {x: 'name' if x == 'ctid' else x for x in args} else: # OpenVZ opts = {x: 'veid' if x == 'envid' else x for x in args} cmd = ['/usr/sbin/vzlist', '-H'] for key, val in kwargs.iteritems(): if isinstance(val, basestring): cmd.extend(['--{}'.format(key), val]) elif val is True: cmd.append('--{}'.format(key)) # forces opts's vals to be in the same order as args cmd_opts = ','.join([opts[x] for x in args]) cmd.extend(['-o', cmd_opts]) try: stdout = check_output(cmd) except CalledProcessError as fail: raise HAError(str(fail)) return stdout def get_cts(*args, **kwargs): """Returns containers according to platform as a list of dicts. kwargs is used (similar to sh) for sending special --flags such as setting all=True""" if not args: args = ['ctid'] stdout = _get_cts(*args, **kwargs) ret = [] # process each line as a dict where keys are the arg and vals are the result for row in stdout.splitlines(): row = row.strip() if not row: continue # blank line row = row.split() if len(row) != len(args): raise HAError('unexpected columns: {!r}'.format(row)) ret.append({x: row[i] for i, x in enumerate(args)}) return ret def list_cts(*args, **kwargs): """Prints containers according to platform. kwargs is used (similar to sh) for sending special --flags such as setting all=True""" if not args: args = ['ctid'] try: list_output = _get_cts(*args, **kwargs) if list_output: for i in list_output.splitlines(): print i.strip() except HAError as fail: sys.exit(str(fail))