mirror of
https://github.com/xcat2/confluent.git
synced 2025-01-16 20:57:53 +00:00
Merge branch 'master' into clustertime
This commit is contained in:
commit
fa24622704
@ -763,7 +763,10 @@ def conserver_command(filehandle, localcommand):
|
||||
|
||||
def get_command_bytes(filehandle, localcommand, cmdlen):
|
||||
while len(localcommand) < cmdlen:
|
||||
ready, _, _ = select.select((filehandle,), (), (), 1)
|
||||
try:
|
||||
ready, _, _ = select.select((filehandle,), (), (), 1)
|
||||
except select.error:
|
||||
ready = ()
|
||||
if ready:
|
||||
localcommand += filehandle.read()
|
||||
return localcommand
|
||||
@ -776,7 +779,10 @@ def check_escape_seq(currinput, filehandle):
|
||||
sys.stdout.flush()
|
||||
return conserver_command(
|
||||
filehandle, currinput[len(conserversequence):])
|
||||
ready, _, _ = select.select((filehandle,), (), (), 3)
|
||||
try:
|
||||
ready, _, _ = select.select((filehandle,), (), (), 3)
|
||||
except select.error:
|
||||
ready = ()
|
||||
if not ready: # 3 seconds of no typing
|
||||
break
|
||||
currinput += filehandle.read()
|
||||
@ -866,8 +872,11 @@ def check_power_state():
|
||||
|
||||
while inconsole or not doexit:
|
||||
if inconsole:
|
||||
rdylist, _, _ = select.select(
|
||||
(sys.stdin, session.connection), (), (), 10)
|
||||
try:
|
||||
rdylist, _, _ = select.select(
|
||||
(sys.stdin, session.connection), (), (), 10)
|
||||
except select.error:
|
||||
rdylist = ()
|
||||
for fh in rdylist:
|
||||
if fh == session.connection:
|
||||
# this only should get called in the
|
||||
|
@ -67,6 +67,8 @@ cfgpaths = {
|
||||
'bmc.ipv4_gateway': (
|
||||
'configuration/management_controller/net_interfaces/management',
|
||||
'ipv4_gateway'),
|
||||
'bmc.hostname': (
|
||||
'configuration/management_controller/hostname', 'hostname'),
|
||||
}
|
||||
|
||||
autodeps = {
|
||||
|
@ -86,7 +86,7 @@ def run():
|
||||
desc = pipedesc[r]
|
||||
node = desc['node']
|
||||
data = True
|
||||
while data and select.select([r], [], [], 0):
|
||||
while data and select.select([r], [], [], 0)[0]:
|
||||
data = r.readline()
|
||||
if data:
|
||||
if desc['type'] == 'stdout':
|
||||
|
@ -1 +0,0 @@
|
||||
__version__ = "1.5.0.dev395.ggacb3a20"
|
@ -1684,19 +1684,33 @@ def restore_db_from_directory(location, password):
|
||||
if e.errno == 2:
|
||||
raise Exception("Cannot restore without keys, this may be a "
|
||||
"redacted dump")
|
||||
try:
|
||||
moreglobals = json.load(open(os.path.join(location, 'globals.json')))
|
||||
for globvar in moreglobals:
|
||||
set_global(globvar, moreglobals[globvar])
|
||||
except IOError as e:
|
||||
if e.errno != 2:
|
||||
raise
|
||||
with open(os.path.join(location, 'main.json'), 'r') as cfgfile:
|
||||
cfgdata = cfgfile.read()
|
||||
ConfigManager(tenant=None)._load_from_json(cfgdata)
|
||||
|
||||
|
||||
def dump_db_to_directory(location, password, redact=None):
|
||||
if not redact:
|
||||
def dump_db_to_directory(location, password, redact=None, skipkeys=False):
|
||||
if not redact and not skipkeys:
|
||||
with open(os.path.join(location, 'keys.json'), 'w') as cfgfile:
|
||||
cfgfile.write(_dump_keys(password))
|
||||
cfgfile.write('\n')
|
||||
with open(os.path.join(location, 'main.json'), 'w') as cfgfile:
|
||||
cfgfile.write(ConfigManager(tenant=None)._dump_to_json(redact=redact))
|
||||
cfgfile.write('\n')
|
||||
bkupglobals = {}
|
||||
for globvar in _cfgstore['globals']:
|
||||
if globvar.endswith('_key'):
|
||||
continue
|
||||
bkupglobals[globvar] = _cfgstore['globals'][globvar]
|
||||
if bkupglobals:
|
||||
json.dump(bkupglobals, open(os.path.join(location, 'globals.json')))
|
||||
try:
|
||||
for tenant in os.listdir(
|
||||
os.path.join(ConfigManager._cfgdir, '/tenants/')):
|
||||
|
@ -154,6 +154,10 @@ def _init_core():
|
||||
'pluginattrs': ['hardwaremanagement.method'],
|
||||
'default': 'ipmi',
|
||||
}),
|
||||
'hostname': PluginRoute({
|
||||
'pluginattrs': ['hardwaremanagement.method'],
|
||||
'default': 'ipmi',
|
||||
}),
|
||||
'identifier': PluginRoute({
|
||||
'pluginattrs': ['hardwaremanagement.method'],
|
||||
'default': 'ipmi',
|
||||
|
@ -85,6 +85,7 @@ import eventlet
|
||||
import eventlet.greenpool
|
||||
import eventlet.semaphore
|
||||
|
||||
autosensors = set()
|
||||
class nesteddict(dict):
|
||||
|
||||
def __missing__(self, key):
|
||||
@ -350,7 +351,28 @@ def _parameterize_path(pathcomponents):
|
||||
return validselectors, keyparams, listrequested, childcoll
|
||||
|
||||
|
||||
def handle_autosense_config(operation, inputdata):
|
||||
autosense = cfm.get_global('discovery.autosense')
|
||||
autosense = autosense or autosense is None
|
||||
if operation == 'retrieve':
|
||||
yield msg.KeyValueData({'enabled': autosense})
|
||||
elif operation == 'update':
|
||||
enabled = inputdata['enabled']
|
||||
if type(enabled) in (unicode, str):
|
||||
enabled = enabled.lower() in ('true', '1', 'y', 'yes', 'enable',
|
||||
'enabled')
|
||||
if autosense == enabled:
|
||||
return
|
||||
cfm.set_global('discovery.autosense', enabled)
|
||||
if enabled:
|
||||
start_autosense()
|
||||
else:
|
||||
stop_autosense()
|
||||
|
||||
|
||||
def handle_api_request(configmanager, inputdata, operation, pathcomponents):
|
||||
if pathcomponents == ['discovery', 'autosense']:
|
||||
return handle_autosense_config(operation, inputdata)
|
||||
if operation == 'retrieve':
|
||||
return handle_read_api_request(pathcomponents)
|
||||
elif (operation in ('update', 'create') and
|
||||
@ -398,6 +420,7 @@ def handle_read_api_request(pathcomponents):
|
||||
if len(pathcomponents) == 1:
|
||||
dirlist = [msg.ChildCollection(x + '/') for x in sorted(list(subcats))]
|
||||
dirlist.append(msg.ChildCollection('rescan'))
|
||||
dirlist.append(msg.ChildCollection('autosense'))
|
||||
return dirlist
|
||||
if not coll:
|
||||
return show_info(queryparms['by-mac'])
|
||||
@ -695,6 +718,9 @@ def get_chained_smm_name(nodename, cfg, handler, nl=None, checkswitch=True):
|
||||
smmaddr = cd[nodename]['hardwaremanagement.manager']['value']
|
||||
pkey = cd[nodename].get('pubkeys.tls_hardwaremanager', {}).get(
|
||||
'value', None)
|
||||
if not pkey:
|
||||
# We cannot continue through a break in the chain
|
||||
return None, False
|
||||
if pkey:
|
||||
cv = util.TLSCertVerifier(
|
||||
cfg, nodename, 'pubkeys.tls_hardwaremanager').verify_cert
|
||||
@ -1075,12 +1101,14 @@ def newnodes(added, deleting, configmanager):
|
||||
global attribwatcher
|
||||
global needaddhandled
|
||||
global nodeaddhandler
|
||||
_map_unique_ids()
|
||||
configmanager.remove_watcher(attribwatcher)
|
||||
allnodes = configmanager.list_nodes()
|
||||
attribwatcher = configmanager.watch_attributes(
|
||||
allnodes, ('discovery.policy', 'net*.switch',
|
||||
'hardwaremanagement.manager', 'net*.switchport', 'id.uuid',
|
||||
'pubkeys.tls_hardwaremanager', 'net*.bootable'), _recheck_nodes)
|
||||
'hardwaremanagement.manager', 'net*.switchport',
|
||||
'id.uuid', 'pubkeys.tls_hardwaremanager',
|
||||
'net*.bootable'), _recheck_nodes)
|
||||
if nodeaddhandler:
|
||||
needaddhandled = True
|
||||
else:
|
||||
@ -1126,14 +1154,23 @@ def start_detection():
|
||||
'hardwaremanagement.manager', 'net*.switchport', 'id.uuid',
|
||||
'pubkeys.tls_hardwaremanager'), _recheck_nodes)
|
||||
cfg.watch_nodecollection(newnodes)
|
||||
eventlet.spawn_n(slp.snoop, safe_detected)
|
||||
eventlet.spawn_n(pxe.snoop, safe_detected)
|
||||
autosense = cfm.get_global('discovery.autosense')
|
||||
if autosense or autosense is None:
|
||||
start_autosense()
|
||||
if rechecker is None:
|
||||
rechecktime = util.monotonic_time() + 900
|
||||
rechecker = eventlet.spawn_after(900, _periodic_recheck, cfg)
|
||||
|
||||
# eventlet.spawn_n(ssdp.snoop, safe_detected)
|
||||
|
||||
def stop_autosense():
|
||||
for watcher in list(autosensors):
|
||||
watcher.kill()
|
||||
autosensors.discard(watcher)
|
||||
|
||||
def start_autosense():
|
||||
autosensors.add(eventlet.spawn(slp.snoop, safe_detected))
|
||||
autosensors.add(eventlet.spawn(pxe.snoop, safe_detected))
|
||||
|
||||
|
||||
nodes_by_fprint = {}
|
||||
|
@ -191,7 +191,6 @@ def _parse_ssdp(peer, rsp, peerdata):
|
||||
_, code, _ = headlines[0].split(' ', 2)
|
||||
except ValueError:
|
||||
return
|
||||
myurl = None
|
||||
if code == '200':
|
||||
if nid in peerdata:
|
||||
peerdatum = peerdata[nid]
|
||||
@ -208,7 +207,6 @@ def _parse_ssdp(peer, rsp, peerdata):
|
||||
header = header.strip()
|
||||
value = value.strip()
|
||||
if header == 'AL' or header == 'LOCATION':
|
||||
myurl = value
|
||||
if 'urls' not in peerdatum:
|
||||
peerdatum['urls'] = [value]
|
||||
elif value not in peerdatum['urls']:
|
||||
|
@ -397,6 +397,9 @@ def get_input_message(path, operation, inputdata, nodes=None, multinode=False,
|
||||
elif (path[:3] == ['configuration', 'management_controller', 'identifier']
|
||||
and operation != 'retrieve'):
|
||||
return InputMCI(path, nodes, inputdata)
|
||||
elif (path[:3] == ['configuration', 'management_controller', 'hostname']
|
||||
and operation != 'retrieve'):
|
||||
return InputHostname(path, nodes, inputdata, configmanager)
|
||||
elif (path[:4] == ['configuration', 'management_controller',
|
||||
'net_interfaces', 'management'] and operation != 'retrieve'):
|
||||
return InputNetworkConfiguration(path, nodes, inputdata,
|
||||
@ -719,6 +722,25 @@ class InputBMCReset(ConfluentInputMessage):
|
||||
return self.inputbynode[node]
|
||||
|
||||
|
||||
|
||||
class InputHostname(ConfluentInputMessage):
|
||||
def __init__(self, path, nodes, inputdata, configmanager):
|
||||
self.inputbynode = {}
|
||||
self.stripped = False
|
||||
if not inputdata or 'hostname' not in inputdata:
|
||||
raise exc.InvalidArgumentException('missing hostname attribute')
|
||||
if nodes is None:
|
||||
raise exc.InvalidArgumentException(
|
||||
'This only supports per-node input')
|
||||
for expanded in configmanager.expand_attrib_expression(
|
||||
nodes, inputdata['hostname']):
|
||||
node, value = expanded
|
||||
self.inputbynode[node] = value
|
||||
|
||||
def hostname(self, node):
|
||||
return self.inputbynode[node]
|
||||
|
||||
|
||||
class InputMCI(ConfluentInputMessage):
|
||||
def __init__(self, path, nodes, inputdata):
|
||||
self.inputbynode = {}
|
||||
@ -1298,6 +1320,17 @@ class MCI(ConfluentMessage):
|
||||
self.kvpairs = {name: kv}
|
||||
|
||||
|
||||
class Hostname(ConfluentMessage):
|
||||
def __init__(self, name=None, hostname=None):
|
||||
self.notnode = name is None
|
||||
self.desc = 'BMC hostname'
|
||||
|
||||
kv = {'hostname': {'value': hostname}}
|
||||
if self.notnode:
|
||||
self.kvpairs = kv
|
||||
else:
|
||||
self.kvpairs = {name: kv}
|
||||
|
||||
class DomainName(ConfluentMessage):
|
||||
def __init__(self, name=None, dn=None):
|
||||
self.notnode = name is None
|
||||
|
@ -344,7 +344,7 @@ def perform_request(operator, node, element,
|
||||
cfg, results).handle_request()
|
||||
except pygexc.IpmiException as ipmiexc:
|
||||
excmsg = str(ipmiexc)
|
||||
if excmsg == 'Session no longer connected':
|
||||
if excmsg in ('Session no longer connected', 'timeout'):
|
||||
results.put(msg.ConfluentTargetTimeout(node))
|
||||
else:
|
||||
results.put(msg.ConfluentNodeError(node, excmsg))
|
||||
@ -518,6 +518,8 @@ class IpmiHandler(object):
|
||||
return self.handle_reset()
|
||||
elif self.element[1:3] == ['management_controller', 'identifier']:
|
||||
return self.handle_identifier()
|
||||
elif self.element[1:3] == ['management_controller', 'hostname']:
|
||||
return self.handle_hostname()
|
||||
elif self.element[1:3] == ['management_controller', 'domain_name']:
|
||||
return self.handle_domain_name()
|
||||
elif self.element[1:3] == ['management_controller', 'ntp']:
|
||||
@ -986,6 +988,16 @@ class IpmiHandler(object):
|
||||
self.ipmicmd.set_mci(mci)
|
||||
return
|
||||
|
||||
def handle_hostname(self):
|
||||
if 'read' == self.op:
|
||||
hostname = self.ipmicmd.get_hostname()
|
||||
self.output.put(msg.Hostname(self.node, hostname))
|
||||
return
|
||||
elif 'update' == self.op:
|
||||
hostname = self.inputdata.hostname(self.node)
|
||||
self.ipmicmd.set_hostname(hostname)
|
||||
return
|
||||
|
||||
def handle_domain_name(self):
|
||||
if 'read' == self.op:
|
||||
dn = self.ipmicmd.get_domain_name()
|
||||
|
@ -12,7 +12,7 @@ Group: Development/Libraries
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
|
||||
Prefix: %{_prefix}
|
||||
BuildArch: noarch
|
||||
Requires: python-pyghmi >= 1.0.34, python-eventlet, python-greenlet, python-crypto >= 2.6.1, confluent_client, pyparsing, python-paramiko, python-dns, python-netifaces, python2-pyasn1 >= 0.2.3, python-pysnmp >= 4.3.4, python-pyte, python-lxml, python-eficompressor
|
||||
Requires: python-pyghmi >= 1.0.34, python-eventlet, python-greenlet, python-crypto >= 2.6.1, confluent_client, python-pyparsing, python-paramiko, python-dns, python-netifaces, python2-pyasn1 >= 0.2.3, python-pysnmp >= 4.3.4, python-pyte, python-lxml, python-eficompressor
|
||||
Vendor: Jarrod Johnson <jjohnson2@lenovo.com>
|
||||
Url: http://xcat.sf.net/
|
||||
|
||||
|
@ -6,4 +6,6 @@ if [ "$NUMCOMMITS" != "$VERSION" ]; then
|
||||
fi
|
||||
echo $VERSION > VERSION
|
||||
sed -e "s/#VERSION#/$VERSION/" setup.py.tmpl > setup.py
|
||||
echo '__version__ = "'$VERSION'"' > confluent/__init__.py
|
||||
if [ -f confluent/client.py ]; then
|
||||
echo '__version__ = "'$VERSION'"' > confluent/__init__.py
|
||||
fi
|
||||
|
@ -17,7 +17,8 @@ setup(
|
||||
'confluent/plugins/shell/',
|
||||
'confluent/plugins/configuration/'],
|
||||
install_requires=['paramiko', 'pycrypto>=2.6', 'confluent_client>=0.1.0', 'eventlet',
|
||||
'pyghmi>=0.6.5'],
|
||||
'dnspython', 'netifaces', 'pyte', 'pysnmp', 'pyparsing',
|
||||
'pyghmi>=1.0.44'],
|
||||
scripts=['bin/confluent', 'bin/confluentdbutil'],
|
||||
data_files=[('/etc/init.d', ['sysvinit/confluent']),
|
||||
('/usr/lib/sysctl.d', ['sysctl/confluent.conf']),
|
||||
|
Loading…
x
Reference in New Issue
Block a user