Commit a744b676 authored by Manuel Franceschini's avatar Manuel Franceschini

Introduce lib/netutils.py

This patch moves network utility functions to a dedicated module.
Signed-off-by: default avatarManuel Franceschini <livewire@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent 4ea3de4e
......@@ -119,6 +119,7 @@ pkgpython_PYTHON = \
lib/locking.py \
lib/luxi.py \
lib/mcpu.py \
lib/netutils.py \
lib/objects.py \
lib/opcodes.py \
lib/rpc.py \
......@@ -380,6 +381,7 @@ python_tests = \
test/ganeti.luxi_unittest.py \
test/ganeti.masterd.instance_unittest.py \
test/ganeti.mcpu_unittest.py \
test/ganeti.netutils_unittest.py \
test/ganeti.objects_unittest.py \
test/ganeti.opcodes_unittest.py \
test/ganeti.rapi.client_unittest.py \
......
......@@ -54,6 +54,7 @@ from ganeti import ssconf
from ganeti import workerpool
from ganeti import rpc
from ganeti import bootstrap
from ganeti import netutils
CLIENT_REQUEST_WORKERS = 16
......@@ -421,7 +422,7 @@ def CheckAgreement():
other node to be up too to confirm our status.
"""
myself = utils.HostInfo().name
myself = netutils.HostInfo().name
#temp instantiation of a config writer, used only to get the node list
cfg = config.ConfigWriter()
node_list = cfg.GetNodeList()
......
......@@ -46,6 +46,7 @@ from ganeti import http
from ganeti import utils
from ganeti import storage
from ganeti import serializer
from ganeti import netutils
import ganeti.http.server # pylint: disable-msg=W0611
......@@ -589,15 +590,15 @@ class NodeHttpServer(http.server.HttpServer):
"""Do a TcpPing on the remote node.
"""
return utils.TcpPing(params[1], params[2], timeout=params[3],
live_port_needed=params[4], source=params[0])
return netutils.TcpPing(params[1], params[2], timeout=params[3],
live_port_needed=params[4], source=params[0])
@staticmethod
def perspective_node_has_ip_address(params):
"""Checks if a node has the given ip address.
"""
return utils.OwnIpAddress(params[0])
return netutils.OwnIpAddress(params[0])
@staticmethod
def perspective_node_info(params):
......
......@@ -49,6 +49,7 @@ from ganeti import bdev
from ganeti import hypervisor
from ganeti import rapi
from ganeti.confd import client as confd_client
from ganeti import netutils
import ganeti.rapi.client # pylint: disable-msg=W0611
......@@ -209,7 +210,7 @@ class NodeMaintenance(object):
"""Check node status versus cluster desired state.
"""
my_name = utils.HostInfo().name
my_name = netutils.HostInfo().name
req = confd_client.ConfdClientRequest(type=
constants.CONFD_REQ_NODE_ROLE_BYNAME,
query=my_name)
......@@ -438,7 +439,7 @@ class Watcher(object):
def __init__(self, opts, notepad):
self.notepad = notepad
master = client.QueryConfigValues(["master_node"])[0]
if master != utils.HostInfo().name:
if master != netutils.HostInfo().name:
raise NotMasterError("This is not the master node")
# first archive old jobs
self.ArchiveJobs(opts.job_age)
......
......@@ -45,6 +45,7 @@ from ganeti import serializer
from ganeti import objects
from ganeti import locking
from ganeti import impexpd
from ganeti import netutils
#: How many lines to keep in the status file
......@@ -407,7 +408,7 @@ def ParseOptions():
# Normalize and check parameters
if options.host is not None:
try:
options.host = utils.HostInfo.NormalizeName(options.host)
options.host = netutils.HostInfo.NormalizeName(options.host)
except errors.OpPrereqError, err:
parser.error("Invalid hostname '%s': %s" % (options.host, err))
......
......@@ -58,6 +58,7 @@ from ganeti import bdev
from ganeti import objects
from ganeti import ssconf
from ganeti import serializer
from ganeti import netutils
_BOOT_ID_PATH = "/proc/sys/kernel/random/boot_id"
......@@ -258,8 +259,8 @@ def StartMaster(start_daemons, no_voting):
master_netdev, master_ip, _ = GetMasterInfo()
err_msgs = []
if utils.TcpPing(master_ip, constants.DEFAULT_NODED_PORT):
if utils.OwnIpAddress(master_ip):
if netutils.TcpPing(master_ip, constants.DEFAULT_NODED_PORT):
if netutils.OwnIpAddress(master_ip):
# we already have the ip:
logging.debug("Master IP already configured, doing nothing")
else:
......@@ -487,8 +488,8 @@ def VerifyNode(what, cluster_name):
"""
result = {}
my_name = utils.HostInfo().name
port = utils.GetDaemonPort(constants.NODED)
my_name = netutils.HostInfo().name
port = netutils.GetDaemonPort(constants.NODED)
if constants.NV_HYPERVISOR in what:
result[constants.NV_HYPERVISOR] = tmp = {}
......@@ -525,10 +526,10 @@ def VerifyNode(what, cluster_name):
else:
for name, pip, sip in what[constants.NV_NODENETTEST]:
fail = []
if not utils.TcpPing(pip, port, source=my_pip):
if not netutils.TcpPing(pip, port, source=my_pip):
fail.append("primary")
if sip != pip:
if not utils.TcpPing(sip, port, source=my_sip):
if not netutils.TcpPing(sip, port, source=my_sip):
fail.append("secondary")
if fail:
tmp[name] = ("failure using the %s interface(s)" %
......@@ -542,7 +543,7 @@ def VerifyNode(what, cluster_name):
source = constants.IP4_ADDRESS_LOCALHOST
else:
source = None
result[constants.NV_MASTERIP] = utils.TcpPing(master_ip, port,
result[constants.NV_MASTERIP] = netutils.TcpPing(master_ip, port,
source=source)
if constants.NV_LVLIST in what:
......@@ -2591,7 +2592,7 @@ def CreateX509Certificate(validity, cryptodir=constants.CRYPTO_KEYS_DIR):
"""
(key_pem, cert_pem) = \
utils.GenerateSelfSignedX509Cert(utils.HostInfo.SysName(),
utils.GenerateSelfSignedX509Cert(netutils.HostInfo.SysName(),
min(validity, _MAX_SSL_CERT_VALIDITY))
cert_dir = tempfile.mkdtemp(dir=cryptodir,
......@@ -2934,7 +2935,7 @@ def _FindDisks(nodes_ip, disks):
"""
# set the correct physical ID
my_name = utils.HostInfo().name
my_name = netutils.HostInfo().name
for cf in disks:
cf.SetPhysicalID(my_name, nodes_ip)
......
......@@ -33,6 +33,7 @@ from ganeti import errors
from ganeti import constants
from ganeti import objects
from ganeti import compat
from ganeti import netutils
# Size of reads in _CanReadDevice
......@@ -1301,13 +1302,13 @@ class DRBD8(BaseDRBD):
# about its peer.
cls._SetMinorSyncSpeed(minor, constants.SYNC_SPEED)
if utils.IsValidIP6(lhost):
if not utils.IsValidIP6(rhost):
if netutils.IsValidIP6(lhost):
if not netutils.IsValidIP6(rhost):
_ThrowError("drbd%d: can't connect ip %s to ip %s" %
(minor, lhost, rhost))
family = "ipv6"
elif utils.IsValidIP4(lhost):
if not utils.IsValidIP4(rhost):
elif netutils.IsValidIP4(lhost):
if not netutils.IsValidIP4(rhost):
_ThrowError("drbd%d: can't connect ip %s to ip %s" %
(minor, lhost, rhost))
family = "ipv4"
......
......@@ -40,6 +40,7 @@ from ganeti import ssconf
from ganeti import serializer
from ganeti import hypervisor
from ganeti import bdev
from ganeti import netutils
def _InitSSHSetup():
......@@ -239,7 +240,7 @@ def InitCluster(cluster_name, mac_prefix,
" entries: %s" % invalid_hvs,
errors.ECODE_INVAL)
hostname = utils.GetHostInfo()
hostname = netutils.GetHostInfo()
if hostname.ip.startswith("127."):
raise errors.OpPrereqError("This host's IP resolves to the private"
......@@ -247,25 +248,26 @@ def InitCluster(cluster_name, mac_prefix,
(hostname.ip, constants.ETC_HOSTS),
errors.ECODE_ENVIRON)
if not utils.OwnIpAddress(hostname.ip):
if not netutils.OwnIpAddress(hostname.ip):
raise errors.OpPrereqError("Inconsistency: this host's name resolves"
" to %s,\nbut this ip address does not"
" belong to this host. Aborting." %
hostname.ip, errors.ECODE_ENVIRON)
clustername = utils.GetHostInfo(utils.HostInfo.NormalizeName(cluster_name))
clustername = \
netutils.GetHostInfo(netutils.HostInfo.NormalizeName(cluster_name))
if utils.TcpPing(clustername.ip, constants.DEFAULT_NODED_PORT,
if netutils.TcpPing(clustername.ip, constants.DEFAULT_NODED_PORT,
timeout=5):
raise errors.OpPrereqError("Cluster IP already active. Aborting.",
errors.ECODE_NOTUNIQUE)
if secondary_ip:
if not utils.IsValidIP4(secondary_ip):
if not netutils.IsValidIP4(secondary_ip):
raise errors.OpPrereqError("Invalid secondary ip given",
errors.ECODE_INVAL)
if (secondary_ip != hostname.ip and
not utils.OwnIpAddress(secondary_ip)):
not netutils.OwnIpAddress(secondary_ip)):
raise errors.OpPrereqError("You gave %s as secondary IP,"
" but it does not belong to this host." %
secondary_ip, errors.ECODE_ENVIRON)
......@@ -574,7 +576,7 @@ def MasterFailover(no_voting=False):
total_timeout = 30
# Here we have a phase where no master should be running
def _check_ip():
if utils.TcpPing(master_ip, constants.DEFAULT_NODED_PORT):
if netutils.TcpPing(master_ip, constants.DEFAULT_NODED_PORT):
raise utils.RetryAgain()
try:
......@@ -641,7 +643,7 @@ def GatherMasterVotes(node_list):
@return: list of (node, votes)
"""
myself = utils.HostInfo().name
myself = netutils.HostInfo().name
try:
node_list.remove(myself)
except ValueError:
......
......@@ -38,6 +38,7 @@ from ganeti import ssconf
from ganeti import rpc
from ganeti import ssh
from ganeti import compat
from ganeti import netutils
from optparse import (OptionParser, TitledHelpFormatter,
Option, OptionValueError)
......@@ -1624,7 +1625,7 @@ def FormatError(err):
elif isinstance(err, errors.HooksFailure):
obuf.write("Failure: hooks general failure: %s" % msg)
elif isinstance(err, errors.ResolverError):
this_host = utils.HostInfo.SysName()
this_host = netutils.HostInfo.SysName()
if err.args[0] == this_host:
msg = "Failure: can't resolve my own hostname ('%s')"
else:
......
......@@ -49,6 +49,7 @@ from ganeti import ssconf
from ganeti import uidpool
from ganeti import compat
from ganeti import masterd
from ganeti import netutils
import ganeti.masterd.instance # pylint: disable-msg=W0611
......@@ -2513,7 +2514,7 @@ class LURenameCluster(LogicalUnit):
"""Verify that the passed name is a valid one.
"""
hostname = utils.GetHostInfo(self.op.name)
hostname = netutils.GetHostInfo(self.op.name)
new_name = hostname.name
self.ip = new_ip = hostname.ip
......@@ -2524,7 +2525,7 @@ class LURenameCluster(LogicalUnit):
" cluster has changed",
errors.ECODE_INVAL)
if new_ip != old_ip:
if utils.TcpPing(new_ip, constants.DEFAULT_NODED_PORT):
if netutils.TcpPing(new_ip, constants.DEFAULT_NODED_PORT):
raise errors.OpPrereqError("The given cluster IP address (%s) is"
" reachable on the network. Aborting." %
new_ip, errors.ECODE_NOTUNIQUE)
......@@ -3654,7 +3655,7 @@ class LUAddNode(LogicalUnit):
def CheckArguments(self):
# validate/normalize the node name
self.op.node_name = utils.HostInfo.NormalizeName(self.op.node_name)
self.op.node_name = netutils.HostInfo.NormalizeName(self.op.node_name)
def BuildHooksEnv(self):
"""Build hooks env.
......@@ -3686,13 +3687,13 @@ class LUAddNode(LogicalUnit):
node_name = self.op.node_name
cfg = self.cfg
dns_data = utils.GetHostInfo(node_name)
dns_data = netutils.GetHostInfo(node_name)
node = dns_data.name
primary_ip = self.op.primary_ip = dns_data.ip
if self.op.secondary_ip is None:
self.op.secondary_ip = primary_ip
if not utils.IsValidIP4(self.op.secondary_ip):
if not netutils.IsValidIP4(self.op.secondary_ip):
raise errors.OpPrereqError("Invalid secondary IP given",
errors.ECODE_INVAL)
secondary_ip = self.op.secondary_ip
......@@ -3744,13 +3745,13 @@ class LUAddNode(LogicalUnit):
errors.ECODE_INVAL)
# checks reachability
if not utils.TcpPing(primary_ip, constants.DEFAULT_NODED_PORT):
if not netutils.TcpPing(primary_ip, constants.DEFAULT_NODED_PORT):
raise errors.OpPrereqError("Node not reachable by ping",
errors.ECODE_ENVIRON)
if not newbie_singlehomed:
# check reachability from my secondary ip to newbie's secondary ip
if not utils.TcpPing(secondary_ip, constants.DEFAULT_NODED_PORT,
if not netutils.TcpPing(secondary_ip, constants.DEFAULT_NODED_PORT,
source=myself.secondary_ip):
raise errors.OpPrereqError("Node secondary ip not reachable by TCP"
" based ping to noded port",
......@@ -4885,7 +4886,7 @@ class LURenameInstance(LogicalUnit):
# new name verification
if self.op.check_name:
name_info = utils.GetHostInfo(self.op.new_name)
name_info = netutils.GetHostInfo(self.op.new_name)
self.op.new_name = name_info.name
new_name = self.op.new_name
......@@ -4896,7 +4897,7 @@ class LURenameInstance(LogicalUnit):
new_name, errors.ECODE_EXISTS)
if not self.op.ignore_ip:
if utils.TcpPing(name_info.ip, constants.DEFAULT_NODED_PORT):
if netutils.TcpPing(name_info.ip, constants.DEFAULT_NODED_PORT):
raise errors.OpPrereqError("IP %s of instance %s already in use" %
(name_info.ip, new_name),
errors.ECODE_NOTUNIQUE)
......@@ -6492,7 +6493,9 @@ class LUCreateInstance(LogicalUnit):
self.LogInfo("No-installation mode selected, disabling startup")
self.op.start = False
# validate/normalize the instance name
self.op.instance_name = utils.HostInfo.NormalizeName(self.op.instance_name)
self.op.instance_name = \
netutils.HostInfo.NormalizeName(self.op.instance_name)
if self.op.ip_check and not self.op.name_check:
# TODO: make the ip check more flexible and not depend on the name check
raise errors.OpPrereqError("Cannot do ip checks without a name check",
......@@ -6530,7 +6533,7 @@ class LUCreateInstance(LogicalUnit):
# instance name verification
if self.op.name_check:
self.hostname1 = utils.GetHostInfo(self.op.instance_name)
self.hostname1 = netutils.GetHostInfo(self.op.instance_name)
self.op.instance_name = self.hostname1.name
# used in CheckPrereq for ip ping check
self.check_ip = self.hostname1.ip
......@@ -6610,8 +6613,8 @@ class LUCreateInstance(LogicalUnit):
raise errors.OpPrereqError("Missing source instance name",
errors.ECODE_INVAL)
self.source_instance_name = \
utils.GetHostInfo(utils.HostInfo.NormalizeName(src_instance_name)).name
norm_name = netutils.HostInfo.NormalizeName(src_instance_name)
self.source_instance_name = netutils.GetHostInfo(norm_name).name
else:
raise errors.OpPrereqError("Invalid instance creation mode %r" %
......@@ -6955,7 +6958,7 @@ class LUCreateInstance(LogicalUnit):
errors.ECODE_INVAL)
nic_ip = self.hostname1.ip
else:
if not utils.IsValidIP4(ip):
if not netutils.IsValidIP4(ip):
raise errors.OpPrereqError("Given IP address '%s' doesn't look"
" like a valid IP" % ip,
errors.ECODE_INVAL)
......@@ -7061,7 +7064,7 @@ class LUCreateInstance(LogicalUnit):
# ip ping checks (we use the same ip that was resolved in ExpandNames)
if self.op.ip_check:
if utils.TcpPing(self.check_ip, constants.DEFAULT_NODED_PORT):
if netutils.TcpPing(self.check_ip, constants.DEFAULT_NODED_PORT):
raise errors.OpPrereqError("IP %s of instance %s already in use" %
(self.check_ip, self.op.instance_name),
errors.ECODE_NOTUNIQUE)
......@@ -8630,7 +8633,7 @@ class LUSetInstanceParams(LogicalUnit):
if nic_ip.lower() == constants.VALUE_NONE:
nic_dict['ip'] = None
else:
if not utils.IsValidIP4(nic_ip):
if not netutils.IsValidIP4(nic_ip):
raise errors.OpPrereqError("Invalid IP address '%s'" % nic_ip,
errors.ECODE_INVAL)
......
......@@ -62,6 +62,7 @@ from ganeti import errors
from ganeti import confd
from ganeti import ssconf
from ganeti import compat
from ganeti import netutils
class ConfdAsyncUDPClient(daemon.AsyncUDPSocket):
......@@ -144,7 +145,7 @@ class ConfdClient:
self._requests = {}
if self._confd_port is None:
self._confd_port = utils.GetDaemonPort(constants.CONFD)
self._confd_port = netutils.GetDaemonPort(constants.CONFD)
def UpdatePeerList(self, peers):
"""Update the list of peers
......
......@@ -44,6 +44,7 @@ from ganeti import rpc
from ganeti import objects
from ganeti import serializer
from ganeti import uidpool
from ganeti import netutils
_config_lock = locking.SharedLock()
......@@ -150,7 +151,7 @@ class ConfigWriter:
# _DistributeConfig, we compute it here once and reuse it; it's
# better to raise an error before starting to modify the config
# file than after it was modified
self._my_hostname = utils.HostInfo().name
self._my_hostname = netutils.HostInfo().name
self._last_cluster_serial = -1
self._OpenConfig()
......
......@@ -39,6 +39,7 @@ import sys
from ganeti import utils
from ganeti import constants
from ganeti import errors
from ganeti import netutils
_DEFAULT_RUN_USER = "root"
......@@ -156,7 +157,7 @@ class AsyncStreamServer(GanetiBaseAsyncoreDispatcher):
if self.family == socket.AF_UNIX:
# override the client address, as for unix sockets nothing meaningful
# is passed in from accept anyway
client_address = utils.GetSocketCredentials(connected_socket)
client_address = netutils.GetSocketCredentials(connected_socket)
logging.info("Accepted connection from %s",
FormatAddress(self.family, client_address))
self.handle_connection(connected_socket, client_address)
......@@ -552,7 +553,7 @@ def GenericMain(daemon_name, optionparser, dirs, check_fn, exec_fn,
if daemon_name in constants.DAEMONS_PORTS:
default_bind_address = constants.IP4_ADDRESS_ANY
default_port = utils.GetDaemonPort(daemon_name)
default_port = netutils.GetDaemonPort(daemon_name)
# For networked daemons we allow choosing the port and bind address
optionparser.add_option("-p", "--port", dest="port",
......
......@@ -41,6 +41,7 @@ from ganeti import objects
from ganeti import uidpool
from ganeti import ssconf
from ganeti.hypervisor import hv_base
from ganeti import netutils
class KVMHypervisor(hv_base.BaseHypervisor):
......@@ -71,7 +72,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
constants.HV_ACPI: hv_base.NO_CHECK,
constants.HV_SERIAL_CONSOLE: hv_base.NO_CHECK,
constants.HV_VNC_BIND_ADDRESS:
(False, lambda x: (utils.IsValidIP4(x) or utils.IsNormAbsPath(x)),
(False, lambda x: (netutils.IsValidIP4(x) or utils.IsNormAbsPath(x)),
"the VNC bind address must be either a valid IP address or an absolute"
" pathname", None, None),
constants.HV_VNC_TLS: hv_base.NO_CHECK,
......@@ -514,7 +515,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
vnc_bind_address = hvp[constants.HV_VNC_BIND_ADDRESS]
if vnc_bind_address:
if utils.IsValidIP4(vnc_bind_address):
if netutils.IsValidIP4(vnc_bind_address):
if instance.network_port > constants.VNC_BASE_PORT:
display = instance.network_port - constants.VNC_BASE_PORT
if vnc_bind_address == constants.IP4_ADDRESS_ANY:
......@@ -866,7 +867,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
if not alive:
raise errors.HypervisorError("Instance not running, cannot migrate")
if not utils.TcpPing(target, port, live_port_needed=True):
if not netutils.TcpPing(target, port, live_port_needed=True):
raise errors.HypervisorError("Remote host %s not listening on port"
" %s, cannot migrate" % (target, port))
......
......@@ -30,6 +30,7 @@ from ganeti import constants
from ganeti import errors
from ganeti import utils
from ganeti.hypervisor import hv_base
from ganeti import netutils
class XenHypervisor(hv_base.BaseHypervisor):
......@@ -409,7 +410,7 @@ class XenHypervisor(hv_base.BaseHypervisor):
port = instance.hvparams[constants.HV_MIGRATION_PORT]
if not utils.TcpPing(target, port, live_port_needed=True):
if not netutils.TcpPing(target, port, live_port_needed=True):
raise errors.HypervisorError("Remote host %s not listening on port"
" %s, cannot migrate" % (target, port))
......@@ -549,7 +550,7 @@ class XenHvmHypervisor(XenHypervisor):
hv_base.ParamInSet(True, constants.HT_HVM_VALID_NIC_TYPES),
constants.HV_PAE: hv_base.NO_CHECK,
constants.HV_VNC_BIND_ADDRESS:
(False, utils.IsValidIP4,
(False, netutils.IsValidIP4,
"VNC bind address is not a valid IP address", None, None),
constants.HV_KERNEL_PATH: hv_base.REQ_FILE_CHECK,
constants.HV_DEVICE_MODEL: hv_base.REQ_FILE_CHECK,
......
......@@ -53,6 +53,7 @@ from ganeti import mcpu
from ganeti import utils
from ganeti import jstore
from ganeti import rpc
from ganeti import netutils
JOBQUEUE_THREADS = 25
......@@ -762,7 +763,7 @@ class JobQueue(object):
"""
self.context = context
self._memcache = weakref.WeakValueDictionary()
self._my_hostname = utils.HostInfo().name
self._my_hostname = netutils.HostInfo().name
# The Big JobQueue lock. If a code block or method acquires it in shared
# mode safe it must guarantee concurrency with all the code acquiring it in
......
......@@ -32,6 +32,7 @@ from ganeti import errors
from ganeti import compat
from ganeti import utils
from ganeti import objects
from ganeti import netutils
class _ImportExportError(Exception):
......@@ -1553,7 +1554,7 @@ def CheckRemoteExportDiskInfo(cds, disk_index, disk_info):
if not utils.VerifySha1Hmac(cds, msg, hmac_digest, salt=hmac_salt):
raise errors.GenericError("HMAC is wrong")
return (utils.HostInfo.NormalizeName(host),
return (netutils.HostInfo.NormalizeName(host),
utils.ValidateServiceName(port),
magic)
......
#
#
# Copyright (C) 2010 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
"""Ganeti network utility module.
This module holds functions that can be used in both daemons (all) and
the command line scripts.
"""
import errno
import re
import socket
import struct
import IN
from ganeti import constants
from ganeti import errors
# Structure definition for getsockopt(SOL_SOCKET, SO_PEERCRED, ...):
# struct ucred { pid_t pid; uid_t uid; gid_t gid; };
#
# The GNU C Library defines gid_t and uid_t to be "unsigned int" and
# pid_t to "int".
#
# IEEE Std 1003.1-2008:
# "nlink_t, uid_t, gid_t, and id_t shall be integer types"
# "blksize_t, pid_t, and ssize_t shall be signed integer types"
_STRUCT_UCRED = "iII"
_STRUCT_UCRED_SIZE = struct.calcsize(_STRUCT_UCRED)
def GetSocketCredentials(sock):
"""Returns the credentials of the foreign process connected to a socket.
@param sock: Unix socket
@rtype: tuple; (number, number, number)
@return: The PID, UID and GID of the connected foreign process.
"""
peercred = sock.getsockopt(socket.SOL_SOCKET, IN.SO_PEERCRED,
_STRUCT_UCRED_SIZE)
return struct.unpack(_STRUCT_UCRED, peercred)
def GetHostInfo(name=None):
"""Lookup host name and raise an OpPrereqError for failures"""
try:
return HostInfo(name)
except errors.ResolverError, err:
raise errors.OpPrereqError("The given name (%s) does not resolve: %s" %
(err[0], err[2]), errors.ECODE_RESOLVER)
class HostInfo:
"""Class implementing resolver and hostname functionality
"""