improve the updating of /etc/hosts with correct fqdn when possible

Thanks to Adam Gandalman and Marc Cluet for this fix.
This commit is contained in:
Scott Moser 2011-07-19 22:53:05 -04:00
parent 42624e5604
commit 370ee8f4b9
4 changed files with 63 additions and 46 deletions

View File

@ -17,57 +17,60 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import cloudinit.util as util
from cloudinit.CloudConfig import per_always
import platform
import StringIO
frequency = per_always
def handle(name,cfg,cloud,log,args):
if not util.get_cfg_option_bool(cfg,"manage_etc_hosts",False):
hostname = util.get_cfg_option_str(cfg,"hostname",cloud.get_hostname())
fqdn = util.get_cfg_option_str(cfg,"fqdn",cloud.get_hostname(fqdn=True))
if util.get_cfg_option_bool(cfg,"manage_etc_hosts", True):
# manage_etc_hosts not true, update the 127.0.1.1 entry via update_etc_hosts
log.debug("manage_etc_hosts is not set, checking sanity of /etc/hosts")
with open('/etc/hosts', 'r') as etchosts:
current_hostname = platform.node()
hosts_line = "# Added by cloud-init\n127.0.1.1\t%s.localdomain %s\n" % (current_hostname, current_hostname)
need_write = False
need_change = True
new_etchosts = StringIO.StringIO()
for line in etchosts:
split_line = [s.strip() for s in line.split()]
# skip over malformed /etc/hosts entries
if len(split_line) < 2:
continue
ip, hostnames = split_line[0], split_line[1:]
if ip == "127.0.1.1":
for hostname in hostnames:
if hostname == current_hostname:
need_change = False
if need_change == True:
line = hosts_line
need_change = False
need_write = True
new_etchosts.write(line)
etchosts.close()
if need_change == True:
new_etchosts.write(hosts_line)
need_write = True
if need_write == True:
new_etcfile = open ('/etc/hosts','wb')
new_etcfile.write(new_etchosts.getvalue())
new_etcfile.close()
new_etchosts.close()
update_etc_hosts(hostname, fqdn, log)
return
# manage_etc_hosts is set, render from template file
try:
hostname = util.get_cfg_option_str(cfg,"hostname",cloud.get_hostname())
if not hostname:
hostname = cloud.get_hostname()
if not hostname:
log.info("manage_etc_hosts was set, but no hostname found")
return
util.render_to_file('hosts', '/etc/hosts', { 'hostname' : hostname })
util.render_to_file('hosts', '/etc/hosts', \
{ 'hostname' : hostname, 'fqdn' : fqdn })
except Exception as e:
log.warn("failed to update /etc/hosts")
raise
def update_etc_hosts(hostname, fqdn, log):
with open('/etc/hosts', 'r') as etchosts:
hosts_line = "# Added by cloud-init\n127.0.1.1\t%s %s\n" % (fqdn, hostname)
need_write = False
need_change = True
new_etchosts = StringIO.StringIO()
for line in etchosts:
split_line = [s.strip() for s in line.split()]
# skip over malformed /etc/hosts entries
if len(split_line) < 2:
continue
ip, hosts = split_line[0], split_line[1:]
if ip == "127.0.1.1":
if sorted([hostname, fqdn]) == sorted(hosts):
need_change = False
if need_change == True:
line = hosts_line
need_change = False
need_write = True
new_etchosts.write(line)
etchosts.close()
if need_change == True:
new_etchosts.write(hosts_line)
need_write = True
if need_write == True:
new_etcfile = open ('/etc/hosts','wb')
new_etcfile.write(new_etchosts.getvalue())
new_etcfile.close()
new_etchosts.close()
return

View File

@ -22,6 +22,7 @@ DEP_NETWORK = "NETWORK"
import UserDataHandler as ud
import cloudinit.util as util
import platform
class DataSource:
userdata = None
@ -96,20 +97,33 @@ class DataSource:
return "ubuntuhost"
return(self.metadata['instance-id'])
def get_hostname(self):
def get_hostname(self, fqdn=False):
domain = "localdomain"
if not 'local-hostname' in self.metadata:
return None
toks = [ platform.node(), domain ]
else:
toks = self.metadata['local-hostname'].split('.')
toks = self.metadata['local-hostname'].split('.')
# if there is an ipv4 address in 'local-hostname', then
# make up a hostname (LP: #475354)
if len(toks) == 4:
try:
r = filter(lambda x: int(x) < 256 and x > 0, toks)
if len(r) == 4:
return("ip-%s" % '-'.join(r))
except: pass
return toks[0]
toks = [ "ip-%s" % '-'.join(r) ]
except:
pass
if len(toks) > 1:
hostname = toks[0]
domain = '.'.join(toks[1:])
else:
hostname = toks[0]
if fqdn:
return "%s.%s" % (hostname,domain)
else:
return hostname
# return a list of classes that have the same depends as 'depends'
# iterate through cfg_list, loading "DataSourceCollections" modules

View File

@ -452,8 +452,8 @@ class CloudInit:
def get_mirror(self):
return(self.datasource.get_local_mirror())
def get_hostname(self):
return(self.datasource.get_hostname())
def get_hostname(self, fqdn=False):
return(self.datasource.get_hostname(fqdn=fqdn))
def device_name_to_device(self,name):
return(self.datasource.device_name_to_device(name))

View File

@ -13,7 +13,7 @@
# /etc/cloud/cloud.cfg or cloud-config from user-data
#
## The value '$hostname' will be replaced with the local-hostname
127.0.1.1 $hostname
127.0.1.1 $fqdn $hostname
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts