PageRenderTime 8ms CodeModel.GetById 0ms RepoModel.GetById 1ms app.codeStats 0ms

/silverlining/commands/query.py

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