Statistics
| Branch: | Tag: | Revision:

root / tools / cfgupgrade @ fdb85e3d

History | View | Annotate | Download (12.7 kB)

1 0006af7d Michael Hanselmann
#!/usr/bin/python
2 0006af7d Michael Hanselmann
#
3 0006af7d Michael Hanselmann
4 fdb85e3d Bernardo Dal Seno
# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 a421fdeb Iustin Pop
This code handles only the types supported by simplejson. As an
25 a421fdeb Iustin Pop
example, 'set' 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 eda37a5a Michael Hanselmann
import logging
35 7939f60c Michael Hanselmann
import time
36 7939f60c Michael Hanselmann
from cStringIO import StringIO
37 0006af7d Michael Hanselmann
38 95e4a814 Michael Hanselmann
from ganeti import constants
39 95e4a814 Michael Hanselmann
from ganeti import serializer
40 319856a9 Michael Hanselmann
from ganeti import utils
41 f97c7901 Michael Hanselmann
from ganeti import cli
42 a421fdeb Iustin Pop
from ganeti import bootstrap
43 ac4d25b6 Iustin Pop
from ganeti import config
44 011974df Michael Hanselmann
from ganeti import netutils
45 09bf5d24 Michael Hanselmann
from ganeti import pathutils
46 0006af7d Michael Hanselmann
47 0006af7d Michael Hanselmann
48 319856a9 Michael Hanselmann
options = None
49 319856a9 Michael Hanselmann
args = None
50 0006af7d Michael Hanselmann
51 6f285030 Iustin Pop
52 93fd9bb1 Iustin Pop
#: Target major version we will upgrade to
53 93fd9bb1 Iustin Pop
TARGET_MAJOR = 2
54 93fd9bb1 Iustin Pop
#: Target minor version we will upgrade to
55 b830193c Guido Trotter
TARGET_MINOR = 7
56 93fd9bb1 Iustin Pop
57 93fd9bb1 Iustin Pop
58 319856a9 Michael Hanselmann
class Error(Exception):
59 319856a9 Michael Hanselmann
  """Generic exception"""
60 319856a9 Michael Hanselmann
  pass
61 0006af7d Michael Hanselmann
62 0006af7d Michael Hanselmann
63 eda37a5a Michael Hanselmann
def SetupLogging():
64 eda37a5a Michael Hanselmann
  """Configures the logging module.
65 eda37a5a Michael Hanselmann
66 eda37a5a Michael Hanselmann
  """
67 eda37a5a Michael Hanselmann
  formatter = logging.Formatter("%(asctime)s: %(message)s")
68 eda37a5a Michael Hanselmann
69 eda37a5a Michael Hanselmann
  stderr_handler = logging.StreamHandler()
70 eda37a5a Michael Hanselmann
  stderr_handler.setFormatter(formatter)
71 eda37a5a Michael Hanselmann
  if options.debug:
72 eda37a5a Michael Hanselmann
    stderr_handler.setLevel(logging.NOTSET)
73 eda37a5a Michael Hanselmann
  elif options.verbose:
74 eda37a5a Michael Hanselmann
    stderr_handler.setLevel(logging.INFO)
75 eda37a5a Michael Hanselmann
  else:
76 011974df Michael Hanselmann
    stderr_handler.setLevel(logging.WARNING)
77 eda37a5a Michael Hanselmann
78 eda37a5a Michael Hanselmann
  root_logger = logging.getLogger("")
79 eda37a5a Michael Hanselmann
  root_logger.setLevel(logging.NOTSET)
80 eda37a5a Michael Hanselmann
  root_logger.addHandler(stderr_handler)
81 eda37a5a Michael Hanselmann
82 eda37a5a Michael Hanselmann
83 011974df Michael Hanselmann
def CheckHostname(path):
84 011974df Michael Hanselmann
  """Ensures hostname matches ssconf value.
85 011974df Michael Hanselmann
86 011974df Michael Hanselmann
  @param path: Path to ssconf file
87 011974df Michael Hanselmann
88 011974df Michael Hanselmann
  """
