Commit 9440aeab authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

Fix functions for /etc/hosts.

- Combine hostname and aliases on one line
- Fix bug with wrongfully removed newline characters
- Use wrapper for SetEtcHostsEntry in cmdlib

Reviewed-by: iustin
parent 424908c1
...@@ -163,8 +163,16 @@ class NoHooksLU(LogicalUnit): ...@@ -163,8 +163,16 @@ class NoHooksLU(LogicalUnit):
return {}, [], [] return {}, [], []
def _AddHostToEtcHosts(hostname):
"""Wrapper around utils.SetEtcHostsEntry.
"""
hi = utils.HostInfo(name=hostname)
utils.SetEtcHostsEntry(constants.ETC_HOSTS, hi.ip, hi.name, [hi.ShortName()])
def _RemoveHostFromEtcHosts(hostname): def _RemoveHostFromEtcHosts(hostname):
"""Wrapper around utils.RemoteEtcHostsEntry. """Wrapper around utils.RemoveEtcHostsEntry.
""" """
hi = utils.HostInfo(name=hostname) hi = utils.HostInfo(name=hostname)
...@@ -574,10 +582,7 @@ class LUInitCluster(LogicalUnit): ...@@ -574,10 +582,7 @@ class LUInitCluster(LogicalUnit):
f.close() f.close()
sshkey = sshline.split(" ")[1] sshkey = sshline.split(" ")[1]
hi = utils.HostInfo(name=hostname.name) _AddHostToEtcHosts(hostname.name)
utils.AddEtcHostsEntry(constants.ETC_HOSTS, hostname.name, hi.ip)
utils.AddEtcHostsEntry(constants.ETC_HOSTS, hi.ShortName(), hi.ip)
del hi
_UpdateKnownHosts(hostname.name, hostname.ip, sshkey) _UpdateKnownHosts(hostname.name, hostname.ip, sshkey)
...@@ -1484,10 +1489,7 @@ class LUAddNode(LogicalUnit): ...@@ -1484,10 +1489,7 @@ class LUAddNode(LogicalUnit):
raise errors.OpExecError("Cannot transfer ssh keys to the new node") raise errors.OpExecError("Cannot transfer ssh keys to the new node")
# Add node to our /etc/hosts, and add key to known_hosts # Add node to our /etc/hosts, and add key to known_hosts
hi = utils.HostInfo(name=new_node.name) _AddHostToEtcHosts(new_node.name)
utils.AddEtcHostsEntry(constants.ETC_HOSTS, new_node.name, hi.ip)
utils.AddEtcHostsEntry(constants.ETC_HOSTS, hi.ShortName(), hi.ip)
del hi
_UpdateKnownHosts(new_node.name, new_node.primary_ip, _UpdateKnownHosts(new_node.name, new_node.primary_ip,
self.cfg.GetHostKey()) self.cfg.GetHostKey())
......
...@@ -752,36 +752,43 @@ def RemoveAuthorizedKey(file_name, key): ...@@ -752,36 +752,43 @@ def RemoveAuthorizedKey(file_name, key):
raise raise
def AddEtcHostsEntry(file_name, hostname, ip): def SetEtcHostsEntry(file_name, ip, hostname, aliases):
"""Adds an IP address and hostname to /etc/hosts. """Sets the name of an IP address and hostname in /etc/hosts.
""" """
f = open(file_name, 'a+') fd, tmpname = tempfile.mkstemp(dir=os.path.dirname(file_name))
try: try:
nl = True out = os.fdopen(fd, 'w')
for line in f: try:
fields = line.split() f = open(file_name, 'r')
if len(fields) < 2 or fields[0].startswith('#'): try:
continue written = False
if fields[0] == ip and hostname in fields[1:]: for line in f:
break fields = line.split()
nl = line.endswith('\n') if not fields[0].startswith('#') and ip == fields[0]:
else: continue
if not nl: out.write(line)
f.write("\n")
f.write(ip) out.write("%s %s" % (ip, hostname))
f.write(' ') if aliases:
f.write(hostname) out.write(" %s" % ' '.join(aliases))
f.write("\n") out.write('\n')
f.flush()
finally: out.flush()
f.close() os.rename(tmpname, file_name)
finally:
f.close()
finally:
out.close()
except:
RemoveFile(tmpname)
raise
def RemoveEtcHostsEntry(file_name, hostname): def RemoveEtcHostsEntry(file_name, hostname):
"""Removes a hostname from /etc/hosts. """Removes a hostname from /etc/hosts.
IP addresses without hostnames are removed from the file. IP addresses without names are removed from the file.
""" """
fd, tmpname = tempfile.mkstemp(dir=os.path.dirname(file_name)) fd, tmpname = tempfile.mkstemp(dir=os.path.dirname(file_name))
try: try:
...@@ -797,9 +804,7 @@ def RemoveEtcHostsEntry(file_name, hostname): ...@@ -797,9 +804,7 @@ def RemoveEtcHostsEntry(file_name, hostname):
while hostname in names: while hostname in names:
names.remove(hostname) names.remove(hostname)
if names: if names:
out.write(fields[0]) out.write("%s %s\n" % (fields[0], ' '.join(names)))
out.write(' ')
out.write(' '.join(names))
continue continue
out.write(line) out.write(line)
......
...@@ -38,7 +38,7 @@ from ganeti.utils import IsProcessAlive, Lock, Unlock, RunCmd, \ ...@@ -38,7 +38,7 @@ from ganeti.utils import IsProcessAlive, Lock, Unlock, RunCmd, \
RemoveFile, CheckDict, MatchNameComponent, FormatUnit, \ RemoveFile, CheckDict, MatchNameComponent, FormatUnit, \
ParseUnit, AddAuthorizedKey, RemoveAuthorizedKey, \ ParseUnit, AddAuthorizedKey, RemoveAuthorizedKey, \
ShellQuote, ShellQuoteArgs, TcpPing, ListVisibleFiles, \ ShellQuote, ShellQuoteArgs, TcpPing, ListVisibleFiles, \
AddEtcHostsEntry, RemoveEtcHostsEntry SetEtcHostsEntry, RemoveEtcHostsEntry
from ganeti.errors import LockError, UnitParseError from ganeti.errors import LockError, UnitParseError
...@@ -447,29 +447,29 @@ class TestEtcHosts(unittest.TestCase): ...@@ -447,29 +447,29 @@ class TestEtcHosts(unittest.TestCase):
return tmpname return tmpname
def testAddingNewIp(self): def testSettingNewIp(self):
tmpname = self.writeTestFile() tmpname = self.writeTestFile()
try: try:
AddEtcHostsEntry(tmpname, 'myhost.domain.tld', '1.2.3.4') SetEtcHostsEntry(tmpname, '1.2.3.4', 'myhost.domain.tld', ['myhost'])
f = open(tmpname, 'r') f = open(tmpname, 'r')
try: try:
self.assertEqual(md5.new(f.read(8192)).hexdigest(), self.assertEqual(md5.new(f.read(8192)).hexdigest(),
'00e0e88250482e7449743c89a49e9349') '410c141dcafffd505f662a41713d2eab')
finally: finally:
f.close() f.close()
finally: finally:
os.unlink(tmpname) os.unlink(tmpname)
def testAddingExistingIp(self): def testSettingExistingIp(self):
tmpname = self.writeTestFile() tmpname = self.writeTestFile()
try: try:
AddEtcHostsEntry(tmpname, 'myhost.domain.tld', '192.168.1.1') SetEtcHostsEntry(tmpname, '192.168.1.1', 'myhost.domain.tld', ['myhost'])
f = open(tmpname, 'r') f = open(tmpname, 'r')
try: try:
self.assertEqual(md5.new(f.read(8192)).hexdigest(), self.assertEqual(md5.new(f.read(8192)).hexdigest(),
'4dc04c0acdd247175e0b980c6beea822') 'bbf60c542dec949f3968b59522ec0d7b')
finally: finally:
f.close() f.close()
finally: finally:
...@@ -483,7 +483,7 @@ class TestEtcHosts(unittest.TestCase): ...@@ -483,7 +483,7 @@ class TestEtcHosts(unittest.TestCase):
f = open(tmpname, 'r') f = open(tmpname, 'r')
try: try:
self.assertEqual(md5.new(f.read(8192)).hexdigest(), self.assertEqual(md5.new(f.read(8192)).hexdigest(),
'7d1e7a559eedbc25e0dff67d33ccac84') '8b09207a23709d60240674601a3548b2')
finally: finally:
f.close() f.close()
finally: finally:
...@@ -517,6 +517,20 @@ class TestEtcHosts(unittest.TestCase): ...@@ -517,6 +517,20 @@ class TestEtcHosts(unittest.TestCase):
finally: finally:
os.unlink(tmpname) os.unlink(tmpname)
def testRemovingAlias(self):
tmpname = self.writeTestFile()
try:
RemoveEtcHostsEntry(tmpname, 'gw')
f = open(tmpname, 'r')
try:
self.assertEqual(md5.new(f.read(8192)).hexdigest(),
'156dd3980a17b2ef934e2d0bf670aca2')
finally:
f.close()
finally:
os.unlink(tmpname)
class TestShellQuoting(unittest.TestCase): class TestShellQuoting(unittest.TestCase):
"""Test case for shell quoting functions""" """Test case for shell quoting functions"""
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment