Revision 89e1fc26
b/daemons/ganeti-master | ||
---|---|---|
35 | 35 |
|
36 | 36 |
import os |
37 | 37 |
import sys |
38 |
import socket |
|
39 | 38 |
|
40 | 39 |
from optparse import OptionParser |
41 | 40 |
|
... | ... | |
150 | 149 |
""" |
151 | 150 |
options, args = ParseOptions() |
152 | 151 |
debug = options.debug |
152 |
try: |
|
153 |
myself = utils.HostInfo() |
|
154 |
except errors.ResolverError, err: |
|
155 |
sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0]) |
|
156 |
return EXIT_NODESETUP_ERROR |
|
157 |
|
|
153 | 158 |
result = CheckNodeSetup(debug) |
154 | 159 |
if not result: |
155 | 160 |
if debug: |
... | ... | |
157 | 162 |
return EXIT_NODESETUP_ERROR |
158 | 163 |
|
159 | 164 |
master_node, master_netdev, master_ip = result |
160 |
if socket.gethostname() != master_node and args[0] == "start":
|
|
165 |
if myself.name != master_node and args[0] == "start":
|
|
161 | 166 |
if debug: |
162 | 167 |
sys.stderr.write("Not master, ignoring request.\n") |
163 | 168 |
return EXIT_NOTMASTER |
b/daemons/ganeti-watcher | ||
---|---|---|
39 | 39 |
import time |
40 | 40 |
import fcntl |
41 | 41 |
import errno |
42 |
import socket |
|
43 | 42 |
from optparse import OptionParser |
44 | 43 |
|
45 | 44 |
|
46 | 45 |
from ganeti import utils |
47 | 46 |
from ganeti import constants |
48 | 47 |
from ganeti import ssconf |
48 |
from ganeti import errors |
|
49 | 49 |
|
50 | 50 |
|
51 | 51 |
class Error(Exception): |
... | ... | |
263 | 263 |
def __init__(self): |
264 | 264 |
sstore = ssconf.SimpleStore() |
265 | 265 |
master = sstore.GetMasterNode() |
266 |
if master != socket.gethostname():
|
|
266 |
if master != utils.HostInfo().name:
|
|
267 | 267 |
raise NotMasterError("This is not the master node") |
268 | 268 |
self.instances = InstanceList() |
269 | 269 |
self.messages = [] |
... | ... | |
357 | 357 |
if options.debug: |
358 | 358 |
sys.stderr.write("Not master, exiting.\n") |
359 | 359 |
sys.exit(constants.EXIT_NOTMASTER) |
360 |
except errors.ResolverError, err: |
|
361 |
sys.stderr.write("Cannot resolve hostname '%s', exiting.\n" % err.args[0]) |
|
362 |
sys.exit(constants.EXIT_NODESETUP_ERROR) |
|
360 | 363 |
except Error, err: |
361 | 364 |
print err |
362 | 365 |
|
b/lib/cli.py | ||
---|---|---|
296 | 296 |
except errors.HooksFailure, err: |
297 | 297 |
logger.ToStderr("Failure: hooks general failure: %s" % str(err)) |
298 | 298 |
result = 1 |
299 |
except errors.ResolverError, err: |
|
300 |
this_host = utils.HostInfo.SysName() |
|
301 |
if err.args[0] == this_host: |
|
302 |
msg = "Failure: can't resolve my own hostname ('%s')" |
|
303 |
else: |
|
304 |
msg = "Failure: can't resolve hostname '%s'" |
|
305 |
logger.ToStderr(msg % err.args[0]) |
|
306 |
result = 1 |
|
299 | 307 |
except errors.OpPrereqError, err: |
300 | 308 |
logger.ToStderr("Failure: prerequisites not met for this" |
301 | 309 |
" operation:\n%s" % str(err)) |
b/lib/cmdlib.py | ||
---|---|---|
85 | 85 |
" use 'gnt-cluster init' first.") |
86 | 86 |
if self.REQ_MASTER: |
87 | 87 |
master = sstore.GetMasterNode() |
88 |
if master != socket.gethostname():
|
|
88 |
if master != utils.HostInfo().name:
|
|
89 | 89 |
raise errors.OpPrereqError("Commands must be run on the master" |
90 | 90 |
" node %s" % master) |
91 | 91 |
|
... | ... | |
558 | 558 |
if config.ConfigWriter.IsCluster(): |
559 | 559 |
raise errors.OpPrereqError("Cluster is already initialised") |
560 | 560 |
|
561 |
hostname_local = socket.gethostname() |
|
562 |
self.hostname = hostname = utils.LookupHostname(hostname_local) |
|
563 |
if not hostname: |
|
564 |
raise errors.OpPrereqError("Cannot resolve my own hostname ('%s')" % |
|
565 |
hostname_local) |
|
566 |
|
|
567 |
if hostname.name != hostname_local: |
|
568 |
raise errors.OpPrereqError("My own hostname (%s) does not match the" |
|
569 |
" resolver (%s): probably not using FQDN" |
|
570 |
" for hostname." % |
|
571 |
(hostname_local, hostname.name)) |
|
561 |
self.hostname = hostname = utils.HostInfo() |
|
572 | 562 |
|
573 | 563 |
if hostname.ip.startswith("127."): |
574 | 564 |
raise errors.OpPrereqError("This host's IP resolves to the private" |
575 | 565 |
" range (%s). Please fix DNS or /etc/hosts." % |
576 | 566 |
(hostname.ip,)) |
577 | 567 |
|
578 |
self.clustername = clustername = utils.LookupHostname(self.op.cluster_name) |
|
579 |
if not clustername: |
|
580 |
raise errors.OpPrereqError("Cannot resolve given cluster name ('%s')" |
|
581 |
% self.op.cluster_name) |
|
568 |
self.clustername = clustername = utils.HostInfo(self.op.cluster_name) |
|
582 | 569 |
|
583 | 570 |
result = utils.RunCmd(["fping", "-S127.0.0.1", "-q", hostname.ip]) |
584 | 571 |
if result.failed: |
... | ... | |
961 | 948 |
"""Verify that the passed name is a valid one. |
962 | 949 |
|
963 | 950 |
""" |
964 |
hostname = utils.LookupHostname(self.op.name) |
|
965 |
if not hostname: |
|
966 |
raise errors.OpPrereqError("Cannot resolve the new cluster name ('%s')" % |
|
967 |
self.op.name) |
|
951 |
hostname = utils.HostInfo(self.op.name) |
|
968 | 952 |
|
969 | 953 |
new_name = hostname.name |
970 | 954 |
self.ip = new_ip = hostname.ip |
... | ... | |
1404 | 1388 |
node_name = self.op.node_name |
1405 | 1389 |
cfg = self.cfg |
1406 | 1390 |
|
1407 |
dns_data = utils.LookupHostname(node_name) |
|
1408 |
if not dns_data: |
|
1409 |
raise errors.OpPrereqError("Node %s is not resolvable" % node_name) |
|
1391 |
dns_data = utils.HostInfo(node_name) |
|
1410 | 1392 |
|
1411 | 1393 |
node = dns_data.name |
1412 | 1394 |
primary_ip = self.op.primary_ip = dns_data.ip |
... | ... | |
1614 | 1596 |
This checks that we are not already the master. |
1615 | 1597 |
|
1616 | 1598 |
""" |
1617 |
self.new_master = socket.gethostname() |
|
1618 |
|
|
1599 |
self.new_master = utils.HostInfo().name |
|
1619 | 1600 |
self.old_master = self.sstore.GetMasterNode() |
1620 | 1601 |
|
1621 | 1602 |
if self.old_master == self.new_master: |
... | ... | |
1716 | 1697 |
""" |
1717 | 1698 |
filename = self.op.filename |
1718 | 1699 |
|
1719 |
myname = socket.gethostname()
|
|
1700 |
myname = utils.HostInfo().name
|
|
1720 | 1701 |
|
1721 | 1702 |
for node in self.nodes: |
1722 | 1703 |
if node == myname: |
... | ... | |
2152 | 2133 |
self.instance = instance |
2153 | 2134 |
|
2154 | 2135 |
# new name verification |
2155 |
hostname1 = utils.LookupHostname(self.op.new_name) |
|
2156 |
if not hostname1: |
|
2157 |
raise errors.OpPrereqError("New instance name '%s' not found in dns" % |
|
2158 |
self.op.new_name) |
|
2136 |
name_info = utils.HostInfo(self.op.new_name) |
|
2159 | 2137 |
|
2160 |
self.op.new_name = new_name = hostname1.name
|
|
2138 |
self.op.new_name = new_name = name_info.name
|
|
2161 | 2139 |
if not getattr(self.op, "ignore_ip", False): |
2162 |
command = ["fping", "-q", hostname1.ip]
|
|
2140 |
command = ["fping", "-q", name_info.ip]
|
|
2163 | 2141 |
result = utils.RunCmd(command) |
2164 | 2142 |
if not result.failed: |
2165 | 2143 |
raise errors.OpPrereqError("IP %s of instance %s already in use" % |
2166 |
(hostname1.ip, new_name))
|
|
2144 |
(name_info.ip, new_name))
|
|
2167 | 2145 |
|
2168 | 2146 |
|
2169 | 2147 |
def Exec(self, feedback_fn): |
... | ... | |
2839 | 2817 |
" primary node" % self.op.os_type) |
2840 | 2818 |
|
2841 | 2819 |
# instance verification |
2842 |
hostname1 = utils.LookupHostname(self.op.instance_name) |
|
2843 |
if not hostname1: |
|
2844 |
raise errors.OpPrereqError("Instance name '%s' not found in dns" % |
|
2845 |
self.op.instance_name) |
|
2820 |
hostname1 = utils.HostInfo(self.op.instance_name) |
|
2846 | 2821 |
|
2847 | 2822 |
self.op.instance_name = instance_name = hostname1.name |
2848 | 2823 |
instance_list = self.cfg.GetInstanceList() |
b/lib/config.py | ||
---|---|---|
35 | 35 |
""" |
36 | 36 |
|
37 | 37 |
import os |
38 |
import socket |
|
39 | 38 |
import tempfile |
40 | 39 |
import random |
41 | 40 |
|
... | ... | |
78 | 77 |
else: |
79 | 78 |
self._cfg_file = cfg_file |
80 | 79 |
self._temporary_ids = set() |
80 |
# Note: in order to prevent errors when resolving our name in |
|
81 |
# _DistributeConfig, we compute it here once and reuse it; it's |
|
82 |
# better to raise an error before starting to modify the config |
|
83 |
# file than after it was modified |
|
84 |
self._my_hostname = utils.HostInfo().name |
|
81 | 85 |
|
82 | 86 |
# this method needs to be static, so that we can call it on the class |
83 | 87 |
@staticmethod |
... | ... | |
527 | 531 |
return True |
528 | 532 |
bad = False |
529 | 533 |
nodelist = self.GetNodeList() |
530 |
myhostname = socket.gethostname()
|
|
534 |
myhostname = self._my_hostname
|
|
531 | 535 |
|
532 | 536 |
tgt_list = [] |
533 | 537 |
for node in nodelist: |
b/lib/errors.py | ||
---|---|---|
151 | 151 |
""" |
152 | 152 |
|
153 | 153 |
|
154 |
class ResolverError(GenericError): |
|
155 |
"""Host name cannot be resolved. |
|
156 |
|
|
157 |
This is not a normal situation for Ganeti, as we rely on having a |
|
158 |
working resolver. |
|
159 |
|
|
160 |
The non-resolvable hostname is available as the first element of the |
|
161 |
args tuple; the other two elements of the tuple are the first two |
|
162 |
args of the socket.gaierror exception (error code and description). |
|
163 |
|
|
164 |
""" |
|
165 |
|
|
166 |
|
|
154 | 167 |
class HooksFailure(GenericError): |
155 | 168 |
"""A generic hook failure. |
156 | 169 |
|
b/lib/utils.py | ||
---|---|---|
397 | 397 |
|
398 | 398 |
|
399 | 399 |
class HostInfo: |
400 |
"""Class holding host info as returned by gethostbyname
|
|
400 |
"""Class implementing resolver and hostname functionality
|
|
401 | 401 |
|
402 | 402 |
""" |
403 |
def __init__(self, name, aliases, ipaddrs):
|
|
403 |
def __init__(self, name=None):
|
|
404 | 404 |
"""Initialize the host name object. |
405 | 405 |
|
406 |
Arguments are the same as returned by socket.gethostbyname_ex() |
|
406 |
If the name argument is not passed, it will use this system's |
|
407 |
name. |
|
407 | 408 |
|
408 | 409 |
""" |
409 |
self.name = name |
|
410 |
self.aliases = aliases |
|
411 |
self.ipaddrs = ipaddrs |
|
410 |
if name is None: |
|
411 |
name = self.SysName() |
|
412 |
|
|
413 |
self.query = name |
|
414 |
self.name, self.aliases, self.ipaddrs = self.LookupHostname(name) |
|
412 | 415 |
self.ip = self.ipaddrs[0] |
413 | 416 |
|
417 |
@staticmethod |
|
418 |
def SysName(): |
|
419 |
"""Return the current system's name. |
|
414 | 420 |
|
415 |
def LookupHostname(hostname): |
|
416 |
"""Look up hostname |
|
421 |
This is simply a wrapper over socket.gethostname() |
|
417 | 422 |
|
418 |
Args:
|
|
419 |
hostname: hostname to look up, can be also be a non FQDN
|
|
423 |
"""
|
|
424 |
return socket.gethostname()
|
|
420 | 425 |
|
421 |
Returns: |
|
422 |
a HostInfo object |
|
426 |
@staticmethod |
|
427 |
def LookupHostname(hostname): |
|
428 |
"""Look up hostname |
|
423 | 429 |
|
424 |
""" |
|
425 |
try: |
|
426 |
(name, aliases, ipaddrs) = socket.gethostbyname_ex(hostname) |
|
427 |
except socket.gaierror: |
|
428 |
# hostname not found in DNS |
|
429 |
return None |
|
430 |
Args: |
|
431 |
hostname: hostname to look up |
|
432 |
|
|
433 |
Returns: |
|
434 |
a tuple (name, aliases, ipaddrs) as returned by socket.gethostbyname_ex |
|
435 |
in case of errors in resolving, we raise a ResolverError |
|
436 |
|
|
437 |
""" |
|
438 |
try: |
|
439 |
result = socket.gethostbyname_ex(hostname) |
|
440 |
except socket.gaierror, err: |
|
441 |
# hostname not found in DNS |
|
442 |
raise errors.ResolverError(hostname, err.args[0], err.args[1]) |
|
430 | 443 |
|
431 |
return HostInfo(name, aliases, ipaddrs)
|
|
444 |
return result
|
|
432 | 445 |
|
433 | 446 |
|
434 | 447 |
def ListVolumeGroups(): |
b/test/ganeti.config_unittest.py | ||
---|---|---|
54 | 54 |
|
55 | 55 |
def _init_cluster(self, cfg): |
56 | 56 |
"""Initializes the cfg object""" |
57 |
cfg.InitConfig(socket.gethostname(), '127.0.0.1', None, '', 'aa:00:00',
|
|
57 |
cfg.InitConfig(utils.HostInfo().name, '127.0.0.1', None, '', 'aa:00:00',
|
|
58 | 58 |
'xenvg', constants.DEFAULT_BRIDGE) |
59 | 59 |
|
60 | 60 |
def _create_instance(self): |
b/test/mocks.py | ||
---|---|---|
22 | 22 |
"""Module implementing a fake ConfigWriter""" |
23 | 23 |
|
24 | 24 |
import socket |
25 |
from ganeti import utils |
|
25 | 26 |
|
26 | 27 |
class FakeConfig: |
27 | 28 |
"""Fake configuration object""" |
... | ... | |
33 | 34 |
return ["a", "b", "c"] |
34 | 35 |
|
35 | 36 |
def GetMaster(self): |
36 |
return socket.gethostname()
|
|
37 |
return utils.HostInfo().name
|
|
37 | 38 |
|
38 | 39 |
|
39 | 40 |
class FakeSStore: |
... | ... | |
43 | 44 |
return "test.cluster" |
44 | 45 |
|
45 | 46 |
def GetMasterNode(self): |
46 |
return socket.gethostname() |
|
47 |
return utils.HostInfo().name |
Also available in: Unified diff