89 011974df Michael Hanselmann
  ssconf_master_node = utils.ReadOneLineFile(path)
90 011974df Michael Hanselmann
  hostname = netutils.GetHostname().name
91 011974df Michael Hanselmann
92 011974df Michael Hanselmann
  if ssconf_master_node == hostname:
93 011974df Michael Hanselmann
    return True
94 011974df Michael Hanselmann
95 011974df Michael Hanselmann
  logging.warning("Warning: ssconf says master node is '%s', but this"
96 011974df Michael Hanselmann
                  " machine's name is '%s'; this tool must be run on"
97 011974df Michael Hanselmann
                  " the master node", ssconf_master_node, hostname)
98 011974df Michael Hanselmann
  return False
99 011974df Michael Hanselmann
100 3c286190 Dimitris Aragiorgis
101 58bf877f Dimitris Aragiorgis
def UpgradeNetworks(config_data):
102 58bf877f Dimitris Aragiorgis
  networks = config_data.get("networks", None)
103 58bf877f Dimitris Aragiorgis
  if not networks:
104 58bf877f Dimitris Aragiorgis
    config_data["networks"] = {}
105 58bf877f Dimitris Aragiorgis
106 58bf877f Dimitris Aragiorgis
107 58bf877f Dimitris Aragiorgis
def UpgradeGroups(config_data):
108 58bf877f Dimitris Aragiorgis
  for group in config_data["nodegroups"].values():
109 58bf877f Dimitris Aragiorgis
    networks = group.get("networks", None)
110 58bf877f Dimitris Aragiorgis
    if not networks:
111 58bf877f Dimitris Aragiorgis
      group["networks"] = {}
112 58bf877f Dimitris Aragiorgis
113 011974df Michael Hanselmann
114 f032d55c Dimitris Aragiorgis
def UpgradeInstances(config_data):
115 f032d55c Dimitris Aragiorgis
  network2uuid = dict((n["name"], n["uuid"])
116 f032d55c Dimitris Aragiorgis
                      for n in config_data["networks"].values())
117 f032d55c Dimitris Aragiorgis
  for inst in config_data["instances"].values():
118 f032d55c Dimitris Aragiorgis
    for nic in inst["nics"]:
119 f032d55c Dimitris Aragiorgis
      name = nic.get("network", None)
120 f032d55c Dimitris Aragiorgis
      if name:
121 f032d55c Dimitris Aragiorgis
        uuid = network2uuid.get(name, None)
122 f032d55c Dimitris Aragiorgis
        if uuid:
123 f032d55c Dimitris Aragiorgis
          print("NIC with network name %s found."
124 f032d55c Dimitris Aragiorgis
                " Substituting with uuid %s." % (name, uuid))
125 f032d55c Dimitris Aragiorgis
          nic["network"] = uuid
126 f032d55c Dimitris Aragiorgis
127 f032d55c Dimitris Aragiorgis
128 6d691282 Michael Hanselmann
def main():
129 6d691282 Michael Hanselmann
  """Main program.
130 6d691282 Michael Hanselmann
131 6d691282 Michael Hanselmann
  """
132 b459a848 Andrea Spadaccini
  global options, args # pylint: disable=W0603
133 6d691282 Michael Hanselmann
134 0006af7d Michael Hanselmann
  # Option parsing
135 95e4a814 Michael Hanselmann
  parser = optparse.OptionParser(usage="%prog [--debug|--verbose] [--force]")
136 3ccb3a64 Michael Hanselmann
  parser.add_option("--dry-run", dest="dry_run",
137 60edf71e Michael Hanselmann
                    action="store_true",
138 f4bc1f2c Michael Hanselmann
                    help="Try to do the conversion, but don't write"
139 f4bc1f2c Michael Hanselmann
                         " output file")
140 f97c7901 Michael Hanselmann
  parser.add_option(cli.FORCE_OPT)
141 eda37a5a Michael Hanselmann
  parser.add_option(cli.DEBUG_OPT)
142 9cdb9578 Iustin Pop
  parser.add_option(cli.VERBOSE_OPT)
143 011974df Michael Hanselmann
  parser.add_option("--ignore-hostname", dest="ignore_hostname",
144 011974df Michael Hanselmann
                    action="store_true", default=False,
145 011974df Michael Hanselmann
                    help="Don't abort if hostname doesn't match")
146 3ccb3a64 Michael Hanselmann
  parser.add_option("--path", help="Convert configuration in this"
147 09bf5d24 Michael Hanselmann
                    " directory instead of '%s'" % pathutils.DATA_DIR,
148 09bf5d24 Michael Hanselmann
                    default=pathutils.DATA_DIR, dest="data_dir")
149 7939f60c Michael Hanselmann
  parser.add_option("--confdir",
150 7939f60c Michael Hanselmann
                    help=("Use this directory instead of '%s'" %
151 7939f60c Michael Hanselmann
                          pathutils.CONF_DIR),
152 7939f60c Michael Hanselmann
                    default=pathutils.CONF_DIR, dest="conf_dir")
153 02e1292d Michael Hanselmann
  parser.add_option("--no-verify",
154 02e1292d Michael Hanselmann
                    help="Do not verify configuration after upgrade",
155 02e1292d Michael Hanselmann
                    action="store_true", dest="no_verify", default=False)
156 0006af7d Michael Hanselmann
  (options, args) = parser.parse_args()
157 0006af7d Michael Hanselmann
158 ac4d25b6 Iustin Pop
  # We need to keep filenames locally because they might be renamed between
159 ac4d25b6 Iustin Pop
  # versions.
160 0cddd44d Iustin Pop
  options.data_dir = os.path.abspath(options.data_dir)
161 ac4d25b6 Iustin Pop
  options.CONFIG_DATA_PATH = options.data_dir + "/config.data"
162 ac4d25b6 Iustin Pop
  options.SERVER_PEM_PATH = options.data_dir + "/server.pem"
163 ac4d25b6 Iustin Pop
  options.KNOWN_HOSTS_PATH = options.data_dir + "/known_hosts"
164 ac4d25b6 Iustin Pop
  options.RAPI_CERT_FILE = options.data_dir + "/rapi.pem"
165 b6267745 Andrea Spadaccini
  options.SPICE_CERT_FILE = options.data_dir + "/spice.pem"
166 b6267745 Andrea Spadaccini
  options.SPICE_CACERT_FILE = options.data_dir + "/spice-ca.pem"
167 fdd9ac5b Michael Hanselmann
  options.RAPI_USERS_FILE = options.data_dir + "/rapi/users"
168 fdd9ac5b Michael Hanselmann
  options.RAPI_USERS_FILE_PRE24 = options.data_dir + "/rapi_users"
169 6b7d5878 Michael Hanselmann
  options.CONFD_HMAC_KEY = options.data_dir + "/hmac.key"
170 fc0726b9 Michael Hanselmann
  options.CDS_FILE = options.data_dir + "/cluster-domain-secret"
171 011974df Michael Hanselmann
  options.SSCONF_MASTER_NODE = options.data_dir + "/ssconf_master_node"
172 a292020f Michael Hanselmann
  options.WATCHER_STATEFILE = options.data_dir + "/watcher.data"
173 7939f60c Michael Hanselmann
  options.FILE_STORAGE_PATHS_FILE = options.conf_dir + "/file-storage-paths"
174 ac4d25b6 Iustin Pop
175 eda37a5a Michael Hanselmann
  SetupLogging()
176 eda37a5a Michael Hanselmann
177 0006af7d Michael Hanselmann
  # Option checking
178 0006af7d Michael Hanselmann
  if args:
179 95e4a814 Michael Hanselmann
    raise Error("No arguments expected")
180 0006af7d Michael Hanselmann
181 011974df Michael Hanselmann
  # Check master name
182 011974df Michael Hanselmann
  if not (CheckHostname(options.SSCONF_MASTER_NODE) or options.ignore_hostname):
183 011974df Michael Hanselmann
    logging.error("Aborting due to hostname mismatch")
184 011974df Michael Hanselmann
    sys.exit(constants.EXIT_FAILURE)
185 011974df Michael Hanselmann
186 319856a9 Michael Hanselmann
  if not options.force:
187 011974df Michael Hanselmann
    usertext = ("Please make sure you have read the upgrade notes for"
188 011974df Michael Hanselmann
                " Ganeti %s (available in the UPGRADE file and included"
189 011974df Michael Hanselmann
                " in other documentation formats). Continue with upgrading"
190 011974df Michael Hanselmann
                " configuration?" % constants.RELEASE_VERSION)
191 f97c7901 Michael Hanselmann
    if not cli.AskUser(usertext):
192 a9221f09 Michael Hanselmann
      sys.exit(constants.EXIT_FAILURE)
193 319856a9 Michael Hanselmann
194 95e4a814 Michael Hanselmann
  # Check whether it's a Ganeti configuration directory
195 ac4d25b6 Iustin Pop
  if not (os.path.isfile(options.CONFIG_DATA_PATH) and
196 30acff6c Michael Hanselmann
          os.path.isfile(options.SERVER_PEM_PATH) and
197 ac4d25b6 Iustin Pop
          os.path.isfile(options.KNOWN_HOSTS_PATH)):
198 a9221f09 Michael Hanselmann
    raise Error(("%s does not seem to be a Ganeti configuration"
199 ac4d25b6 Iustin Pop
                 " directory") % options.data_dir)
200 95e4a814 Michael Hanselmann
201 7939f60c Michael Hanselmann
  if not os.path.isdir(options.conf_dir):
202 7939f60c Michael Hanselmann
    raise Error("Not a directory: %s" % options.conf_dir)
203 7939f60c Michael Hanselmann
204 11c31f5c Michael Hanselmann
  config_data = serializer.LoadJson(utils.ReadFile(options.CONFIG_DATA_PATH))
205 a421fdeb Iustin Pop
206 11c31f5c Michael Hanselmann
  try:
207 11c31f5c Michael Hanselmann
    config_version = config_data["version"]
208 11c31f5c Michael Hanselmann
  except KeyError:
209 11c31f5c Michael Hanselmann
    raise Error("Unable to determine configuration version")
210 0006af7d Michael Hanselmann
211 11c31f5c Michael Hanselmann
  (config_major, config_minor, config_revision) = \
212 11c31f5c Michael Hanselmann
    constants.SplitVersion(config_version)
213 319856a9 Michael Hanselmann
214 11c31f5c Michael Hanselmann
  logging.info("Found configuration version %s (%d.%d.%d)",
215 11c31f5c Michael Hanselmann
               config_version, config_major, config_minor, config_revision)
216 319856a9 Michael Hanselmann
217 11c31f5c Michael Hanselmann
  if "config_version" in config_data["cluster"]:
218 11c31f5c Michael Hanselmann
    raise Error("Inconsistent configuration: found config_version in"
219 11c31f5c Michael Hanselmann
                " configuration file")
220 95e4a814 Michael Hanselmann
221 b830193c Guido Trotter
  # Upgrade from 2.{0..6} to 2.7
222 b830193c Guido Trotter
  if config_major == 2 and config_minor in (0, 1, 2, 3, 4, 5, 6):
223 aeb0c953 Michael Hanselmann
    if config_revision != 0:
224 a9221f09 Michael Hanselmann
      logging.warning("Config revision is %s, not 0", config_revision)
225 aeb0c953 Michael Hanselmann
226 93fd9bb1 Iustin Pop
    config_data["version"] = constants.BuildVersion(TARGET_MAJOR,
227 93fd9bb1 Iustin Pop
                                                    TARGET_MINOR, 0)
