#!/usr/bin/python # # Copyright (C) 2007, 2008 Google Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. """Tool to upgrade the configuration file. This code handles only the types supported by simplejson. As an example, "set" is a "list". """ import os import os.path import sys import optparse import tempfile import simplejson from ganeti import utils from ganeti import cli options = None args = None class Error(Exception): """Generic exception""" pass def ReadConfig(path): """Reads configuration file. """ f = open(path, 'r') try: return simplejson.load(f) finally: f.close() def WriteConfig(path, data): """Writes the configuration file. """ if not options.dry_run: utils.CreateBackup(path) (fd, name) = tempfile.mkstemp(dir=os.path.dirname(path)) f = os.fdopen(fd, 'w') try: try: simplejson.dump(data, f) f.flush() if options.dry_run: os.unlink(name) else: os.rename(name, path) except: os.unlink(name) raise finally: f.close() def UpdateFromVersion2To3(cfg): """Updates the configuration from version 2 to 3. """ if cfg['cluster']['config_version'] != 2: return # Add port pool if 'tcpudp_port_pool' not in cfg['cluster']: cfg['cluster']['tcpudp_port_pool'] = [] # Add bridge settings if 'default_bridge' not in cfg['cluster']: cfg['cluster']['default_bridge'] = 'xen-br0' for inst in cfg['instances'].values(): for nic in inst['nics']: if 'bridge' not in nic: nic['bridge'] = None cfg['cluster']['config_version'] = 3 # Main program if __name__ == "__main__": program = os.path.basename(sys.argv[0]) # Option parsing parser = optparse.OptionParser(usage="%prog [options] ") parser.add_option('--dry-run', dest='dry_run', action="store_true", help="Try to do the conversion, but don't write" " output file") parser.add_option(cli.FORCE_OPT) parser.add_option('--verbose', dest='verbose', action="store_true", help="Verbose output") (options, args) = parser.parse_args() # Option checking if args: cfg_file = args[0] else: raise Error("Configuration file not specified") if not options.force: usertext = ("%s MUST run on the master node. Is this the master" " node?" % program) if not cli.AskUser(usertext): sys.exit(1) config = ReadConfig(cfg_file) if options.verbose: import pprint print "Before upgrade:" pprint.pprint(config) print UpdateFromVersion2To3(config) if options.verbose: print "After upgrade:" pprint.pprint(config) print WriteConfig(cfg_file, config) print "The configuration file has been updated successfully. Please run" print " gnt-cluster copyfile %s" % cfg_file print "now." # vim: set foldmethod=marker :