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):
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):
"""Wrapper around utils.RemoteEtcHostsEntry.
"""Wrapper around utils.RemoveEtcHostsEntry.
"""
hi = utils.HostInfo(name=hostname)
......@@ -574,10 +582,7 @@ class LUInitCluster(LogicalUnit):
f.close()
sshkey = sshline.split(" ")[1]
hi = utils.HostInfo(name=hostname.name)
utils.AddEtcHostsEntry(constants.ETC_HOSTS, hostname.name, hi.ip)
utils.AddEtcHostsEntry(constants.ETC_HOSTS, hi.ShortName(), hi.ip)
del hi
_AddHostToEtcHosts(hostname.name)
_UpdateKnownHosts(hostname.name, hostname.ip, sshkey)
......@@ -1484,10 +1489,7 @@ class LUAddNode(LogicalUnit):
raise errors.OpExecError("Cannot transfer ssh keys to the new node")
# Add node to our /etc/hosts, and add key to known_hosts
hi = utils.HostInfo(name=new_node.name)
utils.AddEtcHostsEntry(constants.ETC_HOSTS, new_node.name, hi.ip)
utils.AddEtcHostsEntry(constants.ETC_HOSTS, hi.ShortName(), hi.ip)
del hi
_AddHostToEtcHosts(new_node.name)
_UpdateKnownHosts(new_node.name, new_node.primary_ip,
self.cfg.GetHostKey())
......
......@@ -752,36 +752,43 @@ def RemoveAuthorizedKey(file_name, key):
raise
def AddEtcHostsEntry(file_name, hostname, ip):
"""Adds an IP address and hostname to /etc/hosts.
def SetEtcHostsEntry(file_name, ip, hostname, aliases):
"""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:
nl = True
out = os.fdopen(fd, 'w')
try:
f = open(file_name, 'r')
try:
written = False
for line in f:
fields = line.split()
if len(fields) < 2 or fields[0].startswith('#'):
if not fields[0].startswith('#') and ip == fields[0]:
continue
if fields[0] == ip and hostname in fields[1:]:
break
nl = line.endswith('\n')
else:
if not nl:
f.write("\n")
f.write(ip)
f.write(' ')
f.write(hostname)
f.write("\n")
f.flush()
out.write(line)
out.write("%s %s" % (ip, hostname))
if aliases:
out.write(" %s" % ' '.join(aliases))
out.write('\n')
out.flush()
os.rename(tmpname, file_name)
finally:
f.close()
finally:
out.close()
except:
RemoveFile(tmpname)
raise
def RemoveEtcHostsEntry(file_name, hostname):
"""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))
try:
......@@ -797,9 +804,7 @@ def RemoveEtcHostsEntry(file_name, hostname):
while hostname in names:
names.remove(hostname)
if names:
out.write(fields[0])
out.write(' ')
out.write(' '.join(names))
out.write("%s %s\n" % (fields[0], ' '.join(names)))
continue
out.write(line)
......
......@@ -38,7 +38,7 @@ from ganeti.utils import IsProcessAlive, Lock, Unlock, RunCmd, \
RemoveFile, CheckDict, MatchNameComponent, FormatUnit, \
ParseUnit, AddAuthorizedKey, RemoveAuthorizedKey, \
ShellQuote, ShellQuoteArgs, TcpPing, ListVisibleFiles, \
AddEtcHostsEntry, RemoveEtcHostsEntry
SetEtcHostsEntry, RemoveEtcHostsEntry
from ganeti.errors import LockError, UnitParseError
......@@ -447,29 +447,29 @@ class TestEtcHosts(unittest.TestCase):
return tmpname
def testAddingNewIp(self):
def testSettingNewIp(self):
tmpname = self.writeTestFile()
try:
AddEtcHostsEntry(tmpname, 'myhost.domain.tld', '1.2.3.4')
SetEtcHostsEntry(tmpname, '1.2.3.4', 'myhost.domain.tld', ['myhost'])
f = open(tmpname, 'r')
try:
self.assertEqual(md5.new(f.read(8192)).hexdigest(),
'00e0e88250482e7449743c89a49e9349')
'410c141dcafffd505f662a41713d2eab')
finally:
f.close()
finally:
os.unlink(tmpname)
def testAddingExistingIp(self):
def testSettingExistingIp(self):
tmpname = self.writeTestFile()
try:
AddEtcHostsEntry(tmpname, 'myhost.domain.tld', '192.168.1.1')
SetEtcHostsEntry(tmpname, '192.168.1.1', 'myhost.domain.tld', ['myhost'])
f = open(tmpname, 'r')
try:
self.assertEqual(md5.new(f.read(8192)).hexdigest(),
'4dc04c0acdd247175e0b980c6beea822')
'bbf60c542dec949f3968b59522ec0d7b')
finally:
f.close()
finally:
......@@ -483,7 +483,7 @@ class TestEtcHosts(unittest.TestCase):
f = open(tmpname, 'r')
try:
self.assertEqual(md5.new(f.read(8192)).hexdigest(),
'7d1e7a559eedbc25e0dff67d33ccac84')
'8b09207a23709d60240674601a3548b2')
finally:
f.close()
finally:
......@@ -517,6 +517,20 @@ class TestEtcHosts(unittest.TestCase):
finally:
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):
"""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