228 a9221f09 Michael Hanselmann
229 904910c4 Iustin Pop
    if "instances" not in config_data:
230 904910c4 Iustin Pop
      raise Error("Can't find the 'instances' key in the configuration!")
231 904910c4 Iustin Pop
    for instance, iobj in config_data["instances"].items():
232 904910c4 Iustin Pop
      if "disks" not in iobj:
233 904910c4 Iustin Pop
        raise Error("Instance '%s' doesn't have a disks entry?!" % instance)
234 904910c4 Iustin Pop
      disks = iobj["disks"]
235 904910c4 Iustin Pop
      for idx, dobj in enumerate(disks):
236 904910c4 Iustin Pop
        expected = "disk/%s" % idx
237 904910c4 Iustin Pop
        current = dobj.get("iv_name", "")
238 904910c4 Iustin Pop
        if current != expected:
239 904910c4 Iustin Pop
          logging.warning("Updating iv_name for instance %s/disk %s"
240 904910c4 Iustin Pop
                          " from '%s' to '%s'",
241 904910c4 Iustin Pop
                          instance, idx, current, expected)
242 904910c4 Iustin Pop
          dobj["iv_name"] = expected
243 904910c4 Iustin Pop
244 93fd9bb1 Iustin Pop
  elif config_major == TARGET_MAJOR and config_minor == TARGET_MINOR:
245 a9221f09 Michael Hanselmann
    logging.info("No changes necessary")
246 a9221f09 Michael Hanselmann
247 a9221f09 Michael Hanselmann
  else:
248 a9221f09 Michael Hanselmann
    raise Error("Configuration version %d.%d.%d not supported by this tool" %
249 a9221f09 Michael Hanselmann
                (config_major, config_minor, config_revision))
250 aeb0c953 Michael Hanselmann
251 87c80992 Michael Hanselmann
  if (os.path.isfile(options.RAPI_USERS_FILE_PRE24) and
252 87c80992 Michael Hanselmann
      not os.path.islink(options.RAPI_USERS_FILE_PRE24)):
253 87c80992 Michael Hanselmann
    if os.path.exists(options.RAPI_USERS_FILE):
254 87c80992 Michael Hanselmann
      raise Error("Found pre-2.4 RAPI users file at %s, but another file"
255 87c80992 Michael Hanselmann
                  " already exists at %s" %
256 87c80992 Michael Hanselmann
                  (options.RAPI_USERS_FILE_PRE24, options.RAPI_USERS_FILE))
257 fdd9ac5b Michael Hanselmann
    logging.info("Found pre-2.4 RAPI users file at %s, renaming to %s",
258 fdd9ac5b Michael Hanselmann
                 options.RAPI_USERS_FILE_PRE24, options.RAPI_USERS_FILE)
259 87c80992 Michael Hanselmann
    if not options.dry_run:
260 87c80992 Michael Hanselmann
      utils.RenameFile(options.RAPI_USERS_FILE_PRE24, options.RAPI_USERS_FILE,
261 87c80992 Michael Hanselmann
                       mkdir=True, mkdir_mode=0750)
262 fdd9ac5b Michael Hanselmann
263 fdd9ac5b Michael Hanselmann
  # Create a symlink for RAPI users file
264 87c80992 Michael Hanselmann
  if (not (os.path.islink(options.RAPI_USERS_FILE_PRE24) or
265 87c80992 Michael Hanselmann
           os.path.isfile(options.RAPI_USERS_FILE_PRE24)) and
266 87c80992 Michael Hanselmann
      os.path.isfile(options.RAPI_USERS_FILE)):
267 fdd9ac5b Michael Hanselmann
    logging.info("Creating symlink from %s to %s",
268 fdd9ac5b Michael Hanselmann
                 options.RAPI_USERS_FILE_PRE24, options.RAPI_USERS_FILE)
269 87c80992 Michael Hanselmann
    if not options.dry_run:
270 87c80992 Michael Hanselmann
      os.symlink(options.RAPI_USERS_FILE, options.RAPI_USERS_FILE_PRE24)
271 fdd9ac5b Michael Hanselmann
272 a292020f Michael Hanselmann
  # Remove old watcher state file if it exists
273 a292020f Michael Hanselmann
  if os.path.exists(options.WATCHER_STATEFILE):
274 a292020f Michael Hanselmann
    logging.info("Removing watcher state file %s", options.WATCHER_STATEFILE)
275 a292020f Michael Hanselmann
    if not options.dry_run:
276 a292020f Michael Hanselmann
      utils.RemoveFile(options.WATCHER_STATEFILE)
277 a292020f Michael Hanselmann
278 7939f60c Michael Hanselmann
  # Write file storage paths
279 7939f60c Michael Hanselmann
  if not os.path.exists(options.FILE_STORAGE_PATHS_FILE):
280 7939f60c Michael Hanselmann
    cluster = config_data["cluster"]
281 7939f60c Michael Hanselmann
    file_storage_dir = cluster.get("file_storage_dir")
282 7939f60c Michael Hanselmann
    shared_file_storage_dir = cluster.get("shared_file_storage_dir")
283 7939f60c Michael Hanselmann
    del cluster
284 7939f60c Michael Hanselmann
285 7939f60c Michael Hanselmann
    logging.info("Ganeti 2.7 and later only allow whitelisted directories"
286 7939f60c Michael Hanselmann
                 " for file storage; writing existing configuration values"
287 7939f60c Michael Hanselmann
                 " into '%s'",
288 7939f60c Michael Hanselmann
                 options.FILE_STORAGE_PATHS_FILE)
289 7939f60c Michael Hanselmann
290 7939f60c Michael Hanselmann
    if file_storage_dir:
291 7939f60c Michael Hanselmann
      logging.info("File storage directory: %s", file_storage_dir)
292 7939f60c Michael Hanselmann
    if shared_file_storage_dir:
293 7939f60c Michael Hanselmann
      logging.info("Shared file storage directory: %s",
294 7939f60c Michael Hanselmann
                   shared_file_storage_dir)
295 7939f60c Michael Hanselmann
296 7939f60c Michael Hanselmann
    buf = StringIO()
297 7939f60c Michael Hanselmann
    buf.write("# List automatically generated from configuration by\n")
298 7939f60c Michael Hanselmann
    buf.write("# cfgupgrade at %s\n" % time.asctime())
299 7939f60c Michael Hanselmann
    if file_storage_dir:
300 7939f60c Michael Hanselmann
      buf.write("%s\n" % file_storage_dir)
301 7939f60c Michael Hanselmann
    if shared_file_storage_dir:
302 7939f60c Michael Hanselmann
      buf.write("%s\n" % shared_file_storage_dir)
303 7939f60c Michael Hanselmann
    utils.WriteFile(file_name=options.FILE_STORAGE_PATHS_FILE,
304 7939f60c Michael Hanselmann
                    data=buf.getvalue(),
305 7939f60c Michael Hanselmann
                    mode=0600,
306 7939f60c Michael Hanselmann
                    dry_run=options.dry_run,
307 7939f60c Michael Hanselmann
                    backup=True)
308 7939f60c Michael Hanselmann
309 58bf877f Dimitris Aragiorgis
  UpgradeNetworks(config_data)
310 58bf877f Dimitris Aragiorgis
  UpgradeGroups(config_data)
311 f032d55c Dimitris Aragiorgis
  UpgradeInstances(config_data)
312 58bf877f Dimitris Aragiorgis
313 11c31f5c Michael Hanselmann
  try:
314 11c31f5c Michael Hanselmann
    logging.info("Writing configuration file to %s", options.CONFIG_DATA_PATH)
