Statistics
| Branch: | Tag: | Revision:

root / tools / cfgupgrade @ eda37a5a

History | View | Annotate | Download (4.1 kB)

1 0006af7d Michael Hanselmann
#!/usr/bin/python
2 0006af7d Michael Hanselmann
#
3 0006af7d Michael Hanselmann
4 f97c7901 Michael Hanselmann
# Copyright (C) 2007, 2008 Google Inc.
5 0006af7d Michael Hanselmann
#
6 0006af7d Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 0006af7d Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 0006af7d Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 0006af7d Michael Hanselmann
# (at your option) any later version.
10 0006af7d Michael Hanselmann
#
11 0006af7d Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 0006af7d Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 0006af7d Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 0006af7d Michael Hanselmann
# General Public License for more details.
15 0006af7d Michael Hanselmann
#
16 0006af7d Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 0006af7d Michael Hanselmann
# along with this program; if not, write to the Free Software
18 0006af7d Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 0006af7d Michael Hanselmann
# 02110-1301, USA.
20 0006af7d Michael Hanselmann
21 0006af7d Michael Hanselmann
22 0006af7d Michael Hanselmann
"""Tool to upgrade the configuration file.
23 0006af7d Michael Hanselmann
24 319856a9 Michael Hanselmann
This code handles only the types supported by simplejson. As an example, "set"
25 e0732b36 Michael Hanselmann
is a "list".
26 0006af7d Michael Hanselmann
27 0006af7d Michael Hanselmann
"""
28 0006af7d Michael Hanselmann
29 0006af7d Michael Hanselmann
30 0006af7d Michael Hanselmann
import os
31 0006af7d Michael Hanselmann
import os.path
32 0006af7d Michael Hanselmann
import sys
33 0006af7d Michael Hanselmann
import optparse
34 0006af7d Michael Hanselmann
import tempfile
35 319856a9 Michael Hanselmann
import simplejson
36 eda37a5a Michael Hanselmann
import logging
37 0006af7d Michael Hanselmann
38 319856a9 Michael Hanselmann
from ganeti import utils
39 f97c7901 Michael Hanselmann
from ganeti import cli
40 0006af7d Michael Hanselmann
41 0006af7d Michael Hanselmann
42 319856a9 Michael Hanselmann
options = None
43 319856a9 Michael Hanselmann
args = None
44 0006af7d Michael Hanselmann
45 0006af7d Michael Hanselmann
46 319856a9 Michael Hanselmann
class Error(Exception):
47 319856a9 Michael Hanselmann
  """Generic exception"""
48 319856a9 Michael Hanselmann
  pass
49 0006af7d Michael Hanselmann
50 0006af7d Michael Hanselmann
51 319856a9 Michael Hanselmann
def ReadConfig(path):
52 319856a9 Michael Hanselmann
  """Reads configuration file.
53 0006af7d Michael Hanselmann
54 0006af7d Michael Hanselmann
  """
55 319856a9 Michael Hanselmann
  f = open(path, 'r')
56 319856a9 Michael Hanselmann
  try:
57 e0732b36 Michael Hanselmann
    return simplejson.load(f)
58 319856a9 Michael Hanselmann
  finally:
59 319856a9 Michael Hanselmann
    f.close()
60 0006af7d Michael Hanselmann
61 0006af7d Michael Hanselmann
62 319856a9 Michael Hanselmann
def WriteConfig(path, data):
63 319856a9 Michael Hanselmann
  """Writes the configuration file.
64 319856a9 Michael Hanselmann
65 319856a9 Michael Hanselmann
  """
66 319856a9 Michael Hanselmann
  if not options.dry_run:
67 319856a9 Michael Hanselmann
    utils.CreateBackup(path)
68 0006af7d Michael Hanselmann
69 0006af7d Michael Hanselmann
  (fd, name) = tempfile.mkstemp(dir=os.path.dirname(path))
