Revision 899d2a81

b/lib/utils.py
20 20

  
21 21

  
22 22
"""Ganeti small utilities
23

  
23 24
"""
24 25

  
25 26

  
......
745 746
    raise
746 747

  
747 748

  
749
def AddEtcHostsEntry(file_name, hostname, ip):
750
  """
751

  
752
  """
753
  f = open(file_name, 'a+')
754
  try:
755
    nl = True
756
    for line in f:
757
      fields = line.split()
758
      if len(fields) < 2 or fields[0].startswith('#'):
759
        continue
760
      if fields[0] == ip and hostname in fields[1:]:
761
        break
762
      nl = line.endswith('\n')
763
    else:
764
      if not nl:
765
        f.write("\n")
766
      f.write(ip)
767
      f.write(' ')
768
      f.write(hostname)
769
      f.write("\n")
770
      f.flush()
771
  finally:
772
    f.close()
773

  
774

  
775
def RemoveEtcHostsEntry(file_name, hostname):
776
  """
777

  
778
  """
779
  fd, tmpname = tempfile.mkstemp(dir=os.path.dirname(file_name))
780
  try:
781
    out = os.fdopen(fd, 'w')
782
    try:
783
      f = open(file_name, 'r')
784
      try:
785
        for line in f:
786
          fields = line.split()
787
          if len(fields) > 1 and not fields[0].startswith('#'):
788
            names = fields[1:]
789
            if hostname in names:
790
              while hostname in names:
791
                names.remove(hostname)
792
              if names:
793
                out.write(fields[0])
794
                out.write(' ')
795
                out.write(' '.join(names))
796
              continue
797

  
798
          out.write(line)
799

  
800
        out.flush()
801
        os.rename(tmpname, file_name)
802
      finally:
803
        f.close()
804
    finally:
805
      out.close()
806
  except:
807
    RemoveFile(tmpname)
808
    raise
809

  
810

  
748 811
def CreateBackup(file_name):
749 812
  """Creates a backup of a file.
750 813

  
b/test/ganeti.utils_unittest.py
37 37
from ganeti.utils import IsProcessAlive, Lock, Unlock, RunCmd, \
38 38
     RemoveFile, CheckDict, MatchNameComponent, FormatUnit, \
39 39
     ParseUnit, AddAuthorizedKey, RemoveAuthorizedKey, \
40
     ShellQuote, ShellQuoteArgs, TcpPing, ListVisibleFiles
40
     ShellQuote, ShellQuoteArgs, TcpPing, ListVisibleFiles, \
41
     AddEtcHostsEntry, RemoveEtcHostsEntry
41 42
from ganeti.errors import LockError, UnitParseError
42 43

  
43 44

  
......
431 432
      os.unlink(tmpname)
432 433

  
433 434

  
435
class TestEtcHosts(unittest.TestCase):
436
  """Test functions modifying /etc/hosts"""
437

  
438
  def writeTestFile(self):
439
    (fd, tmpname) = tempfile.mkstemp(prefix = 'ganeti-test')
440
    f = os.fdopen(fd, 'w')
441
    try:
442
      f.write('# This is a test file for /etc/hosts\n')
443
      f.write('127.0.0.1\tlocalhost\n')
444
      f.write('192.168.1.1 router gw\n')
445
    finally:
446
      f.close()
447

  
448
    return tmpname
449

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

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

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

  
469
      f = open(tmpname, 'r')
470
      try:
471
        self.assertEqual(md5.new(f.read(8192)).hexdigest(),
472
                         '4dc04c0acdd247175e0b980c6beea822')
473
      finally:
474
        f.close()
475
    finally:
476
      os.unlink(tmpname)
477

  
478
  def testRemovingExistingHost(self):
479
    tmpname = self.writeTestFile()
480
    try:
481
      RemoveEtcHostsEntry(tmpname, 'router')
482

  
483
      f = open(tmpname, 'r')
484
      try:
485
        self.assertEqual(md5.new(f.read(8192)).hexdigest(),
486
                         '7d1e7a559eedbc25e0dff67d33ccac84')
487
      finally:
488
        f.close()
489
    finally:
490
      os.unlink(tmpname)
491

  
492
  def testRemovingSingleExistingHost(self):
493
    tmpname = self.writeTestFile()
494
    try:
495
      RemoveEtcHostsEntry(tmpname, 'localhost')
496

  
497
      f = open(tmpname, 'r')
498
      try:
499
        self.assertEqual(md5.new(f.read(8192)).hexdigest(),
500
                         'ec4e4589b56f82fdb88db5675de011b1')
501
      finally:
502
        f.close()
503
    finally:
504
      os.unlink(tmpname)
505

  
506
  def testRemovingNonExistingHost(self):
507
    tmpname = self.writeTestFile()
508
    try:
509
      RemoveEtcHostsEntry(tmpname, 'myhost')
510

  
511
      f = open(tmpname, 'r')
512
      try:
513
        self.assertEqual(md5.new(f.read(8192)).hexdigest(),
514
                         'aa005bddc6d9ee399c296953f194929e')
515
      finally:
516
        f.close()
517
    finally:
518
      os.unlink(tmpname)
519

  
520

  
434 521
class TestShellQuoting(unittest.TestCase):
435 522
  """Test case for shell quoting functions"""
436 523

  

Also available in: Unified diff