315 11c31f5c Michael Hanselmann
    utils.WriteFile(file_name=options.CONFIG_DATA_PATH,
316 11c31f5c Michael Hanselmann
                    data=serializer.DumpJson(config_data),
317 11c31f5c Michael Hanselmann
                    mode=0600,
318 11c31f5c Michael Hanselmann
                    dry_run=options.dry_run,
319 11c31f5c Michael Hanselmann
                    backup=True)
320 a421fdeb Iustin Pop
321 a421fdeb Iustin Pop
    if not options.dry_run:
322 5ae4945a Iustin Pop
      bootstrap.GenerateClusterCrypto(
323 5ae4945a Iustin Pop
        False, False, False, False, False,
324 5ae4945a Iustin Pop
        nodecert_file=options.SERVER_PEM_PATH,
325 5ae4945a Iustin Pop
        rapicert_file=options.RAPI_CERT_FILE,
326 5ae4945a Iustin Pop
        spicecert_file=options.SPICE_CERT_FILE,
327 5ae4945a Iustin Pop
        spicecacert_file=options.SPICE_CACERT_FILE,
328 5ae4945a Iustin Pop
        hmackey_file=options.CONFD_HMAC_KEY,
329 5ae4945a Iustin Pop
        cds_file=options.CDS_FILE)
330 aeb0c953 Michael Hanselmann
331 a9221f09 Michael Hanselmann
  except Exception:
332 11c31f5c Michael Hanselmann
    logging.critical("Writing configuration failed. It is probably in an"
333 95e4a814 Michael Hanselmann
                     " inconsistent state and needs manual intervention.")
334 95e4a814 Michael Hanselmann
    raise
335 0006af7d Michael Hanselmann
336 ac4d25b6 Iustin Pop
  # test loading the config file
337 fdb85e3d Bernardo Dal Seno
  all_ok = True
338 02e1292d Michael Hanselmann
  if not (options.dry_run or options.no_verify):
339 ac4d25b6 Iustin Pop
    logging.info("Testing the new config file...")
340 ac4d25b6 Iustin Pop
    cfg = config.ConfigWriter(cfg_file=options.CONFIG_DATA_PATH,
341 959b6fe5 Apollon Oikonomopoulos
                              accept_foreign=options.ignore_hostname,
342 ac4d25b6 Iustin Pop
                              offline=True)
343 ac4d25b6 Iustin Pop
    # if we reached this, it's all fine
344 ac4d25b6 Iustin Pop
    vrfy = cfg.VerifyConfig()
345 ac4d25b6 Iustin Pop
    if vrfy:
346 ac4d25b6 Iustin Pop
      logging.error("Errors after conversion:")
347 ac4d25b6 Iustin Pop
      for item in vrfy:
348 07b8a2b5 Iustin Pop
        logging.error(" - %s", item)
349 fdb85e3d Bernardo Dal Seno
      all_ok = False
350 fdb85e3d Bernardo Dal Seno
    else:
351 fdb85e3d Bernardo Dal Seno
      logging.info("File loaded successfully after upgrading")
352 ac4d25b6 Iustin Pop
    del cfg
353 ac4d25b6 Iustin Pop
354 fdb85e3d Bernardo Dal Seno
  if all_ok:
355 fdb85e3d Bernardo Dal Seno
    cli.ToStderr("Configuration successfully upgraded to version %s.",
356 fdb85e3d Bernardo Dal Seno
                 constants.RELEASE_VERSION)
357 fdb85e3d Bernardo Dal Seno
  else:
358 fdb85e3d Bernardo Dal Seno
    cli.ToStderr("Configuration upgraded to version %s, but there are errors."
359 fdb85e3d Bernardo Dal Seno
                 "\nPlease review the file.", constants.RELEASE_VERSION)
360 66a66fa7 Michael Hanselmann
361 6d691282 Michael Hanselmann
362 6d691282 Michael Hanselmann
if __name__ == "__main__":
363 6d691282 Michael Hanselmann
  main()