Mini Shell

Direktori : /opt/imh-python/lib/python2.7/site-packages/rads/
Upload File :
Current File : //opt/imh-python/lib/python2.7/site-packages/rads/ha.py

"""
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))

Zerion Mini Shell 1.0