blob: eb7ab5f6cbce64ddab197059662cf8ba414bde38 [file] [log] [blame]
#!/usr/bin/python2.7
"""stream update images to gfiber devices."""
import glob
import os
import subprocess
import sys
import options
optspec = """
flasher.py [options...] host1 host2 ... hostN
--
b,basedir= Read image from under this base directory
f,force Bypass image version check
i,image= Use this specific image file
"""
global_serve_map = {}
def FindImages(basedir):
"""Find our Buildroot directory, then return paths to all its images."""
if not basedir:
basedir = os.getcwd()
search_dir = basedir
last_search_dir = ''
while last_search_dir != '/':
dirents = os.listdir(search_dir)
if 'buildroot' in dirents:
break
last_search_dir = search_dir
search_dir, _ = os.path.split(basedir)
else:
raise OSError('buildroot directory not found in %r or its parents' %
basedir)
images_glob = os.path.join(os.path.realpath(search_dir), '*/images/*.gi')
images = glob.glob(images_glob)
serve_map = {}
latest_map = {}
for image in images:
tail = os.path.basename(image)
if tail == 'latest.gi':
tail = os.path.basename(os.path.realpath(image))
platform, _ = tail.split('-', 1)
latest_map[platform] = tail
serve_map[tail] = image
return serve_map, latest_map
def main():
global global_serve_map
os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '..'))
o = options.Options(optspec)
(opt, _, extra) = o.parse(sys.argv[1:])
if not extra:
o.fatal('must supply at least one host to flash')
global_serve_map, latest_map = FindImages(opt.basedir)
for host in extra:
host_ssh = ['ssh', '-o RequestTTY=no', 'root@%s' % host]
current_version = subprocess.check_output(
host_ssh + ['cat /etc/version'])
host_platform, unused_host_build = current_version.split('-', 1)
if opt.image:
image_file = os.path.basename(opt.image)
requested_version = os.path.splitext(image_file)[0]
unused_platform, build = requested_version.split('-', 1)
image = '%s-%s.gi' % (host_platform, build)
if image not in global_serve_map:
global_serve_map[image] = opt.image
else:
image = latest_map[host_platform]
if image == '%s.gi' % current_version and not opt.force:
print >> sys.stderr, ('Skipping host %s, already running version %s' %
(host, current_version))
print >> sys.stderr, 'Run again with --force to override this.'
continue
install_cmd = ('ginstall -t - && '
'echo "Installed image successfully; rebooting" && '
'( sleep 1; reboot; ) &')
image_file = open(global_serve_map[image])
subprocess.check_call(host_ssh + [install_cmd], stdin=image_file)
if __name__ == '__main__':
main()