@@ -0,0 +1,80 @@
from __future__ import with_statement
from fabric .api import env , run , settings , hide
from fabric .decorators import hosts , runs_once
venv = "/home/websites/.virtualenvs/twtv3/"
env .user = 'webdev'
env .hosts = [
'192.168.1.10' ,
'192.168.1.11' ,
'192.168.1.12' ,
'192.168.1.13' ,
]
def _get_package_list ():
"""
Get the list of currently installed packages and versions via pip freeze
"""
with settings (
hide ('warnings' , 'running' , 'stdout' , 'stderr' ),
warn_only = True
):
return run ("%sbin/pip freeze -l" % venv )
def _process_packages (packages ):
"""
Convert the packages datastructure into the multiple versions and missing
servers lists and output the result
"""
multi_versions = {}
missing_servers = []
for package , versions in packages .items ():
if len (versions .keys ()) > 1 :
# There is more than one version installed on the servers
multi_versions [package ] = versions
elif len (versions [versions .keys ()[0 ]]) != len (env .hosts ):
# The package is not installed on all the servers
missing_hosts = set (env .hosts ) - set (versions [versions .keys ()[0 ]])
missing_servers .append (
"%s: %s" % (package , ", " .join (missing_hosts ))
)
if missing_servers or multi_versions :
print ""
print "Packages out-of-sync:"
if multi_versions :
print ""
print "Multiple versions found of these packages:"
for package , versions in multi_versions .items ():
print package
for ver , servers in versions .items ():
print " %s: %s" % (ver , ", " .join (servers ))
if missing_servers :
print ""
print "These packages are missing on these servers:"
for item in missing_servers :
print item
@runs_once
def check_package_versions ():
"""
Check the versions of all the packages on all the servers and print out
the out of sync packages
"""
packages = {}
for host in env .hosts :
with settings (host_string = host ):
print "Getting packages on %s" % host
result = _get_package_list ()
pkg_list = result .splitlines ()
for package in pkg_list :
if package .startswith ("-e" ):
version , pkg = package .split ("#egg=" )
else :
pkg , version = package .split ("==" )
if pkg not in packages :
packages [pkg ] = {}
if version not in packages [pkg ]:
packages [pkg ][version ] = []
packages [pkg ][version ].append (host )
_process_packages (packages )