70 0006af7d Michael Hanselmann
  f = os.fdopen(fd, 'w')
71 0006af7d Michael Hanselmann
  try:
72 0006af7d Michael Hanselmann
    try:
73 319856a9 Michael Hanselmann
      simplejson.dump(data, f)
74 0006af7d Michael Hanselmann
      f.flush()
75 319856a9 Michael Hanselmann
      if options.dry_run:
76 60edf71e Michael Hanselmann
        os.unlink(name)
77 60edf71e Michael Hanselmann
      else:
78 60edf71e Michael Hanselmann
        os.rename(name, path)
79 0006af7d Michael Hanselmann
    except:
80 0006af7d Michael Hanselmann
      os.unlink(name)
81 0006af7d Michael Hanselmann
      raise
82 0006af7d Michael Hanselmann
  finally:
83 0006af7d Michael Hanselmann
    f.close()
84 0006af7d Michael Hanselmann
85 0006af7d Michael Hanselmann
86 0006af7d Michael Hanselmann
def UpdateFromVersion2To3(cfg):
87 0006af7d Michael Hanselmann
  """Updates the configuration from version 2 to 3.
88 0006af7d Michael Hanselmann
89 0006af7d Michael Hanselmann
  """
90 0006af7d Michael Hanselmann
  if cfg['cluster']['config_version'] != 2:
91 0006af7d Michael Hanselmann
    return
92 0006af7d Michael Hanselmann
93 0006af7d Michael Hanselmann
  # Add port pool
94 0006af7d Michael Hanselmann
  if 'tcpudp_port_pool' not in cfg['cluster']:
95 319856a9 Michael Hanselmann
    cfg['cluster']['tcpudp_port_pool'] = []
96 0006af7d Michael Hanselmann
97 0006af7d Michael Hanselmann
  # Add bridge settings
98 0006af7d Michael Hanselmann
  if 'default_bridge' not in cfg['cluster']:
99 0006af7d Michael Hanselmann
    cfg['cluster']['default_bridge'] = 'xen-br0'
100 0006af7d Michael Hanselmann
  for inst in cfg['instances'].values():
101 0006af7d Michael Hanselmann
    for nic in inst['nics']:
102 0006af7d Michael Hanselmann
      if 'bridge' not in nic:
103 0006af7d Michael Hanselmann
        nic['bridge'] = None
104 0006af7d Michael Hanselmann
105 0006af7d Michael Hanselmann
  cfg['cluster']['config_version'] = 3
106 0006af7d Michael Hanselmann
107 0006af7d Michael Hanselmann
108 eda37a5a Michael Hanselmann
def SetupLogging():
109 eda37a5a Michael Hanselmann
  """Configures the logging module.
110 eda37a5a Michael Hanselmann
111 eda37a5a Michael Hanselmann
  """
112 eda37a5a Michael Hanselmann
  formatter = logging.Formatter("%(asctime)s: %(message)s")
113 eda37a5a Michael Hanselmann
114 eda37a5a Michael Hanselmann
  stderr_handler = logging.StreamHandler()
115 eda37a5a Michael Hanselmann
  stderr_handler.setFormatter(formatter)
116 eda37a5a Michael Hanselmann
  if options.debug:
117 eda37a5a Michael Hanselmann
    stderr_handler.setLevel(logging.NOTSET)
118 eda37a5a Michael Hanselmann
  elif options.verbose:
119 eda37a5a Michael Hanselmann
    stderr_handler.setLevel(logging.INFO)
120 eda37a5a Michael Hanselmann
  else:
121 eda37a5a Michael Hanselmann
    stderr_handler.setLevel(logging.CRITICAL)
122 eda37a5a Michael Hanselmann
123 eda37a5a Michael Hanselmann
  root_logger = logging.getLogger("")
124 eda37a5a Michael Hanselmann
  root_logger.setLevel(logging.NOTSET)
