Revision 9440aeab

b/lib/cmdlib.py
163 163
    return {}, [], []
164 164

  
165 165

  
166
def _AddHostToEtcHosts(hostname):
167
  """Wrapper around utils.SetEtcHostsEntry.
168

  
169
  """
170
  hi = utils.HostInfo(name=hostname)
171
  utils.SetEtcHostsEntry(constants.ETC_HOSTS, hi.ip, hi.name, [hi.ShortName()])
172

  
173

  
166 174
def _RemoveHostFromEtcHosts(hostname):
167
  """Wrapper around utils.RemoteEtcHostsEntry.
175
  """Wrapper around utils.RemoveEtcHostsEntry.
168 176

  
169 177
  """
170 178
  hi = utils.HostInfo(name=hostname)
......
574 582
      f.close()
575 583
    sshkey = sshline.split(" ")[1]
576 584

  
577
    hi = utils.HostInfo(name=hostname.name)
578
    utils.AddEtcHostsEntry(constants.ETC_HOSTS, hostname.name, hi.ip)
579
    utils.AddEtcHostsEntry(constants.ETC_HOSTS, hi.ShortName(), hi.ip)
580
    del hi
585
    _AddHostToEtcHosts(hostname.name)
581 586

  
582 587
    _UpdateKnownHosts(hostname.name, hostname.ip, sshkey)
583 588

  
......
1484 1489
      raise errors.OpExecError("Cannot transfer ssh keys to the new node")
1485 1490

  
1486 1491
    # Add node to our /etc/hosts, and add key to known_hosts
1487
    hi = utils.HostInfo(name=new_node.name)
1488
    utils.AddEtcHostsEntry(constants.ETC_HOSTS, new_node.name, hi.ip)
1489
    utils.AddEtcHostsEntry(constants.ETC_HOSTS, hi.ShortName(), hi.ip)
1490
    del hi
1492
    _AddHostToEtcHosts(new_node.name)
1491 1493

  
1492 1494
    _UpdateKnownHosts(new_node.name, new_node.primary_ip,
1493 1495
                      self.cfg.GetHostKey())
b/lib/utils.py
752 752
    raise
753 753

  
754 754

  
755
def AddEtcHostsEntry(file_name, hostname, ip):
756
  """Adds an IP address and hostname to /etc/hosts.
755
def SetEtcHostsEntry(file_name, ip, hostname, aliases):
756
  """Sets the name of an IP address and hostname in /etc/hosts.
757 757

  
758 758
  """
759
  f = open(file_name, 'a+')
759
  fd, tmpname = tempfile.mkstemp(dir=os.path.dirname(file_name))
760 760
  try:
761
    nl = True
762
    for line in f:
763
      fields = line.split()
764
      if len(fields) < 2 or fields[0].startswith('#'):
765
        continue
766
      if fields[0] == ip and hostname in fields[1:]:
767
        break
768
      nl = line.endswith('\n')
769
    else:
770
      if not nl:
771
        f.write("\n")
772
      f.write(ip)
773
      f.write(' ')
774
      f.write(hostname)
775
      f.write("\n")
776
      f.flush()
777
  finally:
778
    f.close()
761
    out = os.fdopen(fd, 'w')
762
    try:
763
      f = open(file_name, 'r')
764
      try:
765
        written = False
766
        for line in f:
767
          fields = line.split()
768
          if not fields[0].startswith('#') and ip == fields[0]:
769
            continue
770
          out.write(line)
771

  
772
        out.write("%s %s" % (ip, hostname))
773
        if aliases:
774
          out.write(" %s" % ' '.join(aliases))
775
        out.write('\n')
776

  
777
        out.flush()
778
        os.rename(tmpname, file_name)
779
      finally:
780
        f.close()
781
    finally:
782
      out.close()
783
  except:
784
    RemoveFile(tmpname)
785
    raise
