#930: OGAgent for ogLive can launch the Browser.
parent
3642196f14
commit
582ab7873b
|
@ -41,7 +41,6 @@ import urllib
|
||||||
from opengnsys import REST
|
from opengnsys import REST
|
||||||
from opengnsys import operations
|
from opengnsys import operations
|
||||||
from opengnsys.log import logger
|
from opengnsys.log import logger
|
||||||
from opengnsys.scriptThread import ScriptExecutorThread
|
|
||||||
from opengnsys.workers import ServerWorker
|
from opengnsys.workers import ServerWorker
|
||||||
from six.moves.urllib import parse
|
from six.moves.urllib import parse
|
||||||
|
|
||||||
|
@ -167,6 +166,46 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
'config': operations.get_configuration()})
|
'config': operations.get_configuration()})
|
||||||
self._launch_browser(menu_url)
|
self._launch_browser(menu_url)
|
||||||
|
|
||||||
|
def _launch_browser(self, url):
|
||||||
|
"""
|
||||||
|
Launchs the Browser with specified URL
|
||||||
|
:param url: URL to show
|
||||||
|
"""
|
||||||
|
logger.debug('Launching browser with URL: {}'.format(url))
|
||||||
|
if hasattr(self.browser, 'process'):
|
||||||
|
self.browser['process'].kill()
|
||||||
|
self.browser['url'] = url
|
||||||
|
self.browser['process'] = subprocess.Popen(['browser', '-qws', url])
|
||||||
|
|
||||||
|
def _task_command(self, route, code, op_id):
|
||||||
|
"""
|
||||||
|
Task to execute a command and return results to a server URI
|
||||||
|
:param route: server callback REST route to return results
|
||||||
|
:param code: code to execute
|
||||||
|
:param op_id: operation id.
|
||||||
|
"""
|
||||||
|
menu_url = ''
|
||||||
|
# Show execution tacking log, if OGAgent runs on ogLive
|
||||||
|
os_type = operations.os_type.lower()
|
||||||
|
if os_type == 'oglive':
|
||||||
|
menu_url = self.browser['url']
|
||||||
|
self._launch_browser('http://localhost/cgi-bin/httpd-log.sh')
|
||||||
|
# Executing command
|
||||||
|
(stat, out, err) = operations.exec_command(code)
|
||||||
|
# Removing command from the list
|
||||||
|
for c in self.commands:
|
||||||
|
if c.getName() == op_id:
|
||||||
|
self.commands.remove(c)
|
||||||
|
# Removing the REST API prefix, if needed
|
||||||
|
if route.startswith(self.REST.endpoint):
|
||||||
|
route = route[len(self.REST.endpoint):]
|
||||||
|
# Sending results
|
||||||
|
self.REST.sendMessage(route, {'mac': self.interface.mac, 'ip': self.interface.ip, 'trace': op_id,
|
||||||
|
'status': stat, 'output': out, 'error': err})
|
||||||
|
# Show latest menu, if OGAgent runs on ogLive
|
||||||
|
if os_type == 'oglive':
|
||||||
|
self._launch_browser(menu_url)
|
||||||
|
|
||||||
def onActivation(self):
|
def onActivation(self):
|
||||||
"""
|
"""
|
||||||
Sends OGAgent activation notification to OpenGnsys server
|
Sends OGAgent activation notification to OpenGnsys server
|
||||||
|
@ -222,21 +261,11 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
logger.debug('Successful connection after {} tries'.format(t))
|
logger.debug('Successful connection after {} tries'.format(t))
|
||||||
elif t == 100:
|
elif t == 100:
|
||||||
raise Exception('Initialization error: Cannot connect to remote server')
|
raise Exception('Initialization error: Cannot connect to remote server')
|
||||||
# Delete marking files
|
# Completing OGAgent initialization process
|
||||||
for f in ['ogboot.me', 'ogboot.firstboot', 'ogboot.secondboot']:
|
os_type = operations.os_type.lower()
|
||||||
try:
|
if os_type == 'oglive':
|
||||||
os.remove(os.sep + f)
|
### Following code may be separated in a different function to launch browser while catching disk configuration
|
||||||
except OSError:
|
message = """
|
||||||
pass
|
|
||||||
# Copy file "HostsFile.FirstOctetOfIPAddress" to "HostsFile", if it exists
|
|
||||||
# (used in "exam mode" from the University of Seville)
|
|
||||||
hosts_file = os.path.join(operations.get_etc_path(), 'hosts')
|
|
||||||
new_hosts_file = hosts_file + '.' + self.interface.ip.split('.')[0]
|
|
||||||
if os.path.isfile(new_hosts_file):
|
|
||||||
shutil.copyfile(new_hosts_file, hosts_file)
|
|
||||||
### Separate in a different function to launch browser while catching disk configuration
|
|
||||||
# Create HTML file (TEMPORARY)
|
|
||||||
message = """
|
|
||||||
<html>
|
<html>
|
||||||
<head></head>
|
<head></head>
|
||||||
<style>
|
<style>
|
||||||
|
@ -265,14 +294,27 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
"""
|
"""
|
||||||
#f = open('/tmp/init.html', 'w')
|
f = open('/tmp/init.html', 'w')
|
||||||
#f.write(message)
|
f.write(message)
|
||||||
#f.close()
|
f.close()
|
||||||
# Launch browser
|
# Launch the Browser
|
||||||
#subprocess.Popen(['browser', '-qws', '/tmp/init.html'])
|
self._launch_browser('/tmp/init.html')
|
||||||
#config = operations.get_configuration()
|
config = operations.get_configuration()
|
||||||
#self.REST.sendMessage('clients/config', {'mac': self.interface.mac, 'ip': self.interface.ip,
|
self.REST.sendMessage('ogagent/config', {'mac': self.interface.mac, 'ip': self.interface.ip,
|
||||||
# 'config': config})
|
'config': config})
|
||||||
|
else:
|
||||||
|
# Delete marking files
|
||||||
|
for f in ['ogboot.me', 'ogboot.firstboot', 'ogboot.secondboot']:
|
||||||
|
try:
|
||||||
|
os.remove(os.sep + f)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
# Copy file "HostsFile.FirstOctetOfIPAddress" to "HostsFile", if it exists
|
||||||
|
# (used in "exam mode" from the University of Seville)
|
||||||
|
hosts_file = os.path.join(operations.get_etc_path(), 'hosts')
|
||||||
|
new_hosts_file = hosts_file + '.' + self.interface.ip.split('.')[0]
|
||||||
|
if os.path.isfile(new_hosts_file):
|
||||||
|
shutil.copyfile(new_hosts_file, hosts_file)
|
||||||
|
|
||||||
def onDeactivation(self):
|
def onDeactivation(self):
|
||||||
"""
|
"""
|
||||||
|
@ -346,7 +388,7 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
res['status'] = ''
|
res['status'] = ''
|
||||||
# Check if OpenGnsys Client is busy
|
# Check if OpenGnsys Client is busy
|
||||||
if res['status'] == 'oglive' and self.locked:
|
if res['status'] == 'oglive' and len(self.commands) > 0:
|
||||||
res['status'] = 'busy'
|
res['status'] = 'busy'
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
@ -400,15 +442,27 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
:return: JSON object {"op": "launched"}
|
:return: JSON object {"op": "launched"}
|
||||||
"""
|
"""
|
||||||
logger.debug('Processing script request')
|
logger.debug('Processing script request')
|
||||||
# Decoding script
|
|
||||||
script = urllib.unquote(post_params.get('script').decode('base64')).decode('utf8')
|
# Processing data
|
||||||
script = 'import subprocess; subprocess.check_output("""{}""",shell=True)'.format(script)
|
try:
|
||||||
# Executing script.
|
script = urllib.unquote(post_params.get('script').decode('base64')).decode('utf8')
|
||||||
if post_params.get('client', 'false') == 'false':
|
op_id = post_params.get('id')
|
||||||
thr = ScriptExecutorThread(script)
|
route = post_params.get('redirect_uri')
|
||||||
thr.start()
|
# Checking if the thread id. exists
|
||||||
else:
|
for c in self.commands:
|
||||||
self.sendClientMessage('script', {'code': script})
|
if c.getName() == str(op_id):
|
||||||
|
raise Exception('Task id. already exists: {}'.format(op_id))
|
||||||
|
if post_params.get('client', 'false') == 'false':
|
||||||
|
# Launching a new thread
|
||||||
|
thr = threading.Thread(name=op_id, target=self._task_command, args=(route, script, op_id))
|
||||||
|
thr.start()
|
||||||
|
self.commands.append(thr)
|
||||||
|
else:
|
||||||
|
# Executing as normal user
|
||||||
|
self.sendClientMessage('script', {'code': script})
|
||||||
|
except Exception as e:
|
||||||
|
logger.error('Got exception {}'.format(e))
|
||||||
|
return {'error': e}
|
||||||
return {'op': 'launched'}
|
return {'op': 'launched'}
|
||||||
|
|
||||||
@check_secret
|
@check_secret
|
||||||
|
@ -434,6 +488,7 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
def process_client_popup(self, params):
|
def process_client_popup(self, params):
|
||||||
self.REST.sendMessage('popup_done', params)
|
self.REST.sendMessage('popup_done', params)
|
||||||
|
|
||||||
|
@check_secret
|
||||||
def process_config(self, path, get_params, post_params, server):
|
def process_config(self, path, get_params, post_params, server):
|
||||||
"""
|
"""
|
||||||
Returns client configuration
|
Returns client configuration
|
||||||
|
@ -447,27 +502,26 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
storage = [] # Storage configuration
|
storage = [] # Storage configuration
|
||||||
warnings = 0 # Number of warnings
|
warnings = 0 # Number of warnings
|
||||||
logger.debug('Received getconfig operation')
|
logger.debug('Received getconfig operation')
|
||||||
self.checkSecret(server)
|
|
||||||
# Processing data
|
# Processing data
|
||||||
for row in operations.get_configuration().split(';'):
|
for row in operations.get_configuration().split(';'):
|
||||||
cols = row.split(':')
|
cols = row.split(':')
|
||||||
if len(cols) == 1:
|
if len(cols) == 1:
|
||||||
if cols[0] != '':
|
if cols[0] != '':
|
||||||
# Serial number
|
# Serial number
|
||||||
serialno = cols[0]
|
serial_no = cols[0]
|
||||||
else:
|
else:
|
||||||
# Skip blank rows
|
# Skip blank rows
|
||||||
pass
|
pass
|
||||||
elif len(cols) == 7:
|
elif len(cols) == 7:
|
||||||
disk, npart, tpart, fs, opsys, size, usage = cols
|
disk, part_no, part_type, fs, op_sys, size, usage = cols
|
||||||
try:
|
try:
|
||||||
if int(npart) == 0:
|
if int(npart) == 0:
|
||||||
# Disk information
|
# Disk information
|
||||||
storage.append({'disk': int(disk), 'parttable': int(tpart), 'size': int(size)})
|
storage.append({'disk': int(disk), 'parttable': int(part_type), 'size': int(size)})
|
||||||
else:
|
else:
|
||||||
# Partition information
|
# Partition information
|
||||||
storage.append({'disk': int(disk), 'partition': int(npart), 'parttype': tpart,
|
storage.append({'disk': int(disk), 'partition': int(part_no), 'parttype': part_type,
|
||||||
'filesystem': fs, 'operatingsystem': opsys, 'size': int(size),
|
'filesystem': fs, 'operatingsystem': op_sys, 'size': int(size),
|
||||||
'usage': int(usage)})
|
'usage': int(usage)})
|
||||||
except ValueError:
|
except ValueError:
|
||||||
logger.warn('Configuration parameter error: {}'.format(cols))
|
logger.warn('Configuration parameter error: {}'.format(cols))
|
||||||
|
@ -477,25 +531,9 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
logger.warn('Configuration data error: {}'.format(cols))
|
logger.warn('Configuration data error: {}'.format(cols))
|
||||||
warnings += 1
|
warnings += 1
|
||||||
# Returning configuration data and count of warnings
|
# Returning configuration data and count of warnings
|
||||||
return {'serialno': serialno, 'storage': storage, 'warnings': warnings}
|
return {'serial': serial_no, 'storage': storage, 'warnings': warnings}
|
||||||
|
|
||||||
def task_command(self, code, route, op_id):
|
|
||||||
"""
|
|
||||||
Task to execute a command
|
|
||||||
:param code: Code to execute
|
|
||||||
:param route: server callback REST route to return results
|
|
||||||
:param op_id: operation id.
|
|
||||||
"""
|
|
||||||
# Executing command
|
|
||||||
(stat, out, err) = operations.exec_command(code)
|
|
||||||
# Removing command from the list
|
|
||||||
for c in self.commands:
|
|
||||||
if c.getName() == op_id:
|
|
||||||
self.commands.remove(c)
|
|
||||||
# Sending results
|
|
||||||
self.REST.sendMessage(route, {'client': self.interface.ip, 'trace': op_id, 'status': stat, 'output': out,
|
|
||||||
'error': err})
|
|
||||||
|
|
||||||
|
@check_secret
|
||||||
def process_command(self, path, get_params, post_params, server):
|
def process_command(self, path, get_params, post_params, server):
|
||||||
"""
|
"""
|
||||||
Launches a thread to executing a command
|
Launches a thread to executing a command
|
||||||
|
@ -509,7 +547,6 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
:rtype: object with launching status
|
:rtype: object with launching status
|
||||||
"""
|
"""
|
||||||
logger.debug('Received command operation with params: {}'.format(post_params))
|
logger.debug('Received command operation with params: {}'.format(post_params))
|
||||||
self.checkSecret(server)
|
|
||||||
# Processing data
|
# Processing data
|
||||||
try:
|
try:
|
||||||
script = post_params.get('script')
|
script = post_params.get('script')
|
||||||
|
@ -528,6 +565,7 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
return {'error': e}
|
return {'error': e}
|
||||||
return {'op': 'launched'}
|
return {'op': 'launched'}
|
||||||
|
|
||||||
|
@check_secret
|
||||||
def process_execinfo(self, path, get_params, post_params, server):
|
def process_execinfo(self, path, get_params, post_params, server):
|
||||||
"""
|
"""
|
||||||
Returns running commands information
|
Returns running commands information
|
||||||
|
@ -539,16 +577,15 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
"""
|
"""
|
||||||
data = []
|
data = []
|
||||||
logger.debug('Received execinfo operation')
|
logger.debug('Received execinfo operation')
|
||||||
self.checkSecret(server)
|
|
||||||
# Returning the arguments of all running threads
|
# Returning the arguments of all running threads
|
||||||
for c in self.commands:
|
for c in self.commands:
|
||||||
if c.is_alive():
|
if c.is_alive():
|
||||||
data.append(c.__dict__['_Thread__args'])
|
data.append(c.__dict__['_Thread__args'])
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
@check_secret
|
||||||
def process_stopcmd(self, path, get_params, post_params, server):
|
def process_stopcmd(self, path, get_params, post_params, server):
|
||||||
logger.debug('Received stopcmd operation with params {}:'.format(post_params))
|
logger.debug('Received stopcmd operation with params {}:'.format(post_params))
|
||||||
self.checkSecret(server)
|
|
||||||
op_id = post_params.get('trace')
|
op_id = post_params.get('trace')
|
||||||
for c in self.commands:
|
for c in self.commands:
|
||||||
if c.is_alive() and c.getName() == str(op_id):
|
if c.is_alive() and c.getName() == str(op_id):
|
||||||
|
@ -556,6 +593,7 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
return {"stopped": op_id}
|
return {"stopped": op_id}
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
@check_secret
|
||||||
def process_hardware(self, path, get_params, post_params, server):
|
def process_hardware(self, path, get_params, post_params, server):
|
||||||
"""
|
"""
|
||||||
Returns client's hardware profile
|
Returns client's hardware profile
|
||||||
|
@ -576,6 +614,7 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
# Return list of hardware components
|
# Return list of hardware components
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
@check_secret
|
||||||
def process_software(self, path, get_params, post_params, server):
|
def process_software(self, path, get_params, post_params, server):
|
||||||
"""
|
"""
|
||||||
Returns software profile installed on an operating system
|
Returns software profile installed on an operating system
|
||||||
|
|
Loading…
Reference in New Issue