RAPI: Convert instance shutdown to the new FillOpCode
[ganeti-local] / lib / utils / nodesetup.py
1 #
2 #
3
4 # Copyright (C) 2006, 2007, 2010, 2011 Google Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20
21 """Utility functions for manipulating /etc/hosts.
22
23 """
24
25 import os
26
27 from ganeti import constants
28
29 from ganeti.utils import algo
30 from ganeti.utils import io
31
32
33 def SetEtcHostsEntry(file_name, ip, hostname, aliases):
34   """Sets the name of an IP address and hostname in /etc/hosts.
35
36   @type file_name: str
37   @param file_name: path to the file to modify (usually C{/etc/hosts})
38   @type ip: str
39   @param ip: the IP address
40   @type hostname: str
41   @param hostname: the hostname to be added
42   @type aliases: list
43   @param aliases: the list of aliases to add for the hostname
44
45   """
46   # Ensure aliases are unique
47   aliases = algo.UniqueSequence([hostname] + aliases)[1:]
48
49   def _WriteEtcHosts(fd):
50     # Duplicating file descriptor because os.fdopen's result will automatically
51     # close the descriptor, but we would still like to have its functionality.
52     out = os.fdopen(os.dup(fd), "w")
53     try:
54       for line in io.ReadFile(file_name).splitlines(True):
55         fields = line.split()
56         if fields and not fields[0].startswith("#") and ip == fields[0]:
57           continue
58         out.write(line)
59
60       out.write("%s\t%s" % (ip, hostname))
61       if aliases:
62         out.write(" %s" % " ".join(aliases))
63       out.write("\n")
64       out.flush()
65     finally:
66       out.close()
67
68   io.WriteFile(file_name, fn=_WriteEtcHosts, mode=0644)
69
70
71 def AddHostToEtcHosts(hostname, ip):
72   """Wrapper around SetEtcHostsEntry.
73
74   @type hostname: str
75   @param hostname: a hostname that will be resolved and added to
76       L{constants.ETC_HOSTS}
77   @type ip: str
78   @param ip: The ip address of the host
79
80   """
81   SetEtcHostsEntry(constants.ETC_HOSTS, ip, hostname, [hostname.split(".")[0]])
82
83
84 def RemoveEtcHostsEntry(file_name, hostname):
85   """Removes a hostname from /etc/hosts.
86
87   IP addresses without names are removed from the file.
88
89   @type file_name: str
90   @param file_name: path to the file to modify (usually C{/etc/hosts})
91   @type hostname: str
92   @param hostname: the hostname to be removed
93
94   """
95   def _WriteEtcHosts(fd):
96     # Duplicating file descriptor because os.fdopen's result will automatically
97     # close the descriptor, but we would still like to have its functionality.
98     out = os.fdopen(os.dup(fd), "w")
99     try:
100       for line in io.ReadFile(file_name).splitlines(True):
101         fields = line.split()
102         if len(fields) > 1 and not fields[0].startswith("#"):
103           names = fields[1:]
104           if hostname in names:
105             while hostname in names:
106               names.remove(hostname)
107             if names:
108               out.write("%s %s\n" % (fields[0], " ".join(names)))
109             continue
110
111         out.write(line)
112
113       out.flush()
114     finally:
115       out.close()
116
117   io.WriteFile(file_name, fn=_WriteEtcHosts, mode=0644)
118
119
120 def RemoveHostFromEtcHosts(hostname):
121   """Wrapper around RemoveEtcHostsEntry.
122
123   @type hostname: str
124   @param hostname: hostname that will be resolved and its
125       full and shot name will be removed from
126       L{constants.ETC_HOSTS}
127
128   """
129   RemoveEtcHostsEntry(constants.ETC_HOSTS, hostname)
130   RemoveEtcHostsEntry(constants.ETC_HOSTS, hostname.split(".")[0])