PageRenderTime 184ms CodeModel.GetById 80ms app.highlight 16ms RepoModel.GetById 85ms app.codeStats 0ms

/silverlining/commands/query.py

https://bitbucket.org/ianb/silverlining/
Python | 133 lines | 124 code | 5 blank | 4 comment | 21 complexity | 5f78aa7abf13beb584c800d62453a7c6 MD5 | raw file
  1"""Query a server for its active instances"""
  2import re
  3import fnmatch
  4from silversupport.shell import ssh
  5
  6
  7def command_query(config):
  8    stdout, stderr, returncode = ssh(
  9        'www-mgr', config.node_hostname,
 10        'cat /var/www/appdata.map; echo "END"; '
 11        'cat /var/www/disabledapps.txt; echo END; '
 12        'ls /var/www',
 13        capture_stdout=True)
 14    hosts = {}
 15    lines = [line.strip()
 16             for line in stdout.splitlines()
 17             if line.strip() and not line.strip().startswith('#')]
 18    hosts = {}
 19    site_instances = {}
 20    instance_site = {}
 21    sites = set()
 22    disabled = set()
 23
 24    # parse appdata.map
 25    while 1:
 26        if not lines:
 27            break
 28        line = lines.pop(0)
 29        if line == 'END':
 30            break
 31        hostname, path, data = line.split(None, 2)
 32        instance_name = data.split('|')[0]
 33        hosts[hostname + path] = instance_name
 34
 35    # parse disabledsites.txt
 36    while 1:
 37        if not lines:
 38            break
 39        line = lines.pop(0)
 40        if line == 'END':
 41            break
 42        disabled.add(line)
 43
 44    # parse directory listing
 45    for line in lines:
 46        if line == 'appdata.map' or line == 'disabledapps.txt':
 47            continue
 48        match = re.match(r'^(?:([a-z0-9_.-]+)\.(.*)|default-[a-z]+)$',
 49                         line)
 50        if not match:
 51            continue
 52        if not match.group(1):
 53            site_name = line
 54            release = ''
 55        else:
 56            site_name = match.group(1)
 57            release = match.group(2)
 58        site_instances.setdefault(site_name, {})[release] = line
 59        sites.add(site_name)
 60        instance_site[line] = site_name
 61    site_names = getattr(config.args, 'app-name')
 62    if site_names:
 63        matcher = re.compile('|'.join(fnmatch.translate(s) for s in site_names))
 64        new_hosts = {}
 65        new_site_instances = {}
 66        new_instance_site = {}
 67        new_sites = set()
 68        for site in sites:
 69            if matcher.match(site):
 70                new_sites.add(site)
 71        for hostname, instance in hosts.iteritems():
 72            if matcher.match(hostname):
 73                new_sites.add(instance.split('.')[0])
 74        for site in new_sites:
 75            new_site_instances[site] = site_instances[site]
 76            for n, v in instance_site.iteritems():
 77                if v == site:
 78                    new_instance_site[n] = v
 79            for n, v in hosts.iteritems():
 80                if v.startswith(site):
 81                    new_hosts[n] = v
 82        hosts = new_hosts
 83        site_instances = new_site_instances
 84        instance_site = new_instance_site
 85        sites = new_sites
 86    notify = config.logger.notify
 87    special_hosts = {}
 88    for hostname, site in hosts.items():
 89        if site in ('disabled', 'notfound'):
 90            special_hosts.setdefault(site, []).append(hostname)
 91        elif site in disabled:
 92            special_hosts.setdefault('disabled', []).append(hostname)
 93    for site in sorted(sites):
 94        if len(sites) > 1:
 95            notify('Site: %s' % site)
 96            config.logger.indent += 2
 97        try:
 98            for release, instance_name in sorted(site_instances[site].items()):
 99                hostnames = []
100                for hostname, inst in hosts.items():
101                    if ':' in hostname:
102                        # boring
103                        continue
104                    if (hostname.startswith('www.')
105                        or hostname.startswith('prev.www')):
106                        continue
107                    if inst == instance_name:
108                        hostnames.append(hostname)
109                if not hostnames:
110                    notify('%s (defunct instance)' % instance_name)
111                elif len(hostnames) == 1:
112                    notify('%s: %s' % (instance_name, hostnames[0]))
113                else:
114                    notify('%s:' % instance_name)
115                    for hostname in sorted(hostnames):
116                        notify('  %s' % hostname)
117        finally:
118            if len(sites) > 1:
119                config.logger.indent -= 2
120    if special_hosts.get('disabled'):
121        notify('Disabled hosts:')
122        for hostname in sorted(special_hosts['disabled']):
123            if (':' in hostname or hostname.startswith('www.')
124                or hostname.startswith('prev.www.')):
125                continue
126            notify('  %s' % hostname)
127    if special_hosts.get('notfound'):
128        notify('Hosts marked as not-found:')
129        for hostname in sorted(special_hosts['disabled']):
130            if (':' in hostname or hostname.startswith('www.')
131                or hostname.startswith('prev.www.')):
132                continue
133            notify('  %s' % hostname)