Statistics
| Branch: | Tag: | Revision:

root / tools / cfgupgrade @ 6d691282

History | View | Annotate | Download (4.2 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 6d691282 Michael Hanselmann
def main():
129 6d691282 Michael Hanselmann
  """Main program.
130 6d691282 Michael Hanselmann
131 6d691282 Michael Hanselmann
  """
132 6d691282 Michael Hanselmann
  global options, args
133 6d691282 Michael Hanselmann
134 319856a9 Michael Hanselmann
  program = os.path.basename(sys.argv[0])
135 319856a9 Michael Hanselmann
136 0006af7d Michael Hanselmann
  # Option parsing
137 1c2d87fc Michael Hanselmann
  parser = optparse.OptionParser(usage="%prog [options] <config-file>")
138 60edf71e Michael Hanselmann
  parser.add_option('--dry-run', dest='dry_run',
139 60edf71e Michael Hanselmann
                    action="store_true",
140 f4bc1f2c Michael Hanselmann
                    help="Try to do the conversion, but don't write"
141 f4bc1f2c Michael Hanselmann
                         " output file")
142 f97c7901 Michael Hanselmann
  parser.add_option(cli.FORCE_OPT)
143 eda37a5a Michael Hanselmann
  parser.add_option(cli.DEBUG_OPT)
144 0006af7d Michael Hanselmann
  parser.add_option('--verbose', dest='verbose',
145 0006af7d Michael Hanselmann
                    action="store_true",
146 0006af7d Michael Hanselmann
                    help="Verbose output")
147 0006af7d Michael Hanselmann
  (options, args) = parser.parse_args()
148 0006af7d Michael Hanselmann
149 eda37a5a Michael Hanselmann
  SetupLogging()
150 eda37a5a Michael Hanselmann
151 0006af7d Michael Hanselmann
  # Option checking
152 0006af7d Michael Hanselmann
  if args:
153 0006af7d Michael Hanselmann
    cfg_file = args[0]
154 0006af7d Michael Hanselmann
  else:
155 3ecf6786 Iustin Pop
    raise Error("Configuration file not specified")
156 0006af7d Michael Hanselmann
157 319856a9 Michael Hanselmann
  if not options.force:
158 f4bc1f2c Michael Hanselmann
    usertext = ("%s MUST run on the master node. Is this the master"
159 f4bc1f2c Michael Hanselmann
                " node?" % program)
160 f97c7901 Michael Hanselmann
    if not cli.AskUser(usertext):
161 319856a9 Michael Hanselmann
      sys.exit(1)
162 319856a9 Michael Hanselmann
163 0006af7d Michael Hanselmann
  config = ReadConfig(cfg_file)
164 0006af7d Michael Hanselmann
165 319856a9 Michael Hanselmann
  if options.verbose:
166 319856a9 Michael Hanselmann
    import pprint
167 319856a9 Michael Hanselmann
    print "Before upgrade:"
168 319856a9 Michael Hanselmann
    pprint.pprint(config)
169 319856a9 Michael Hanselmann
    print
170 319856a9 Michael Hanselmann
171 0006af7d Michael Hanselmann
  UpdateFromVersion2To3(config)
172 0006af7d Michael Hanselmann
173 0006af7d Michael Hanselmann
  if options.verbose:
174 319856a9 Michael Hanselmann
    print "After upgrade:"
175 0006af7d Michael Hanselmann
    pprint.pprint(config)
176 319856a9 Michael Hanselmann
    print
177 319856a9 Michael Hanselmann
178 319856a9 Michael Hanselmann
  WriteConfig(cfg_file, config)
179 319856a9 Michael Hanselmann
180 319856a9 Michael Hanselmann
  print "The configuration file has been updated successfully. Please run"
181 319856a9 Michael Hanselmann
  print "  gnt-cluster copyfile %s" % cfg_file
182 319856a9 Michael Hanselmann
  print "now."
183 0006af7d Michael Hanselmann
184 6d691282 Michael Hanselmann
185 6d691282 Michael Hanselmann
if __name__ == "__main__":
186 6d691282 Michael Hanselmann
  main()
187 6d691282 Michael Hanselmann
188 319856a9 Michael Hanselmann
# vim: set foldmethod=marker :