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