Statistics
| Branch: | Tag: | Revision:

root / tools / cfgupgrade @ eda37a5a

History | View | Annotate | Download (4.1 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
# Main program
129
if __name__ == "__main__":
130
  program = os.path.basename(sys.argv[0])
131

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

    
145
  SetupLogging()
146

    
147
  # Option checking
148
  if args:
149
    cfg_file = args[0]
150
  else:
151
    raise Error("Configuration file not specified")
152

    
153
  if not options.force:
154
    usertext = ("%s MUST run on the master node. Is this the master"
155
                " node?" % program)
156
    if not cli.AskUser(usertext):
157
      sys.exit(1)
158

    
159
  config = ReadConfig(cfg_file)
160

    
161
  if options.verbose:
162
    import pprint
163
    print "Before upgrade:"
164
    pprint.pprint(config)
165
    print
166

    
167
  UpdateFromVersion2To3(config)
168

    
169
  if options.verbose:
170
    print "After upgrade:"
171
    pprint.pprint(config)
172
    print
173

    
174
  WriteConfig(cfg_file, config)
175

    
176
  print "The configuration file has been updated successfully. Please run"
177
  print "  gnt-cluster copyfile %s" % cfg_file
178
  print "now."
179

    
180
# vim: set foldmethod=marker :