Revision 7939f60c

b/test/cfgupgrade_unittest.py
39 39

  
40 40
def _RunUpgrade(path, dry_run, no_verify, ignore_hostname=True):
41 41
  cmd = [sys.executable, "%s/tools/cfgupgrade" % testutils.GetSourceDir(),
42
         "--debug", "--force", "--path=%s" % path]
42
         "--debug", "--force", "--path=%s" % path, "--confdir=%s" % path]
43 43

  
44 44
  if ignore_hostname:
45 45
    cmd.append("--ignore-hostname")
......
67 67
    self.confd_hmac_path = utils.PathJoin(self.tmpdir, "hmac.key")
68 68
    self.cds_path = utils.PathJoin(self.tmpdir, "cluster-domain-secret")
69 69
    self.ss_master_node_path = utils.PathJoin(self.tmpdir, "ssconf_master_node")
70
    self.file_storage_paths = utils.PathJoin(self.tmpdir, "file-storage-paths")
70 71

  
71 72
  def tearDown(self):
72 73
    shutil.rmtree(self.tmpdir)
......
133 134
    utils.WriteFile(self.config_path, data=serializer.DumpJson({}))
134 135
    self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True)
135 136

  
136
  def _TestSimpleUpgrade(self, from_version, dry_run):
137
  def _TestSimpleUpgrade(self, from_version, dry_run,
138
                         file_storage_dir=None,
139
                         shared_file_storage_dir=None):
140
    cluster = {}
141

  
142
    if file_storage_dir:
143
      cluster["file_storage_dir"] = file_storage_dir
144
    if shared_file_storage_dir:
145
      cluster["shared_file_storage_dir"] = shared_file_storage_dir
146

  
137 147
    cfg = {
138 148
      "version": from_version,
139
      "cluster": {},
149
      "cluster": cluster,
140 150
      "instances": {},
141 151
      }
142 152
    self._CreateValidConfigDir()
......
271 281
    for path in [self.rapi_users_path, self.rapi_users_path_pre24]:
272 282
      self.assertEqual(utils.ReadFile(path), "hello world\n")
273 283

  
284
  def testFileStoragePathsDryRun(self):
285
    self.assertFalse(os.path.exists(self.file_storage_paths))
286

  
287
    self._TestSimpleUpgrade(constants.BuildVersion(2, 6, 0), True,
288
                            file_storage_dir=self.tmpdir,
289
                            shared_file_storage_dir="/tmp")
290

  
291
    self.assertFalse(os.path.exists(self.file_storage_paths))
292

  
293
  def testFileStoragePathsBoth(self):
294
    self.assertFalse(os.path.exists(self.file_storage_paths))
295

  
296
    self._TestSimpleUpgrade(constants.BuildVersion(2, 6, 0), False,
297
                            file_storage_dir=self.tmpdir,
298
                            shared_file_storage_dir="/tmp")
299

  
300
    lines = utils.ReadFile(self.file_storage_paths).splitlines()
301
    self.assertTrue(lines.pop(0).startswith("# "))
302
    self.assertTrue(lines.pop(0).startswith("# cfgupgrade"))
303
    self.assertEqual(lines.pop(0), self.tmpdir)
304
    self.assertEqual(lines.pop(0), "/tmp")
305
    self.assertFalse(lines)
306
    self.assertEqual(os.stat(self.file_storage_paths).st_mode & 0777,
307
                     0600, msg="Wrong permissions")
308

  
309
  def testFileStoragePathsSharedOnly(self):
310
    self.assertFalse(os.path.exists(self.file_storage_paths))
311

  
312
    self._TestSimpleUpgrade(constants.BuildVersion(2, 5, 0), False,
313
                            file_storage_dir=None,
314
                            shared_file_storage_dir=self.tmpdir)
315

  
316
    lines = utils.ReadFile(self.file_storage_paths).splitlines()
317
    self.assertTrue(lines.pop(0).startswith("# "))
318
    self.assertTrue(lines.pop(0).startswith("# cfgupgrade"))
319
    self.assertEqual(lines.pop(0), self.tmpdir)
320
    self.assertFalse(lines)
321

  
274 322
  def testUpgradeFrom_2_0(self):
275 323
    self._TestSimpleUpgrade(constants.BuildVersion(2, 0, 0), False)
276 324

  
b/tools/cfgupgrade
32 32
import sys
33 33
import optparse
34 34
import logging
35
import time
36
from cStringIO import StringIO
35 37

  
36 38
from ganeti import constants
37 39
from ganeti import serializer
......
117 119
  parser.add_option("--path", help="Convert configuration in this"
118 120
                    " directory instead of '%s'" % pathutils.DATA_DIR,
119 121
                    default=pathutils.DATA_DIR, dest="data_dir")
122
  parser.add_option("--confdir",
123
                    help=("Use this directory instead of '%s'" %
124
                          pathutils.CONF_DIR),
125
                    default=pathutils.CONF_DIR, dest="conf_dir")
120 126
  parser.add_option("--no-verify",
121 127
                    help="Do not verify configuration after upgrade",
122 128
                    action="store_true", dest="no_verify", default=False)
......
137 143
  options.CDS_FILE = options.data_dir + "/cluster-domain-secret"
138 144
  options.SSCONF_MASTER_NODE = options.data_dir + "/ssconf_master_node"
139 145
  options.WATCHER_STATEFILE = options.data_dir + "/watcher.data"
146
  options.FILE_STORAGE_PATHS_FILE = options.conf_dir + "/file-storage-paths"
140 147

  
141 148
  SetupLogging()
142 149

  
......
164 171
    raise Error(("%s does not seem to be a Ganeti configuration"
165 172
                 " directory") % options.data_dir)
166 173

  
174
  if not os.path.isdir(options.conf_dir):
175
    raise Error("Not a directory: %s" % options.conf_dir)
176

  
167 177
  config_data = serializer.LoadJson(utils.ReadFile(options.CONFIG_DATA_PATH))
168 178

  
169 179
  try:
......
238 248
    if not options.dry_run:
239 249
      utils.RemoveFile(options.WATCHER_STATEFILE)
240 250

  
251
  # Write file storage paths
252
  if not os.path.exists(options.FILE_STORAGE_PATHS_FILE):
253
    cluster = config_data["cluster"]
254
    file_storage_dir = cluster.get("file_storage_dir")
255
    shared_file_storage_dir = cluster.get("shared_file_storage_dir")
256
    del cluster
257

  
258
    logging.info("Ganeti 2.7 and later only allow whitelisted directories"
259
                 " for file storage; writing existing configuration values"
260
                 " into '%s'",
261
                 options.FILE_STORAGE_PATHS_FILE)
262

  
263
    if file_storage_dir:
264
      logging.info("File storage directory: %s", file_storage_dir)
265
    if shared_file_storage_dir:
266
      logging.info("Shared file storage directory: %s",
267
                   shared_file_storage_dir)
268

  
269
    buf = StringIO()
270
    buf.write("# List automatically generated from configuration by\n")
271
    buf.write("# cfgupgrade at %s\n" % time.asctime())
272
    if file_storage_dir:
273
      buf.write("%s\n" % file_storage_dir)
274
    if shared_file_storage_dir:
275
      buf.write("%s\n" % shared_file_storage_dir)
276
    utils.WriteFile(file_name=options.FILE_STORAGE_PATHS_FILE,
277
                    data=buf.getvalue(),
278
                    mode=0600,
279
                    dry_run=options.dry_run,
280
                    backup=True)
281

  
241 282
  try:
242 283
    logging.info("Writing configuration file to %s", options.CONFIG_DATA_PATH)
243 284
    utils.WriteFile(file_name=options.CONFIG_DATA_PATH,

Also available in: Unified diff