Statistics
| Branch: | Tag: | Revision:

root / tools / cfgupgrade @ 6d691282

History | View | Annotate | Download (4.2 kB)

1
#!/usr/bin/python
2
#
3

    
4
# Copyright (C) 2007, 2008 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
"""Tool to upgrade the configuration file.
23

    
24
This code handles only the types supported by simplejson. As an example, "set"
25
is a "list".
26

    
27
"""
28

    
29

    
30
import os
31
import os.path
32
import sys
33
import optparse
34
import tempfile
35
import simplejson
36
import logging
37

    
38
from ganeti import utils
39
from ganeti import cli
40

    
41

    
42
options = None
43
args = None
44

    
45

    
46
class Error(Exception):
47
  """Generic exception"""
48
  pass
49

    
50

    
51
def ReadConfig(path):
52
  """Reads configuration file.
53

    
54
  """
55
  f = open(path, 'r')
56
  try:
57
    return simplejson.load(f)
58
  finally:
59
    f.close()
60

    
61

    
62
def WriteConfig(path, data):
63
  """Writes the configuration file.
64

    
65
  """
66
  if not options.dry_run:
67
    utils.CreateBackup(path)
68

    
69
  (fd, name) = tempfile.mkstemp(dir=os.path.dirname(path))
70
  f = os.fdopen(fd, 'w')
71
  try:
72
    try:
73
      simplejson.dump(data, f)
74
      f.flush()
75
      if options.dry_run:
76
        os.unlink(name)
77
      else:
78
        os.rename(name, path)
79
    except:
80
      os.unlink(name)
81
      raise
82
  finally:
83
    f.close()
84

    
85

    
86
def UpdateFromVersion2To3(cfg):
87
  """Updates the configuration from version 2 to 3.
88

    
89
  """
90
  if cfg['cluster']['config_version'] != 2:
91
    return
92

    
93
  # Add port pool
94
  if 'tcpudp_port_pool' not in cfg['cluster']:
95
    cfg['cluster']['tcpudp_port_pool'] = []
96

    
97
  # Add bridge settings
98
  if 'default_bridge' not in cfg['cluster']:
99
    cfg['cluster']['default_bridge'] = 'xen-br0'
100
  for inst in cfg['instances'].values():
101
    for nic in inst['nics']:
102
      if 'bridge' not in nic:
103
        nic['bridge'] = None
104

    
105
  cfg['cluster']['config_version'] = 3
106

    
107

    
108
def SetupLogging():
109
  """Configures the logging module.
110

    
111
  """
112
  formatter = logging.Formatter("%(asctime)s: %(message)s")
113

    
114
  stderr_handler = logging.StreamHandler()
115
  stderr_handler.setFormatter(formatter)
116
  if options.debug:
117
    stderr_handler.setLevel(logging.NOTSET)
118
  elif options.verbose:
119
    stderr_handler.setLevel(logging.INFO)
120
  else:
121
    stderr_handler.setLevel(logging.CRITICAL)
122

    
123
  root_logger = logging.getLogger("")
124
  root_logger.setLevel(logging.NOTSET)
125
  root_logger.addHandler(stderr_handler)
126

    
127

    
128
def main():
129
  """Main program.
130

    
131
  """
132
  global options, args
133

    
134
  program = os.path.basename(sys.argv[0])
135

    
136
  # Option parsing
137
  parser = optparse.OptionParser(usage="%prog [options] <config-file>")
138
  parser.add_option('--dry-run', dest='dry_run',
139
                    action="store_true",
140
                    help="Try to do the conversion, but don't write"
141
                         " output file")
142
  parser.add_option(cli.FORCE_OPT)
143
  parser.add_option(cli.DEBUG_OPT)
144
  parser.add_option('--verbose', dest='verbose',
145
                    action="store_true",
146
                    help="Verbose output")
147
  (options, args) = parser.parse_args()
148

    
149
  SetupLogging()
150

    
151
  # Option checking
152
  if args:
153
    cfg_file = args[0]
154
  else:
155
    raise Error("Configuration file not specified")
156

    
157
  if not options.force:
158
    usertext = ("%s MUST run on the master node. Is this the master"
159
                " node?" % program)
160
    if not cli.AskUser(usertext):
161
      sys.exit(1)
162

    
163
  config = ReadConfig(cfg_file)
164

    
165
  if options.verbose:
166
    import pprint
167
    print "Before upgrade:"
168
    pprint.pprint(config)
169
    print
170

    
171
  UpdateFromVersion2To3(config)
172

    
173
  if options.verbose:
174
    print "After upgrade:"
175
    pprint.pprint(config)
176
    print
177

    
178
  WriteConfig(cfg_file, config)
179

    
180
  print "The configuration file has been updated successfully. Please run"
181
  print "  gnt-cluster copyfile %s" % cfg_file
182
  print "now."
183

    
184

    
185
if __name__ == "__main__":
186
  main()
187

    
188
# vim: set foldmethod=marker :