779 786

  
780 787

  
781 788
def RemoveEtcHostsEntry(file_name, hostname):
782 789
  """Removes a hostname from /etc/hosts.
783 790

  
784
  IP addresses without hostnames are removed from the file.
791
  IP addresses without names are removed from the file.
785 792
  """
786 793
  fd, tmpname = tempfile.mkstemp(dir=os.path.dirname(file_name))
787 794
  try:
......
797 804
              while hostname in names:
798 805
                names.remove(hostname)
799 806
              if names:
800
                out.write(fields[0])
801
                out.write(' ')
802
                out.write(' '.join(names))
807
                out.write("%s %s\n" % (fields[0], ' '.join(names)))
803 808
              continue
804 809

  
805 810
          out.write(line)
b/test/ganeti.utils_unittest.py
38 38
     RemoveFile, CheckDict, MatchNameComponent, FormatUnit, \
39 39
     ParseUnit, AddAuthorizedKey, RemoveAuthorizedKey, \
40 40
     ShellQuote, ShellQuoteArgs, TcpPing, ListVisibleFiles, \
41
     AddEtcHostsEntry, RemoveEtcHostsEntry
41
     SetEtcHostsEntry, RemoveEtcHostsEntry
42 42
from ganeti.errors import LockError, UnitParseError
43 43

  
44 44

  
......
447 447

  
448 448
    return tmpname
449 449

  
450
  def testAddingNewIp(self):
450
  def testSettingNewIp(self):
451 451
    tmpname = self.writeTestFile()
452 452
    try:
453
      AddEtcHostsEntry(tmpname, 'myhost.domain.tld', '1.2.3.4')
453
      SetEtcHostsEntry(tmpname, '1.2.3.4', 'myhost.domain.tld', ['myhost'])
454 454

  
455 455
      f = open(tmpname, 'r')
456 456
      try:
457 457
        self.assertEqual(md5.new(f.read(8192)).hexdigest(),
458
                         '00e0e88250482e7449743c89a49e9349')
458
                         '410c141dcafffd505f662a41713d2eab')
459 459
      finally:
460 460
        f.close()
461 461
    finally:
462 462
      os.unlink(tmpname)
463 463

  
464
  def testAddingExistingIp(self):
464
  def testSettingExistingIp(self):
465 465
    tmpname = self.writeTestFile()
466 466
    try:
467
      AddEtcHostsEntry(tmpname, 'myhost.domain.tld', '192.168.1.1')
467
      SetEtcHostsEntry(tmpname, '192.168.1.1', 'myhost.domain.tld', ['myhost'])
468 468

  
469 469
      f = open(tmpname, 'r')
470 470
      try:
471 471
        self.assertEqual(md5.new(f.read(8192)).hexdigest(),
472
                         '4dc04c0acdd247175e0b980c6beea822')
472
                         'bbf60c542dec949f3968b59522ec0d7b')
473 473
      finally:
474 474
        f.close()
475 475
    finally:
......
483 483
      f = open(tmpname, 'r')
484 484
      try:
485 485
        self.assertEqual(md5.new(f.read(8192)).hexdigest(),
486
                         '7d1e7a559eedbc25e0dff67d33ccac84')
486
                         '8b09207a23709d60240674601a3548b2')
487 487
      finally:
488 488
        f.close()
489 489
    finally:
......
517 517
    finally:
518 518
      os.unlink(tmpname)
519 519

  
520
  def testRemovingAlias(self):
521
    tmpname = self.writeTestFile()
522
    try:
523
      RemoveEtcHostsEntry(tmpname, 'gw')
524

  
525
      f = open(tmpname, 'r')
526
      try:
527
        self.assertEqual(md5.new(f.read(8192)).hexdigest(),
528
                         '156dd3980a17b2ef934e2d0bf670aca2')
529
      finally:
530
        f.close()
531
    finally:
532
      os.unlink(tmpname)
533

  
520 534

  
521 535
class TestShellQuoting(unittest.TestCase):
522 536
  """Test case for shell quoting functions"""

Also available in: Unified diff