125 eda37a5a Michael Hanselmann
  root_logger.addHandler(stderr_handler)
126 eda37a5a Michael Hanselmann
127 eda37a5a Michael Hanselmann
128 0006af7d Michael Hanselmann
# Main program
129 0006af7d Michael Hanselmann
if __name__ == "__main__":
130 319856a9 Michael Hanselmann
  program = os.path.basename(sys.argv[0])
131 319856a9 Michael Hanselmann
132 0006af7d Michael Hanselmann
  # Option parsing
133 1c2d87fc Michael Hanselmann
  parser = optparse.OptionParser(usage="%prog [options] <config-file>")
134 60edf71e Michael Hanselmann
  parser.add_option('--dry-run', dest='dry_run',
135 60edf71e Michael Hanselmann
                    action="store_true",
136 f4bc1f2c Michael Hanselmann
                    help="Try to do the conversion, but don't write"
137 f4bc1f2c Michael Hanselmann
                         " output file")
138 f97c7901 Michael Hanselmann
  parser.add_option(cli.FORCE_OPT)
139 eda37a5a Michael Hanselmann
  parser.add_option(cli.DEBUG_OPT)
140 0006af7d Michael Hanselmann
  parser.add_option('--verbose', dest='verbose',
141 0006af7d Michael Hanselmann
                    action="store_true",
142 0006af7d Michael Hanselmann
                    help="Verbose output")
143 0006af7d Michael Hanselmann
  (options, args) = parser.parse_args()
144 0006af7d Michael Hanselmann
145 eda37a5a Michael Hanselmann
  SetupLogging()
146 eda37a5a Michael Hanselmann
147 0006af7d Michael Hanselmann
  # Option checking
148 0006af7d Michael Hanselmann
  if args:
149 0006af7d Michael Hanselmann
    cfg_file = args[0]
150 0006af7d Michael Hanselmann
  else:
151 3ecf6786 Iustin Pop
    raise Error("Configuration file not specified")
152 0006af7d Michael Hanselmann
153 319856a9 Michael Hanselmann
  if not options.force:
154 f4bc1f2c Michael Hanselmann
    usertext = ("%s MUST run on the master node. Is this the master"
155 f4bc1f2c Michael Hanselmann
                " node?" % program)
156 f97c7901 Michael Hanselmann
    if not cli.AskUser(usertext):
157 319856a9 Michael Hanselmann
      sys.exit(1)
158 319856a9 Michael Hanselmann
159 0006af7d Michael Hanselmann
  config = ReadConfig(cfg_file)
160 0006af7d Michael Hanselmann
161 319856a9 Michael Hanselmann
  if options.verbose:
162 319856a9 Michael Hanselmann
    import pprint
163 319856a9 Michael Hanselmann
    print "Before upgrade:"
164 319856a9 Michael Hanselmann
    pprint.pprint(config)
165 319856a9 Michael Hanselmann
    print
166 319856a9 Michael Hanselmann
167 0006af7d Michael Hanselmann
  UpdateFromVersion2To3(config)
168 0006af7d Michael Hanselmann
169 0006af7d Michael Hanselmann
  if options.verbose:
170 319856a9 Michael Hanselmann
    print "After upgrade:"
171 0006af7d Michael Hanselmann
    pprint.pprint(config)
172 319856a9 Michael Hanselmann
    print
173 319856a9 Michael Hanselmann
174 319856a9 Michael Hanselmann
  WriteConfig(cfg_file, config)
175 319856a9 Michael Hanselmann
176 319856a9 Michael Hanselmann
  print "The configuration file has been updated successfully. Please run"
177 319856a9 Michael Hanselmann
  print "  gnt-cluster copyfile %s" % cfg_file
178 319856a9 Michael Hanselmann
  print "now."
179 0006af7d Michael Hanselmann
180 319856a9 Michael Hanselmann
# vim: set foldmethod=marker :