Release 0.5.0:
- added support for wstun allowlist - fixed nginx proxy - added GDB management patch - added DeviceFactoryReset RPC - added action to force certificates renewing - added ServicesStatus RPC - added support Arancino device layout - updated info API and status page: webservices list added - fixed deploy scripts - updated UI - fixed rest_manager - updated plugin_manager - added checks in modules loader - fixed device_bkp_rest script (restore function) - rest submit action added - updated info and status APIs - Zuul Openstack CI configuration upgraded Change-Id: I7d5398c2eb8c5d759f2488166a4016c5fcad35d1
This commit is contained in:
parent
f5fa5454dd
commit
47d682fff5
|
@ -77,6 +77,7 @@ class PamResp(Structure):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<PamResp %i '%s'>" % (self.resp_retcode, self.resp)
|
return "<PamResp %i '%s'>" % (self.resp_retcode, self.resp)
|
||||||
|
|
||||||
|
|
||||||
conv_func = CFUNCTYPE(
|
conv_func = CFUNCTYPE(
|
||||||
c_int,
|
c_int,
|
||||||
c_int,
|
c_int,
|
||||||
|
@ -90,6 +91,7 @@ class PamWrapper(Structure):
|
||||||
"""pam_conv structure wrapper"""
|
"""pam_conv structure wrapper"""
|
||||||
_fields_ = [("conv", conv_func), ("appdata_ptr", c_void_p)]
|
_fields_ = [("conv", conv_func), ("appdata_ptr", c_void_p)]
|
||||||
|
|
||||||
|
|
||||||
pamLib_start = libpam.pam_start
|
pamLib_start = libpam.pam_start
|
||||||
pamLib_start.restype = c_int
|
pamLib_start.restype = c_int
|
||||||
pamLib_start.argtypes = [
|
pamLib_start.argtypes = [
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
# Copyright 2011 OpenStack Foundation
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
from iotronic_lightningrod.devices import Device
|
||||||
|
from iotronic_lightningrod.devices.gpio import arancino
|
||||||
|
|
||||||
|
from oslo_log import log as logging
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def whoami():
|
||||||
|
return inspect.stack()[1][3]
|
||||||
|
|
||||||
|
|
||||||
|
def makeNothing():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class System(Device.Device):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(System, self).__init__("arancino")
|
||||||
|
|
||||||
|
arancino.ArancinoGpio().EnableGPIO()
|
||||||
|
|
||||||
|
def finalize(self):
|
||||||
|
"""Function called at the end of module loading (after RPC registration).
|
||||||
|
|
||||||
|
:return:
|
||||||
|
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def testRPC(self):
|
||||||
|
rpc_name = whoami()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED...")
|
||||||
|
await makeNothing()
|
||||||
|
result = " - " + rpc_name + " result: testRPC is working!!!\n"
|
||||||
|
LOG.info(result)
|
||||||
|
return result
|
|
@ -0,0 +1,37 @@
|
||||||
|
# Copyright 2011 OpenStack Foundation
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
from iotronic_lightningrod.devices.gpio import Gpio
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class ArancinoGpio(Gpio.Gpio):
|
||||||
|
def __init__(self):
|
||||||
|
super(ArancinoGpio, self).__init__("arancino")
|
||||||
|
LOG.info("Arancino GPIO module importing...")
|
||||||
|
|
||||||
|
# Enable GPIO
|
||||||
|
def EnableGPIO(self):
|
||||||
|
result = " - GPIO not available for 'arancino' device!"
|
||||||
|
LOG.info(result)
|
||||||
|
|
||||||
|
def DisableGPIO(self):
|
||||||
|
result = " - GPIO not available for 'arancino' device!"
|
||||||
|
LOG.info(result)
|
|
@ -65,8 +65,9 @@ class System(Device.Device):
|
||||||
"""
|
"""
|
||||||
LOG.info(" - readVoltage CALLED... reading pin " + Apin)
|
LOG.info(" - readVoltage CALLED... reading pin " + Apin)
|
||||||
|
|
||||||
voltage = self.gpio._readVoltage(Apin)
|
voltage = await self.gpio._readVoltage(Apin)
|
||||||
|
|
||||||
|
result = "read voltage for " + Apin + " pin: " + voltage
|
||||||
|
|
||||||
result = await "read voltage for " + Apin + " pin: " + voltage
|
|
||||||
LOG.info(result)
|
LOG.info(result)
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -26,7 +26,7 @@ from oslo_log import log as logging
|
||||||
import asyncio
|
import asyncio
|
||||||
import inspect
|
import inspect
|
||||||
import os
|
import os
|
||||||
import pkg_resources
|
# import pkg_resources
|
||||||
import signal
|
import signal
|
||||||
import ssl
|
import ssl
|
||||||
import sys
|
import sys
|
||||||
|
@ -286,13 +286,22 @@ def iotronic_status(board_status):
|
||||||
wamp_singleCheck(SESSION),
|
wamp_singleCheck(SESSION),
|
||||||
loop
|
loop
|
||||||
)
|
)
|
||||||
alive = alive.result()
|
try:
|
||||||
|
alive = alive.result(timeout=5)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
LOG.warning('Check Iotronic request timeout')
|
||||||
|
alive.cancel()
|
||||||
|
alive = "alive_req_canceled"
|
||||||
|
|
||||||
|
except asyncio.TimeoutError as e:
|
||||||
|
LOG.error(" - Iotronic check timeout: " + str(e))
|
||||||
|
alive = "rpc_timeout"
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error(" - Iotronic check: " + str(e))
|
LOG.error(" - Iotronic check: " + str(e))
|
||||||
alive = e
|
alive = "not_connected"
|
||||||
else:
|
else:
|
||||||
alive = "Not connected!"
|
alive = "not_connected"
|
||||||
|
|
||||||
return alive
|
return alive
|
||||||
|
|
||||||
|
@ -445,6 +454,9 @@ async def IotronicLogin(board, session, details):
|
||||||
# reconnection = False
|
# reconnection = False
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
LOG.warning(
|
||||||
|
" - " + str(w_msg.result) + ": " + str(w_msg.message)
|
||||||
|
)
|
||||||
Bye()
|
Bye()
|
||||||
|
|
||||||
except exception.ApplicationError as e:
|
except exception.ApplicationError as e:
|
||||||
|
@ -819,8 +831,10 @@ def wampConnect(wamp_conf):
|
||||||
async def onConnectFailure(session, fail_msg):
|
async def onConnectFailure(session, fail_msg):
|
||||||
LOG.warning("WAMP Connection Failure: " + str(fail_msg))
|
LOG.warning("WAMP Connection Failure: " + str(fail_msg))
|
||||||
|
|
||||||
|
"""
|
||||||
LOG.warning(" - timeout set @ " +
|
LOG.warning(" - timeout set @ " +
|
||||||
str(CONF.autobahn.connection_failure_timer))
|
str(CONF.autobahn.connection_failure_timer))
|
||||||
|
"""
|
||||||
|
|
||||||
global connFailure
|
global connFailure
|
||||||
if connFailure != None:
|
if connFailure != None:
|
||||||
|
@ -930,9 +944,9 @@ def wampConnect(wamp_conf):
|
||||||
LOG.error("Reconnection wrong status!")
|
LOG.error("Reconnection wrong status!")
|
||||||
|
|
||||||
except IndexError as err:
|
except IndexError as err:
|
||||||
LOG.error(" - Error parsing WAMP url: " + str(err))
|
LOG.error(" - Error parsing WAMP url: " + str(err))
|
||||||
LOG.error(" --> port or address not specified")
|
LOG.error(" --> port or address not specified")
|
||||||
board.status = "url_wamp_error"
|
board.status = "url_wamp_error"
|
||||||
|
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
LOG.error(" - WAMP connection error: " + str(err))
|
LOG.error(" - WAMP connection error: " + str(err))
|
||||||
|
@ -1026,68 +1040,73 @@ def modulesLoader(session):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
LOG.info("Available modules: ")
|
try:
|
||||||
|
|
||||||
ep = []
|
LOG.info("Available modules: ")
|
||||||
|
|
||||||
for ep in pkg_resources.iter_entry_points(group='s4t.modules'):
|
ep = []
|
||||||
LOG.info(" - " + str(ep))
|
|
||||||
|
|
||||||
if not ep:
|
for ep in pkg_resources.iter_entry_points(group='s4t.modules'):
|
||||||
|
LOG.info(" - " + str(ep))
|
||||||
|
|
||||||
LOG.info("No modules available!")
|
if not ep:
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
else:
|
LOG.info("No modules available!")
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
modules = extension.ExtensionManager(
|
else:
|
||||||
namespace='s4t.modules',
|
|
||||||
# invoke_on_load=True,
|
|
||||||
# invoke_args=(session,),
|
|
||||||
)
|
|
||||||
|
|
||||||
LOG.info('Modules to load:')
|
modules = extension.ExtensionManager(
|
||||||
|
namespace='s4t.modules',
|
||||||
|
# invoke_on_load=True,
|
||||||
|
# invoke_args=(session,),
|
||||||
|
)
|
||||||
|
|
||||||
for ext in modules.extensions:
|
LOG.info('Modules to load:')
|
||||||
|
|
||||||
LOG.debug(ext.name)
|
for ext in modules.extensions:
|
||||||
|
|
||||||
if (ext.name == 'gpio') & (board.type == 'server'):
|
LOG.debug(ext.name)
|
||||||
LOG.info("- GPIO module disabled for 'server' devices")
|
|
||||||
|
|
||||||
else:
|
if (ext.name == 'gpio') & (board.type == 'server'):
|
||||||
|
LOG.info("- GPIO module disabled for 'server' devices")
|
||||||
|
|
||||||
if ext.name != "rest":
|
else:
|
||||||
|
|
||||||
mod = ext.plugin(board, session)
|
if ext.name != "rest":
|
||||||
|
|
||||||
global MODULES
|
mod = ext.plugin(board, session)
|
||||||
MODULES[mod.name] = mod
|
|
||||||
|
|
||||||
# Methods list for each module
|
global MODULES
|
||||||
meth_list = inspect.getmembers(
|
MODULES[mod.name] = mod
|
||||||
mod, predicate=inspect.ismethod
|
|
||||||
)
|
|
||||||
|
|
||||||
global RPC
|
# Methods list for each module
|
||||||
RPC[mod.name] = meth_list
|
meth_list = inspect.getmembers(
|
||||||
|
mod, predicate=inspect.ismethod
|
||||||
|
)
|
||||||
|
|
||||||
if len(meth_list) == 3:
|
global RPC
|
||||||
# there are at least two methods for each module:
|
RPC[mod.name] = meth_list
|
||||||
# "__init__" and "finalize"
|
|
||||||
|
|
||||||
LOG.info(" - No RPC to register for "
|
if len(meth_list) == 3:
|
||||||
+ str(ext.name) + " module!")
|
# there are at least two methods for each module:
|
||||||
|
# "__init__" and "finalize"
|
||||||
|
|
||||||
else:
|
LOG.info(" - No RPC to register for "
|
||||||
LOG.info(" - RPC list of " + str(mod.name) + ":")
|
+ str(ext.name) + " module!")
|
||||||
moduleWampRegister(SESSION, meth_list)
|
|
||||||
|
|
||||||
# Call the finalize procedure for each module
|
else:
|
||||||
mod.finalize()
|
LOG.info(" - RPC list of " + str(mod.name) + ":")
|
||||||
|
moduleWampRegister(SESSION, meth_list)
|
||||||
|
|
||||||
LOG.info("Lightning-rod modules loaded.")
|
# Call the finalize procedure for each module
|
||||||
LOG.info("\n\nListening...")
|
mod.finalize()
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
LOG.warning("Board modules loading error: " + str(err))
|
||||||
|
|
||||||
|
LOG.info("Lightning-rod modules loaded.")
|
||||||
|
LOG.info("\n\nListening...")
|
||||||
|
|
||||||
|
|
||||||
def moduleReloadInfo(session):
|
def moduleReloadInfo(session):
|
||||||
|
|
|
@ -21,11 +21,14 @@ import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
|
||||||
from autobahn.wamp import exception
|
from autobahn.wamp import exception
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from iotronic_lightningrod.common import utils
|
from iotronic_lightningrod.common import utils
|
||||||
|
# from iotronic_lightningrod.common.exception import timeout
|
||||||
from iotronic_lightningrod.config import package_path
|
from iotronic_lightningrod.config import package_path
|
||||||
from iotronic_lightningrod.lightningrod import RPC_devices
|
from iotronic_lightningrod.lightningrod import RPC_devices
|
||||||
from iotronic_lightningrod.lightningrod import wampNotify
|
from iotronic_lightningrod.lightningrod import wampNotify
|
||||||
|
@ -495,7 +498,8 @@ class DeviceManager(Module.Module):
|
||||||
+ " " + str(pkg)
|
+ " " + str(pkg)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
command = command + " " + str(cmd) + " " + str(pkg)
|
command = command + " " + str(cmd) \
|
||||||
|
+ " " + str(pkg)
|
||||||
|
|
||||||
if 'version' in parameters:
|
if 'version' in parameters:
|
||||||
|
|
||||||
|
@ -682,6 +686,41 @@ class DeviceManager(Module.Module):
|
||||||
|
|
||||||
return w_msg.serialize()
|
return w_msg.serialize()
|
||||||
|
|
||||||
|
# SC
|
||||||
|
async def DeviceFactoryReset(self, req, parameters=None):
|
||||||
|
req_id = req['uuid']
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED [req_id: " + str(req_id) + "]:")
|
||||||
|
if parameters is not None:
|
||||||
|
LOG.info(" - " + rpc_name + " parameters: " + str(parameters))
|
||||||
|
|
||||||
|
def FactoryReset():
|
||||||
|
message = factory_reset()
|
||||||
|
w_msg = WM.WampSuccess(msg=message, req_id=req_id)
|
||||||
|
|
||||||
|
if (req['main_request_uuid'] != None):
|
||||||
|
wampNotify(self.device_session,
|
||||||
|
self.board, w_msg.serialize(), rpc_name)
|
||||||
|
else:
|
||||||
|
return w_msg
|
||||||
|
|
||||||
|
if (req['main_request_uuid'] != None):
|
||||||
|
|
||||||
|
LOG.info(" - main request: " + str(req['main_request_uuid']))
|
||||||
|
try:
|
||||||
|
threading.Thread(target=FactoryReset).start()
|
||||||
|
w_msg = WM.WampRunning(msg=rpc_name, req_id=req_id)
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
message = "Error in thr_" + rpc_name + ": " + str(err)
|
||||||
|
LOG.error(message)
|
||||||
|
w_msg = WM.WampError(msg=message, req_id=req_id)
|
||||||
|
|
||||||
|
else:
|
||||||
|
w_msg = FactoryReset()
|
||||||
|
|
||||||
|
return w_msg.serialize()
|
||||||
|
|
||||||
# SC
|
# SC
|
||||||
async def DeviceNetConfig(self, req, parameters=None):
|
async def DeviceNetConfig(self, req, parameters=None):
|
||||||
req_id = req['uuid']
|
req_id = req['uuid']
|
||||||
|
@ -717,6 +756,136 @@ class DeviceManager(Module.Module):
|
||||||
|
|
||||||
return w_msg.serialize()
|
return w_msg.serialize()
|
||||||
|
|
||||||
|
# SC
|
||||||
|
async def DeviceRestSubmit(self, req, parameters=None):
|
||||||
|
req_id = req['uuid']
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED [req_id: " + str(req_id) + "]:")
|
||||||
|
if parameters is not None:
|
||||||
|
LOG.info(" - " + rpc_name + " parameters: " + str(parameters))
|
||||||
|
|
||||||
|
def RestSubmit():
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
if 'url' in parameters:
|
||||||
|
url = str(parameters['url'])
|
||||||
|
else:
|
||||||
|
message = "Error RestSubmit: no url specified."
|
||||||
|
LOG.error(message)
|
||||||
|
w_msg = WM.WampError(msg=message, req_id=req_id)
|
||||||
|
return w_msg
|
||||||
|
|
||||||
|
if 'method' in parameters:
|
||||||
|
method = str(parameters['method'])
|
||||||
|
else:
|
||||||
|
message = "Error RestSubmit: no REST method specified."
|
||||||
|
LOG.error(message)
|
||||||
|
w_msg = WM.WampError(msg=message, req_id=req_id)
|
||||||
|
return w_msg
|
||||||
|
|
||||||
|
response = requests.request(
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
params=json.dumps(parameters['params']) if '\
|
||||||
|
params' in parameters else None,
|
||||||
|
data=json.dumps(parameters['data']) if '\
|
||||||
|
data' in parameters else None,
|
||||||
|
json=parameters['json'] if '\
|
||||||
|
json' in parameters else None,
|
||||||
|
headers=parameters['headers'] if '\
|
||||||
|
headers' in parameters else None,
|
||||||
|
cookies=parameters['cookies'] if '\
|
||||||
|
cookies' in parameters else None,
|
||||||
|
files=parameters['files'] if '\
|
||||||
|
files' in parameters else None,
|
||||||
|
auth=parameters['auth'] if '\
|
||||||
|
auth' in parameters else None,
|
||||||
|
timeout=float(parameters['timeout']) if '\
|
||||||
|
timeout' in parameters else None,
|
||||||
|
allow_redirects=parameters['allow_redirects'] if '\
|
||||||
|
allow_redirects' in parameters else True,
|
||||||
|
proxies=parameters['proxies'] if '\
|
||||||
|
proxies' in parameters else None,
|
||||||
|
verify=parameters['verify'] if '\
|
||||||
|
verify' in parameters else True,
|
||||||
|
stream=parameters['stream'] if '\
|
||||||
|
stream' in parameters else False,
|
||||||
|
cert=parameters['cert'] if '\
|
||||||
|
cert' in parameters else None,
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
res = json.loads(response.text)
|
||||||
|
|
||||||
|
w_msg = WM.WampSuccess(msg=res, req_id=req_id)
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
return WM.WampError(msg=str(err), req_id=req_id)
|
||||||
|
|
||||||
|
if (req['main_request_uuid'] != None):
|
||||||
|
wampNotify(self.device_session,
|
||||||
|
self.board, w_msg.serialize(), rpc_name)
|
||||||
|
else:
|
||||||
|
return w_msg
|
||||||
|
|
||||||
|
if (req['main_request_uuid'] != None):
|
||||||
|
|
||||||
|
LOG.info(" - main request: " + str(req['main_request_uuid']))
|
||||||
|
try:
|
||||||
|
|
||||||
|
threading.Thread(target=RestSubmit).start()
|
||||||
|
w_msg = WM.WampRunning(msg=rpc_name, req_id=req_id)
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
message = "Error in thr_" + rpc_name + ": " + str(err)
|
||||||
|
LOG.error(message)
|
||||||
|
w_msg = WM.WampError(msg=message, req_id=req_id)
|
||||||
|
|
||||||
|
else:
|
||||||
|
w_msg = RestSubmit()
|
||||||
|
|
||||||
|
return w_msg.serialize()
|
||||||
|
|
||||||
|
|
||||||
|
def lr_install():
|
||||||
|
bashCommand = "lr_install"
|
||||||
|
process = subprocess.Popen(bashCommand.split(),
|
||||||
|
stdout=subprocess.PIPE)
|
||||||
|
output, error = process.communicate()
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def factory_reset():
|
||||||
|
|
||||||
|
LOG.info("Lightning-rod factory reset: ")
|
||||||
|
|
||||||
|
# delete nginx conf.d files
|
||||||
|
os.system("rm /etc/nginx/conf.d/lr_*")
|
||||||
|
LOG.info("--> NGINX settings deleted.")
|
||||||
|
|
||||||
|
# delete letsencrypt
|
||||||
|
os.system("rm -r /etc/letsencrypt/*")
|
||||||
|
LOG.info("--> LetsEncrypt settings deleted.")
|
||||||
|
|
||||||
|
# delete var-iotronic
|
||||||
|
os.system("rm -r /var/lib/iotronic/*")
|
||||||
|
LOG.info("--> Iotronic data deleted.")
|
||||||
|
|
||||||
|
# delete etc-iotronic
|
||||||
|
os.system("rm -r /etc/iotronic/*")
|
||||||
|
LOG.info("--> Iotronic settings deleted.")
|
||||||
|
|
||||||
|
# exec lr_install
|
||||||
|
lr_install()
|
||||||
|
|
||||||
|
# restart LR
|
||||||
|
LOG.info("--> LR restarting in 5 seconds...")
|
||||||
|
lr_utils.LR_restart_delayed(5)
|
||||||
|
|
||||||
|
return "Device reset completed"
|
||||||
|
|
||||||
|
|
||||||
def getIfconfig():
|
def getIfconfig():
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import queue
|
||||||
import shutil
|
import shutil
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
import platform
|
||||||
|
|
||||||
|
|
||||||
from iotronic_lightningrod.common import utils
|
from iotronic_lightningrod.common import utils
|
||||||
|
@ -149,9 +150,17 @@ class PluginManager(Module.Module):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
if (plugin_uuid in PLUGINS_THRS) and (
|
worker_alive = False
|
||||||
PLUGINS_THRS[plugin_uuid].isAlive()
|
if (plugin_uuid in PLUGINS_THRS):
|
||||||
):
|
worker = PLUGINS_THRS[plugin_uuid]
|
||||||
|
|
||||||
|
pyvers = platform.python_version_tuple()
|
||||||
|
if int(pyvers[0]) == 3 and int(pyvers[1]) >= 9:
|
||||||
|
worker_alive = worker.is_alive()
|
||||||
|
else:
|
||||||
|
worker_alive = worker.isAlive()
|
||||||
|
|
||||||
|
if (plugin_uuid in PLUGINS_THRS) and worker_alive:
|
||||||
|
|
||||||
LOG.warning(" - Plugin "
|
LOG.warning(" - Plugin "
|
||||||
+ plugin_uuid + " already started!")
|
+ plugin_uuid + " already started!")
|
||||||
|
@ -380,10 +389,19 @@ class PluginManager(Module.Module):
|
||||||
|
|
||||||
plugin_name = plugins_conf['plugins'][plugin_uuid]['name']
|
plugin_name = plugins_conf['plugins'][plugin_uuid]['name']
|
||||||
|
|
||||||
|
worker_alive = False
|
||||||
|
if (plugin_uuid in PLUGINS_THRS):
|
||||||
|
worker = PLUGINS_THRS[plugin_uuid]
|
||||||
|
|
||||||
|
pyvers = platform.python_version_tuple()
|
||||||
|
|
||||||
|
if int(pyvers[0]) == 3 and int(pyvers[1]) >= 9:
|
||||||
|
worker_alive = worker.is_alive()
|
||||||
|
else:
|
||||||
|
worker_alive = worker.isAlive()
|
||||||
|
|
||||||
# Check if the plugin is already running
|
# Check if the plugin is already running
|
||||||
if (plugin_uuid in PLUGINS_THRS) and (
|
if (plugin_uuid in PLUGINS_THRS) and worker_alive:
|
||||||
PLUGINS_THRS[plugin_uuid].isAlive()
|
|
||||||
):
|
|
||||||
|
|
||||||
message = "ALREADY STARTED!"
|
message = "ALREADY STARTED!"
|
||||||
LOG.warning(" - Plugin "
|
LOG.warning(" - Plugin "
|
||||||
|
@ -495,10 +513,19 @@ class PluginManager(Module.Module):
|
||||||
|
|
||||||
if plugin_uuid in PLUGINS_THRS:
|
if plugin_uuid in PLUGINS_THRS:
|
||||||
|
|
||||||
worker = PLUGINS_THRS[plugin_uuid]
|
worker_alive = False
|
||||||
LOG.debug(" - Stopping plugin " + str(worker))
|
if (plugin_uuid in PLUGINS_THRS):
|
||||||
|
worker = PLUGINS_THRS[plugin_uuid]
|
||||||
|
LOG.debug(" - Stopping plugin " + str(worker))
|
||||||
|
|
||||||
if worker.isAlive():
|
pyvers = platform.python_version_tuple()
|
||||||
|
|
||||||
|
if int(pyvers[0]) == 3 and int(pyvers[1]) >= 9:
|
||||||
|
worker_alive = worker.is_alive()
|
||||||
|
else:
|
||||||
|
worker_alive = worker.isAlive()
|
||||||
|
|
||||||
|
if worker_alive:
|
||||||
|
|
||||||
if 'delay' in parameters:
|
if 'delay' in parameters:
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
|
@ -556,9 +583,17 @@ class PluginManager(Module.Module):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
if (plugin_uuid in PLUGINS_THRS) and (
|
worker_alive = False
|
||||||
PLUGINS_THRS[plugin_uuid].isAlive()
|
if (plugin_uuid in PLUGINS_THRS):
|
||||||
):
|
worker = PLUGINS_THRS[plugin_uuid]
|
||||||
|
|
||||||
|
pyvers = platform.python_version_tuple()
|
||||||
|
if int(pyvers[0]) == 3 and int(pyvers[1]) >= 9:
|
||||||
|
worker_alive = worker.is_alive()
|
||||||
|
else:
|
||||||
|
worker_alive = worker.isAlive()
|
||||||
|
|
||||||
|
if (plugin_uuid in PLUGINS_THRS) and worker_alive:
|
||||||
|
|
||||||
message = "Plugin " + plugin_uuid + " already started!"
|
message = "Plugin " + plugin_uuid + " already started!"
|
||||||
LOG.warning(" - " + message)
|
LOG.warning(" - " + message)
|
||||||
|
@ -727,7 +762,14 @@ class PluginManager(Module.Module):
|
||||||
|
|
||||||
if plugin_uuid in PLUGINS_THRS:
|
if plugin_uuid in PLUGINS_THRS:
|
||||||
worker = PLUGINS_THRS[plugin_uuid]
|
worker = PLUGINS_THRS[plugin_uuid]
|
||||||
if worker.isAlive():
|
|
||||||
|
pyvers = platform.python_version_tuple()
|
||||||
|
if int(pyvers[0]) == 3 and int(pyvers[1]) >= 9:
|
||||||
|
worker_alive = worker.is_alive()
|
||||||
|
else:
|
||||||
|
worker_alive = worker.isAlive()
|
||||||
|
|
||||||
|
if worker_alive:
|
||||||
LOG.info(" - Plugin '"
|
LOG.info(" - Plugin '"
|
||||||
+ plugin_name + "' is running...")
|
+ plugin_name + "' is running...")
|
||||||
worker.stop()
|
worker.stop()
|
||||||
|
@ -798,17 +840,28 @@ class PluginManager(Module.Module):
|
||||||
|
|
||||||
worker = PLUGINS_THRS[plugin_uuid]
|
worker = PLUGINS_THRS[plugin_uuid]
|
||||||
|
|
||||||
|
pyvers = platform.python_version_tuple()
|
||||||
|
if int(pyvers[0]) == 3 and int(pyvers[1]) >= 9:
|
||||||
|
worker_alive = worker.is_alive()
|
||||||
|
else:
|
||||||
|
worker_alive = worker.isAlive()
|
||||||
|
|
||||||
# STOP PLUGIN----------------------------------------------
|
# STOP PLUGIN----------------------------------------------
|
||||||
|
|
||||||
if worker.isAlive():
|
if worker_alive:
|
||||||
|
|
||||||
LOG.info(" - Thread "
|
LOG.info(" - Thread "
|
||||||
+ plugin_uuid + " is running, stopping...")
|
+ plugin_uuid + " is running, stopping...")
|
||||||
LOG.debug(" - Stopping plugin " + str(worker))
|
LOG.debug(" - Stopping plugin " + str(worker))
|
||||||
worker.stop()
|
worker.stop()
|
||||||
|
|
||||||
while worker.isAlive():
|
if int(pyvers[0]) == 3 and int(pyvers[1]) >= 9:
|
||||||
pass
|
worker_alive = worker.is_alive()
|
||||||
|
while worker.is_alive():
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
while worker.isAlive():
|
||||||
|
pass
|
||||||
|
|
||||||
# Remove from plugin thread list
|
# Remove from plugin thread list
|
||||||
del PLUGINS_THRS[plugin_uuid]
|
del PLUGINS_THRS[plugin_uuid]
|
||||||
|
@ -893,7 +946,13 @@ class PluginManager(Module.Module):
|
||||||
|
|
||||||
worker = PLUGINS_THRS[plugin_uuid]
|
worker = PLUGINS_THRS[plugin_uuid]
|
||||||
|
|
||||||
if worker.isAlive():
|
pyvers = platform.python_version_tuple()
|
||||||
|
if int(pyvers[0]) == 3 and int(pyvers[1]) >= 9:
|
||||||
|
worker_alive = worker.is_alive()
|
||||||
|
else:
|
||||||
|
worker_alive = worker.isAlive()
|
||||||
|
|
||||||
|
if worker_alive:
|
||||||
result = "ALIVE"
|
result = "ALIVE"
|
||||||
else:
|
else:
|
||||||
result = "DEAD"
|
result = "DEAD"
|
||||||
|
|
|
@ -24,7 +24,6 @@ LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import shutil
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
@ -212,6 +211,16 @@ class ProxyManager(Proxy.Proxy):
|
||||||
nginx_board_conf = '''server {{
|
nginx_board_conf = '''server {{
|
||||||
listen 50000;
|
listen 50000;
|
||||||
server_name {0};
|
server_name {0};
|
||||||
|
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
|
||||||
location / {{
|
location / {{
|
||||||
proxy_pass http://127.0.0.1:1474;
|
proxy_pass http://127.0.0.1:1474;
|
||||||
}}
|
}}
|
||||||
|
@ -294,6 +303,39 @@ class ProxyManager(Proxy.Proxy):
|
||||||
|
|
||||||
return json.dumps(nginxMsg)
|
return json.dumps(nginxMsg)
|
||||||
|
|
||||||
|
def _proxyRenewWebservice(self):
|
||||||
|
|
||||||
|
nginxMsg = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
command = "/usr/bin/certbot " \
|
||||||
|
"renew " \
|
||||||
|
"--force-renewal " \
|
||||||
|
"-w /var/www/html"
|
||||||
|
|
||||||
|
LOG.info("Certbot is renewing certificate:")
|
||||||
|
LOG.info(command)
|
||||||
|
|
||||||
|
certbot_result = call(command, shell=True)
|
||||||
|
LOG.info("CERTBOT RESULT: " + str(certbot_result))
|
||||||
|
|
||||||
|
if (certbot_result == 0):
|
||||||
|
nginxMsg['result'] = "SUCCESS"
|
||||||
|
nginxMsg['message'] = "Webservice certificate renewed."
|
||||||
|
else:
|
||||||
|
nginxMsg['result'] = "ERROR"
|
||||||
|
nginxMsg['message'] = "Renewing certificate failure."
|
||||||
|
|
||||||
|
LOG.info("--> " + nginxMsg['message'])
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
nginxMsg['log'] = "Renewing certificate error: " + str(err)
|
||||||
|
nginxMsg['code'] = ""
|
||||||
|
LOG.warning("--> " + nginxMsg['log'])
|
||||||
|
|
||||||
|
return json.dumps(nginxMsg)
|
||||||
|
|
||||||
def _exposeWebservice(self, board_dns, service_dns, local_port, dns_list):
|
def _exposeWebservice(self, board_dns, service_dns, local_port, dns_list):
|
||||||
|
|
||||||
nginxMsg = {}
|
nginxMsg = {}
|
||||||
|
@ -316,7 +358,7 @@ class ProxyManager(Proxy.Proxy):
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
location / {{
|
location / {{
|
||||||
proxy_pass http://localhost:{1};
|
proxy_pass http://127.0.0.1:{1};
|
||||||
}}
|
}}
|
||||||
location ~ /.well-known {{
|
location ~ /.well-known {{
|
||||||
root /var/www/html;
|
root /var/www/html;
|
||||||
|
|
|
@ -34,8 +34,9 @@ from flask import request
|
||||||
from flask import send_file
|
from flask import send_file
|
||||||
from flask import session as f_session
|
from flask import session as f_session
|
||||||
from flask import url_for
|
from flask import url_for
|
||||||
|
from flask import abort
|
||||||
|
# from flask import Response
|
||||||
|
|
||||||
import getpass
|
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import threading
|
import threading
|
||||||
|
@ -144,6 +145,18 @@ class RestManager(Module.Module):
|
||||||
lr_cty = sock_bundle[2] + " - " + sock_bundle[0] \
|
lr_cty = sock_bundle[2] + " - " + sock_bundle[0] \
|
||||||
+ " - " + sock_bundle[1]
|
+ " - " + sock_bundle[1]
|
||||||
|
|
||||||
|
webservice_list = []
|
||||||
|
nginx_path = "/etc/nginx/conf.d/"
|
||||||
|
|
||||||
|
if os.path.exists(nginx_path):
|
||||||
|
active_webservice_list = [f for f in os.listdir(nginx_path)
|
||||||
|
if os.path.isfile(os.path.join(nginx_path, f))]
|
||||||
|
|
||||||
|
if len(active_webservice_list) != 0:
|
||||||
|
for ws in active_webservice_list:
|
||||||
|
ws = ws.replace('.conf', '')
|
||||||
|
webservice_list.append(ws)
|
||||||
|
|
||||||
info = {
|
info = {
|
||||||
'board_id': board.uuid,
|
'board_id': board.uuid,
|
||||||
'board_name': board.name,
|
'board_name': board.name,
|
||||||
|
@ -155,6 +168,7 @@ class RestManager(Module.Module):
|
||||||
'board_reg_status': str(board.status),
|
'board_reg_status': str(board.status),
|
||||||
'iotronic_status': str(iotronic_status(board.status)),
|
'iotronic_status': str(iotronic_status(board.status)),
|
||||||
'service_list': service_list,
|
'service_list': service_list,
|
||||||
|
'webservice_list': webservice_list,
|
||||||
'serial_dev': device_manager.getSerialDevice(),
|
'serial_dev': device_manager.getSerialDevice(),
|
||||||
'nic': lr_cty,
|
'nic': lr_cty,
|
||||||
'lr_version': str(
|
'lr_version': str(
|
||||||
|
@ -162,56 +176,85 @@ class RestManager(Module.Module):
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return info
|
return info, 200
|
||||||
|
|
||||||
@app.route('/status')
|
@app.route('/status')
|
||||||
def status():
|
def status():
|
||||||
|
|
||||||
if ('username' in f_session):
|
try:
|
||||||
|
|
||||||
f_session['status'] = str(board.status)
|
if ('username' in f_session):
|
||||||
|
|
||||||
|
f_session['status'] = str(board.status)
|
||||||
|
|
||||||
|
wstun_status = service_manager.wstun_status()
|
||||||
|
if wstun_status == 0:
|
||||||
|
wstun_status = "Online"
|
||||||
|
else:
|
||||||
|
wstun_status = "Offline"
|
||||||
|
|
||||||
|
service_list = service_manager.services_list("html")
|
||||||
|
if service_list == "":
|
||||||
|
service_list = "no services exposed!"
|
||||||
|
|
||||||
|
webservice_list = ""
|
||||||
|
nginx_path = "/etc/nginx/conf.d/"
|
||||||
|
|
||||||
|
if os.path.exists(nginx_path):
|
||||||
|
active_webservice_list = [
|
||||||
|
f for f in os.listdir(nginx_path)
|
||||||
|
if os.path.isfile(os.path.join(nginx_path, f))
|
||||||
|
]
|
||||||
|
|
||||||
|
for ws in active_webservice_list:
|
||||||
|
ws = ws.replace('.conf', '')[3:]
|
||||||
|
webservice_list = webservice_list + "\
|
||||||
|
<li>" + ws + "</li>"
|
||||||
|
else:
|
||||||
|
webservice_list = "no webservices exposed!"
|
||||||
|
|
||||||
|
if webservice_list == "":
|
||||||
|
webservice_list = "no webservices exposed!"
|
||||||
|
|
||||||
|
lr_cty = "N/A"
|
||||||
|
from iotronic_lightningrod.lightningrod import wport
|
||||||
|
sock_bundle = lr_utils.get_socket_info(wport)
|
||||||
|
|
||||||
|
if sock_bundle != "N/A":
|
||||||
|
lr_cty = sock_bundle[2] + " - " + sock_bundle[0] \
|
||||||
|
+ " - " + sock_bundle[1]
|
||||||
|
|
||||||
|
info = {
|
||||||
|
'board_id': board.uuid,
|
||||||
|
'board_name': board.name,
|
||||||
|
'wagent': board.agent,
|
||||||
|
'session_id': board.session_id,
|
||||||
|
'timestamp': str(
|
||||||
|
datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f')),
|
||||||
|
'wstun_status': wstun_status,
|
||||||
|
'board_reg_status': str(board.status),
|
||||||
|
'iotronic_status': str(iotronic_status(board.status)),
|
||||||
|
'service_list': str(service_list),
|
||||||
|
'webservice_list': str(webservice_list),
|
||||||
|
'serial_dev': device_manager.getSerialDevice(),
|
||||||
|
'nic': lr_cty,
|
||||||
|
'lr_version': str(
|
||||||
|
utils.get_version("iotronic-lightningrod")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return render_template('status.html', **info)
|
||||||
|
|
||||||
wstun_status = service_manager.wstun_status()
|
|
||||||
if wstun_status == 0:
|
|
||||||
wstun_status = "Online"
|
|
||||||
else:
|
else:
|
||||||
wstun_status = "Offline"
|
return redirect(url_for('login', next=request.endpoint))
|
||||||
|
|
||||||
service_list = service_manager.services_list("html")
|
|
||||||
if service_list == "":
|
|
||||||
service_list = "no services exposed!"
|
|
||||||
|
|
||||||
lr_cty = "N/A"
|
|
||||||
from iotronic_lightningrod.lightningrod import wport
|
|
||||||
sock_bundle = lr_utils.get_socket_info(wport)
|
|
||||||
|
|
||||||
if sock_bundle != "N/A":
|
|
||||||
lr_cty = sock_bundle[2] + " - " + sock_bundle[0] \
|
|
||||||
+ " - " + sock_bundle[1]
|
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
LOG.error(err)
|
||||||
info = {
|
info = {
|
||||||
'board_id': board.uuid,
|
'messages': [str(err)]
|
||||||
'board_name': board.name,
|
}
|
||||||
'wagent': board.agent,
|
|
||||||
'session_id': board.session_id,
|
|
||||||
'timestamp': str(
|
|
||||||
datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f')),
|
|
||||||
'wstun_status': wstun_status,
|
|
||||||
'board_reg_status': str(board.status),
|
|
||||||
'iotronic_status': str(iotronic_status(board.status)),
|
|
||||||
'service_list': str(service_list),
|
|
||||||
'serial_dev': device_manager.getSerialDevice(),
|
|
||||||
'nic': lr_cty,
|
|
||||||
'lr_version': str(
|
|
||||||
utils.get_version("iotronic-lightningrod")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return render_template('status.html', **info)
|
return render_template('status.html', **info)
|
||||||
|
|
||||||
else:
|
|
||||||
return redirect(url_for('login', next=request.endpoint))
|
|
||||||
|
|
||||||
@app.route('/system')
|
@app.route('/system')
|
||||||
def system():
|
def system():
|
||||||
if 'username' in f_session:
|
if 'username' in f_session:
|
||||||
|
@ -360,7 +403,7 @@ class RestManager(Module.Module):
|
||||||
**info,
|
**info,
|
||||||
error=error
|
error=error
|
||||||
)
|
)
|
||||||
return redirect("/config", code=302)
|
# return redirect("/config", code=302)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return redirect("/", code=302)
|
return redirect("/", code=302)
|
||||||
|
@ -370,6 +413,9 @@ class RestManager(Module.Module):
|
||||||
@app.route('/backup', methods=['GET'])
|
@app.route('/backup', methods=['GET'])
|
||||||
def backup_download():
|
def backup_download():
|
||||||
|
|
||||||
|
# LOG.info(request.query_string)
|
||||||
|
# LOG.info(request.__dict__)
|
||||||
|
|
||||||
if 'username' in f_session:
|
if 'username' in f_session:
|
||||||
|
|
||||||
print("Identity file downloading: ")
|
print("Identity file downloading: ")
|
||||||
|
@ -433,7 +479,33 @@ class RestManager(Module.Module):
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
|
||||||
if request.form.get('reg_btn') == 'CONFIGURE':
|
req_body = request.get_json()
|
||||||
|
|
||||||
|
LOG.debug(req_body)
|
||||||
|
|
||||||
|
if req_body != None:
|
||||||
|
|
||||||
|
if 'action' in req_body:
|
||||||
|
|
||||||
|
if req_body['action'] == "configure":
|
||||||
|
LOG.info("API LR configuration")
|
||||||
|
|
||||||
|
ragent = req_body['urlwagent']
|
||||||
|
code = req_body['code']
|
||||||
|
|
||||||
|
lr_config(ragent, code)
|
||||||
|
|
||||||
|
if 'hostname' in req_body:
|
||||||
|
if req_body['hostname'] != "":
|
||||||
|
change_hostname(req_body['hostname'])
|
||||||
|
|
||||||
|
return {"result": "LR configured, \
|
||||||
|
authenticating..."}, 200
|
||||||
|
|
||||||
|
else:
|
||||||
|
abort(400)
|
||||||
|
|
||||||
|
elif request.form.get('reg_btn') == 'CONFIGURE':
|
||||||
ragent = request.form['urlwagent']
|
ragent = request.form['urlwagent']
|
||||||
code = request.form['code']
|
code = request.form['code']
|
||||||
lr_config(ragent, code)
|
lr_config(ragent, code)
|
||||||
|
@ -633,6 +705,12 @@ class RestManager(Module.Module):
|
||||||
return render_template('config.html', **info)
|
return render_template('config.html', **info)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
if request.method == 'POST':
|
||||||
|
req_body = request.get_json()
|
||||||
|
|
||||||
|
if req_body != None and str(board.status) != "first_boot":
|
||||||
|
return {"result": "LR already configured!"}, 403
|
||||||
|
|
||||||
return redirect(url_for('login', next=request.endpoint))
|
return redirect(url_for('login', next=request.endpoint))
|
||||||
|
|
||||||
app.run(host='0.0.0.0', port=1474, debug=False, use_reloader=False)
|
app.run(host='0.0.0.0', port=1474, debug=False, use_reloader=False)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# Copyright 2017 MDSLAB - University of Messina
|
# Copyright 2017 MDSLAB - University of Messina. All Rights Reserved.
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
# not use this file except in compliance with the License. You may obtain
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
@ -24,9 +23,6 @@ import signal
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import threading
|
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from random import randint
|
from random import randint
|
||||||
|
@ -36,9 +32,7 @@ from urllib.parse import urlparse
|
||||||
from iotronic_lightningrod.common import utils
|
from iotronic_lightningrod.common import utils
|
||||||
from iotronic_lightningrod.config import package_path
|
from iotronic_lightningrod.config import package_path
|
||||||
from iotronic_lightningrod.modules import Module
|
from iotronic_lightningrod.modules import Module
|
||||||
|
|
||||||
from iotronic_lightningrod import lightningrod
|
from iotronic_lightningrod import lightningrod
|
||||||
|
|
||||||
import iotronic_lightningrod.wampmessage as WM
|
import iotronic_lightningrod.wampmessage as WM
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,6 +95,8 @@ class ServiceManager(Module.Module):
|
||||||
if wurl_list[0] == "wss":
|
if wurl_list[0] == "wss":
|
||||||
is_wss = True
|
is_wss = True
|
||||||
|
|
||||||
|
self.board_id = board.uuid
|
||||||
|
|
||||||
if is_wss:
|
if is_wss:
|
||||||
self.wstun_url = "wss://" + self.wstun_ip + ":" + self.wstun_port
|
self.wstun_url = "wss://" + self.wstun_ip + ":" + self.wstun_port
|
||||||
else:
|
else:
|
||||||
|
@ -600,7 +596,7 @@ class ServiceManager(Module.Module):
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
LOG.error(" --> Parsing error in " + s_conf_FILE + ": " + str(err))
|
LOG.error(" --> Parsing error in " + s_conf_FILE + ": " + str(err))
|
||||||
|
|
||||||
if os.path.isfile(s_conf_FILE):
|
if os.path.isfile(s_conf_FILE + '.bkp '):
|
||||||
|
|
||||||
LOG.info(" --> restoring services.json file...")
|
LOG.info(" --> restoring services.json file...")
|
||||||
|
|
||||||
|
@ -621,6 +617,28 @@ class ServiceManager(Module.Module):
|
||||||
LOG.error(" --> services.json backup file does not exist!")
|
LOG.error(" --> services.json backup file does not exist!")
|
||||||
s_conf = None
|
s_conf = None
|
||||||
|
|
||||||
|
if s_conf == None:
|
||||||
|
try:
|
||||||
|
LOG.info(" --> loading services.json template file")
|
||||||
|
template_conf = '''{
|
||||||
|
"services": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
with open(s_conf_FILE, "w") as text_file:
|
||||||
|
text_file.write("%s" % template_conf)
|
||||||
|
|
||||||
|
with open(s_conf_FILE) as settings:
|
||||||
|
s_conf = json.load(settings)
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
LOG.error(
|
||||||
|
" --> Loading template error: \
|
||||||
|
manual check on device required!"
|
||||||
|
)
|
||||||
|
s_conf = None
|
||||||
|
|
||||||
return s_conf
|
return s_conf
|
||||||
|
|
||||||
def _wstunMon(self, wstun, local_port):
|
def _wstunMon(self, wstun, local_port):
|
||||||
|
@ -762,16 +780,24 @@ class ServiceManager(Module.Module):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
# subp_cmd = [CONF.services.wstun_bin, opt_reverse,
|
||||||
|
# self.wstun_url, '-u "' + str(self.board_id) + '"']
|
||||||
|
|
||||||
|
subp_cmd = [CONF.services.wstun_bin, opt_reverse,
|
||||||
|
self.wstun_url, '-u', '' + str(self.board_id) + '']
|
||||||
|
|
||||||
wstun = subprocess.Popen(
|
wstun = subprocess.Popen(
|
||||||
[CONF.services.wstun_bin, opt_reverse, self.wstun_url],
|
subp_cmd,
|
||||||
stdout=subprocess.PIPE
|
stdout=subprocess.PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
if (event != "boot"):
|
if (event != "boot"):
|
||||||
print("WSTUN start event:")
|
print("WSTUN start event:")
|
||||||
|
|
||||||
cmd_print = 'WSTUN exec: ' + str(CONF.services.wstun_bin) \
|
# cmd_print = 'WSTUN exec: ' + str(CONF.services.wstun_bin) \
|
||||||
+ " " + opt_reverse + ' ' + self.wstun_url
|
# + " " + opt_reverse + ' ' + self.wstun_url
|
||||||
|
cmd_print = 'WSTUN exec: ' + str(subp_cmd)
|
||||||
|
|
||||||
print(" - " + str(cmd_print))
|
print(" - " + str(cmd_print))
|
||||||
LOG.debug(cmd_print)
|
LOG.debug(cmd_print)
|
||||||
|
|
||||||
|
@ -845,16 +871,24 @@ class ServiceManager(Module.Module):
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
# subp_cmd = [CONF.services.wstun_bin, opt_reverse, self.wstun_url,
|
||||||
|
# '-u "' + str(self.board_id) + '"']
|
||||||
|
|
||||||
|
subp_cmd = [CONF.services.wstun_bin, opt_reverse, self.wstun_url,
|
||||||
|
'-u', '' + str(self.board_id) + '']
|
||||||
|
|
||||||
wstun = subprocess.Popen(
|
wstun = subprocess.Popen(
|
||||||
[CONF.services.wstun_bin, opt_reverse, self.wstun_url],
|
subp_cmd,
|
||||||
stdout=subprocess.PIPE
|
stdout=subprocess.PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
if (event != "boot"):
|
if (event != "boot"):
|
||||||
print("WSTUN start event:")
|
print("WSTUN start event:")
|
||||||
|
|
||||||
cmd_print = 'WSTUN exec: ' + str(CONF.services.wstun_bin) + " " \
|
# cmd_print = 'WSTUN exec: ' + str(CONF.services.wstun_bin) + " " \
|
||||||
+ opt_reverse + ' ' + self.wstun_url
|
# + opt_reverse + ' ' + self.wstun_url
|
||||||
|
cmd_print = 'WSTUN exec: ' + str(subp_cmd)
|
||||||
print(" - " + str(cmd_print))
|
print(" - " + str(cmd_print))
|
||||||
LOG.debug(cmd_print)
|
LOG.debug(cmd_print)
|
||||||
|
|
||||||
|
@ -926,9 +960,32 @@ class ServiceManager(Module.Module):
|
||||||
if parameters is not None:
|
if parameters is not None:
|
||||||
LOG.info(" - " + rpc_name + " parameters: " + str(parameters))
|
LOG.info(" - " + rpc_name + " parameters: " + str(parameters))
|
||||||
|
|
||||||
thr_list = str(threading.enumerate())
|
tuns = {
|
||||||
|
"sockets": [],
|
||||||
|
"procs": []
|
||||||
|
}
|
||||||
|
|
||||||
w_msg = WM.WampSuccess(msg=thr_list, req_id=req_id)
|
""" LSOF """
|
||||||
|
res_lsof = subprocess.Popen(
|
||||||
|
"lsof -i -n -P | grep '8080'| grep -v grep",
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE
|
||||||
|
)
|
||||||
|
sockets = res_lsof.communicate()[0].decode("utf-8").split("\n")
|
||||||
|
|
||||||
|
tuns['sockets'] = sockets[:-1]
|
||||||
|
|
||||||
|
""" PS """
|
||||||
|
res_ps = subprocess.Popen(
|
||||||
|
"ps aux | grep 'wstun' | grep -v grep",
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE
|
||||||
|
)
|
||||||
|
ps_s4t = res_ps.communicate()[0].decode("utf-8").split("\n")
|
||||||
|
|
||||||
|
tuns['procs'] = ps_s4t[:-1]
|
||||||
|
|
||||||
|
w_msg = WM.WampSuccess(msg=tuns, req_id=req_id)
|
||||||
|
|
||||||
return w_msg.serialize()
|
return w_msg.serialize()
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
import signal
|
||||||
|
|
||||||
|
|
||||||
from iotronic_lightningrod.common import utils
|
from iotronic_lightningrod.common import utils
|
||||||
from iotronic_lightningrod.config import entry_points_name
|
from iotronic_lightningrod.config import entry_points_name
|
||||||
|
@ -40,6 +42,9 @@ LOG = logging.getLogger(__name__)
|
||||||
global connFailureRecovery
|
global connFailureRecovery
|
||||||
connFailureRecovery = None
|
connFailureRecovery = None
|
||||||
|
|
||||||
|
global gdbPid
|
||||||
|
gdbPid = None
|
||||||
|
|
||||||
|
|
||||||
class Utility(Module.Module):
|
class Utility(Module.Module):
|
||||||
|
|
||||||
|
@ -200,18 +205,35 @@ def destroyWampSocket():
|
||||||
LOG.warning("WAMP Connection Recovery timer: EXPIRED")
|
LOG.warning("WAMP Connection Recovery timer: EXPIRED")
|
||||||
lr_utils.LR_restart()
|
lr_utils.LR_restart()
|
||||||
|
|
||||||
|
def timeoutGDB():
|
||||||
|
LOG.warning("WAMP Connection Recovery GDB timer: EXPIRED")
|
||||||
|
|
||||||
|
global gdbPid
|
||||||
|
os.kill(gdbPid, signal.SIGKILL)
|
||||||
|
LOG.warning("WAMP Connection Recovery GDB process: KILLED")
|
||||||
|
|
||||||
|
LOG.warning("WAMP Connection Recovery GDB process: LR restarting...")
|
||||||
|
lr_utils.LR_restart()
|
||||||
|
|
||||||
connFailureRecovery = Timer(30, timeout)
|
connFailureRecovery = Timer(30, timeout)
|
||||||
connFailureRecovery.start()
|
connFailureRecovery.start()
|
||||||
LOG.warning("WAMP Connection Recovery timer: STARTED")
|
LOG.warning("WAMP Connection Recovery timer: STARTED")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
gdbTimeoutCheck = Timer(30, timeoutGDB)
|
||||||
|
gdbTimeoutCheck.start()
|
||||||
|
LOG.debug("WAMP Connection Recovery GDB timer: STARTED")
|
||||||
|
|
||||||
process = subprocess.Popen(
|
process = subprocess.Popen(
|
||||||
["gdb", "-p", str(LR_PID)],
|
["gdb", "-p", str(LR_PID)],
|
||||||
stdin=subprocess.PIPE,
|
stdin=subprocess.PIPE,
|
||||||
stdout=subprocess.PIPE
|
stdout=subprocess.PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
global gdbPid
|
||||||
|
gdbPid = process.pid
|
||||||
|
|
||||||
proc = psutil.Process()
|
proc = psutil.Process()
|
||||||
|
|
||||||
conn_list = proc.connections()
|
conn_list = proc.connections()
|
||||||
|
@ -250,6 +272,9 @@ def destroyWampSocket():
|
||||||
)
|
)
|
||||||
connFailureRecovery.cancel()
|
connFailureRecovery.cancel()
|
||||||
|
|
||||||
|
gdbTimeoutCheck.cancel()
|
||||||
|
LOG.debug("WAMP Connection Recovery GDB timer: CLEANED")
|
||||||
|
|
||||||
if wamp_conn_set == False:
|
if wamp_conn_set == False:
|
||||||
LOG.warning("WAMP CONNECTION NOT FOUND: LR restarting...")
|
LOG.warning("WAMP CONNECTION NOT FOUND: LR restarting...")
|
||||||
# In conn_list there is not the WAMP connection!
|
# In conn_list there is not the WAMP connection!
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 9.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -33,7 +33,13 @@
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
<div align="center"> </div>
|
<div align="center">
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<img src="{{ url_for('static', filename='images/stack4thingslogo.png') }}" alt="stack4thingslogo" width="260" height="260">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,10 @@
|
||||||
|
|
||||||
<div class="login-form">
|
<div class="login-form">
|
||||||
<form action="{{ url_for('login', next=request.args.get('next')) }}" method="post">
|
<form action="{{ url_for('login', next=request.args.get('next')) }}" method="post">
|
||||||
<div class="avatar"><i class="material-icons"></i></div>
|
<!--<div class="avatar"><i class="material-icons"></i></div>-->
|
||||||
|
<center>
|
||||||
|
<img src="{{ url_for('static', filename='images/stack4thingslogo.png') }}" alt="stack4thingslogo" width="200" height="200">
|
||||||
|
</center>
|
||||||
<h4 class="modal-title">Login to Lightning-rod</h4>
|
<h4 class="modal-title">Login to Lightning-rod</h4>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="text" class="form-control" name="username" placeholder="Username" required="required" value="{{request.form.username }}">
|
<input type="text" class="form-control" name="username" placeholder="Username" required="required" value="{{request.form.username }}">
|
||||||
|
|
|
@ -6,32 +6,65 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="jumbotron">
|
<div class="jumbotron">
|
||||||
<h2>Board info @ {{ timestamp }}</h2>
|
|
||||||
<br>
|
|
||||||
<h4> Iotronic </h4>
|
|
||||||
<li> Lightning-rod version: {{lr_version}}</li>
|
|
||||||
|
|
||||||
<li> Iotronic connection status: {{iotronic_status}}</li>
|
{% if messages %}
|
||||||
<li>Name: {{ board_name }} </li>
|
|
||||||
<li>UUID: {{ board_id }} </li>
|
|
||||||
<li>Registartion status: {{ board_reg_status }}</li>
|
|
||||||
<li>WAMP Agent: {{ wagent }} </li>
|
|
||||||
<li>Session ID: {{ session_id }} </li>
|
|
||||||
<br>
|
|
||||||
<h4> WSTUN </h4>
|
|
||||||
<li>Status: {{ wstun_status }} </li>
|
|
||||||
<li>Services: <br>
|
|
||||||
<ul>
|
|
||||||
{% autoescape false %}
|
|
||||||
{{service_list}}
|
|
||||||
{% endautoescape %}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</li>
|
<h5><b>Error messages:</b></h5>
|
||||||
<br>
|
|
||||||
<h4> Hardware information </h4>
|
<center>
|
||||||
<li>Serial device: {{ serial_dev }} </li>
|
|
||||||
<li>NIC: {{ nic }} </li>
|
<div align="left" style="width:90%">
|
||||||
|
<ul class="messages">
|
||||||
|
{% for message in messages %}
|
||||||
|
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</center>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<h2>Board info @ {{ timestamp }}</h2>
|
||||||
|
<br>
|
||||||
|
<h4> Iotronic </h4>
|
||||||
|
<li> Lightning-rod version: {{lr_version}}</li>
|
||||||
|
|
||||||
|
<li> Iotronic connection status: {{iotronic_status}}</li>
|
||||||
|
<li>Name: {{ board_name }} </li>
|
||||||
|
<li>UUID: {{ board_id }} </li>
|
||||||
|
<li>Registartion status: {{ board_reg_status }}</li>
|
||||||
|
<li>WAMP Agent: {{ wagent }} </li>
|
||||||
|
<li>Session ID: {{ session_id }} </li>
|
||||||
|
<br>
|
||||||
|
<h4> WSTUN </h4>
|
||||||
|
<li>Status: {{ wstun_status }} </li>
|
||||||
|
<li>Services: <br>
|
||||||
|
<ul>
|
||||||
|
{% autoescape false %}
|
||||||
|
{{service_list}}
|
||||||
|
{% endautoescape %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<li>WebServices: <br>
|
||||||
|
<ul>
|
||||||
|
{% autoescape false %}
|
||||||
|
{{webservice_list}}
|
||||||
|
{% endautoescape %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
<h4> Hardware information </h4>
|
||||||
|
<li>Serial device: {{ serial_dev }} </li>
|
||||||
|
<li>NIC: {{ nic }} </li>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,5 +1,4 @@
|
||||||
# Copyright 2017 MDSLAB - University of Messina
|
# Copyright 2017 MDSLAB - University of Messina. All Rights Reserved.
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
# not use this file except in compliance with the License. You may obtain
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
@ -18,10 +17,12 @@ __author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
from iotronic_lightningrod.common import utils
|
from iotronic_lightningrod.common import utils
|
||||||
from iotronic_lightningrod.config import package_path
|
from iotronic_lightningrod.config import package_path
|
||||||
from iotronic_lightningrod.lightningrod import RPC_proxies
|
from iotronic_lightningrod.lightningrod import RPC_proxies
|
||||||
|
from iotronic_lightningrod.lightningrod import wampNotify
|
||||||
from iotronic_lightningrod.modules import Module
|
from iotronic_lightningrod.modules import Module
|
||||||
import iotronic_lightningrod.wampmessage as WM
|
import iotronic_lightningrod.wampmessage as WM
|
||||||
|
|
||||||
|
from autobahn.wamp import exception
|
||||||
|
import threading
|
||||||
import importlib as imp
|
import importlib as imp
|
||||||
import inspect
|
import inspect
|
||||||
import json
|
import json
|
||||||
|
@ -29,6 +30,7 @@ import OpenSSL.crypto
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
@ -248,3 +250,74 @@ class WebServiceManager(Module.Module):
|
||||||
w_msg = WM.WampSuccess(msg=message, req_id=req_id)
|
w_msg = WM.WampSuccess(msg=message, req_id=req_id)
|
||||||
|
|
||||||
return w_msg.serialize()
|
return w_msg.serialize()
|
||||||
|
|
||||||
|
"""
|
||||||
|
# LONG
|
||||||
|
async def RenewWebservice(self, req, parameters=None):
|
||||||
|
req_id = req['uuid']
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED [req_id: " + str(req_id) + "]")
|
||||||
|
if parameters is not None:
|
||||||
|
LOG.info(" - " + rpc_name + " parameters: " + str(parameters))
|
||||||
|
|
||||||
|
message = self.board.proxy._proxyRenewWebservice()
|
||||||
|
|
||||||
|
w_msg = WM.WampSuccess(msg=message, req_id=req_id)
|
||||||
|
|
||||||
|
return w_msg.serialize()
|
||||||
|
"""
|
||||||
|
|
||||||
|
# LONG
|
||||||
|
async def RenewWebservice(self, req, parameters=None):
|
||||||
|
req_id = req['uuid']
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED [req_id: " + str(req_id) + "]")
|
||||||
|
if parameters is not None:
|
||||||
|
LOG.info(" - " + rpc_name + " parameters: " + str(parameters))
|
||||||
|
|
||||||
|
def renewing():
|
||||||
|
message = self.board.proxy._proxyRenewWebservice()
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
message = json.loads(message)
|
||||||
|
|
||||||
|
w_msg = WM.WampMessage(
|
||||||
|
message=message['message'],
|
||||||
|
result=message['result'],
|
||||||
|
req_id=req_id
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error(e)
|
||||||
|
w_msg = WM.WampError(
|
||||||
|
msg="Error returning message",
|
||||||
|
req_id=req_id
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
wampNotify(
|
||||||
|
self.session,
|
||||||
|
self.board,
|
||||||
|
w_msg.serialize(),
|
||||||
|
rpc_name
|
||||||
|
)
|
||||||
|
|
||||||
|
except exception.ApplicationError as e:
|
||||||
|
LOG.error(
|
||||||
|
" - Notify result '" + rpc_name + "' error: " + str(e)
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
threading.Thread(target=renewing).start()
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
LOG.error("Error in renewing thread: " + str(err))
|
||||||
|
|
||||||
|
out_msg = "LR is renewing webservice certificates..."
|
||||||
|
|
||||||
|
w_msg = WM.WampRunning(msg=out_msg, req_id=req_id)
|
||||||
|
|
||||||
|
return w_msg.serialize()
|
||||||
|
|
|
@ -11,7 +11,7 @@ if [ "$1" = "backup" ]; then
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
bkp_path=""
|
bkp_path="."
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -24,13 +24,15 @@ if [ "$1" = "backup" ]; then
|
||||||
tar zcvf $bkp_filename /var/lib/iotronic /etc/iotronic /etc/letsencrypt /etc/nginx/conf.d &>/dev/null
|
tar zcvf $bkp_filename /var/lib/iotronic /etc/iotronic /etc/letsencrypt /etc/nginx/conf.d &>/dev/null
|
||||||
|
|
||||||
elif [ "$1" = "restore" ]; then
|
elif [ "$1" = "restore" ]; then
|
||||||
|
|
||||||
if [ "$#" -ne 2 ]; then
|
if [ "$#" -ne 2 ]; then
|
||||||
echo "You have to specify: 'restore' <BACKUP_FILE> "
|
echo "You have to specify: 'restore' <BACKUP_FILE_PATH> "
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
# RESTORE
|
# RESTORE
|
||||||
echo "Restoring Iotronic configuration"
|
echo "Restoring Iotronic configuration"
|
||||||
tar -xvzf $2 -C /
|
#tar -xvzf $2 -C /
|
||||||
|
tar -xvf $2 -C /
|
||||||
|
|
||||||
service nginx restart
|
service nginx restart
|
||||||
|
|
||||||
|
@ -39,8 +41,13 @@ elif [ "$1" = "restore" ]; then
|
||||||
echo -e "\nCompleted!"
|
echo -e "\nCompleted!"
|
||||||
|
|
||||||
else
|
else
|
||||||
echo "You have to specify:"
|
|
||||||
echo " - for backup: 'backup'"
|
echo "You have to specify:"
|
||||||
echo " - for restore: 'restore' <backup-filename-to-restore>"
|
echo " - to backup: 'backup'"
|
||||||
exit
|
echo " - options:"
|
||||||
|
echo " --path: specify path where to save the backup file; e.g.: /tmp or /home/<USER>"
|
||||||
|
echo ""
|
||||||
|
echo " - to restore: 'restore' <BACKUP_FILE_PATH>"
|
||||||
|
exit
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
if len(sys.argv) == 1:
|
if len(sys.argv) == 1:
|
||||||
|
|
||||||
print('Arguments required:')
|
print('Arguments required:')
|
||||||
|
@ -28,6 +29,13 @@ else:
|
||||||
|
|
||||||
if sys.argv[1] == "-c":
|
if sys.argv[1] == "-c":
|
||||||
|
|
||||||
|
test=os.system('grep -Rq "<REGISTRATION-TOKEN>" ' + sys.argv[4] + '/settings.json')
|
||||||
|
#print(test)
|
||||||
|
if test == 0:
|
||||||
|
print("Configuration status: new")
|
||||||
|
else:
|
||||||
|
print("Configuration status: configured")
|
||||||
|
|
||||||
if len(sys.argv) < 5:
|
if len(sys.argv) < 5:
|
||||||
print('Arguments required: '
|
print('Arguments required: '
|
||||||
+ '<REGISTRATION-TOKEN> '
|
+ '<REGISTRATION-TOKEN> '
|
||||||
|
@ -36,20 +44,63 @@ else:
|
||||||
str(sys.argv)
|
str(sys.argv)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
os.system('sed -i "s|\\"code\\":.*|\\"code\\": \\"'
|
|
||||||
+ sys.argv[2] + '\\"|g" ' + sys.argv[4] + '/settings.json')
|
|
||||||
os.system('sed -i "s|\\"url\\":.*|\\"url\\": \\"'
|
os.system('sed -i "s|\\"url\\":.*|\\"url\\": \\"'
|
||||||
+ sys.argv[3] + '\\",|g" ' + sys.argv[4] + '/settings.json')
|
+ sys.argv[3] + '\\",|g" ' + sys.argv[4] + '/settings.json')
|
||||||
os.system('sed -i "s|<IOTRONIC-REALM>|s4t|g" '
|
os.system('sed -i "s|<IOTRONIC-REALM>|s4t|g" '
|
||||||
+ sys.argv[4] + '/settings.json')
|
+ sys.argv[4] + '/settings.json')
|
||||||
|
|
||||||
|
if test == 0:
|
||||||
|
#print("Configuration status: new")
|
||||||
|
os.system('sed -i "s|\\"code\\":.*|\\"code\\": \\"'
|
||||||
|
+ sys.argv[2] + '\\"|g" ' + sys.argv[4] + '/settings.json')
|
||||||
|
print("Configuration completed")
|
||||||
|
else:
|
||||||
|
|
||||||
|
check_reg=os.system('grep -Rq "main-agent" ' + sys.argv[4] + '/settings.json')
|
||||||
|
if check_reg == 0:
|
||||||
|
#print("Configuration status: configured")
|
||||||
|
os.system('sed -i "s|\\"code\\":.*|\\"code\\": \\"'
|
||||||
|
+ sys.argv[2] + '\\",|g" ' + sys.argv[4] + '/settings.json')
|
||||||
|
else:
|
||||||
|
os.system('sed -i "s|\\"code\\":.*|\\"code\\": \\"'
|
||||||
|
+ sys.argv[2] + '\\"|g" ' + sys.argv[4] + '/settings.json')
|
||||||
|
|
||||||
|
print("Configuration overwritten")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
|
test=os.system('grep -Rq "<REGISTRATION-TOKEN>" /etc/iotronic/settings.json')
|
||||||
|
#print(test)
|
||||||
|
if test == 0:
|
||||||
|
print("Configuration status: new")
|
||||||
|
else:
|
||||||
|
print("Configuration status: configured")
|
||||||
|
|
||||||
if len(sys.argv) < 3:
|
if len(sys.argv) < 3:
|
||||||
print('Arguments required: <REGISTRATION-TOKEN> <WAMP-REG-AGENT-URL>',
|
print('Arguments required: <REGISTRATION-TOKEN> <WAMP-REG-AGENT-URL>',
|
||||||
str(sys.argv))
|
str(sys.argv))
|
||||||
else:
|
else:
|
||||||
os.system('sed -i "s|\\"code\\":.*|\\"code\\": \\"'
|
|
||||||
+ sys.argv[1] + '\\"|g" /etc/iotronic/settings.json')
|
|
||||||
os.system('sed -i "s|\\"url\\":.*|\\"url\\": \\"'
|
os.system('sed -i "s|\\"url\\":.*|\\"url\\": \\"'
|
||||||
+ sys.argv[2] + '\\",|g" /etc/iotronic/settings.json')
|
+ sys.argv[2] + '\\",|g" /etc/iotronic/settings.json')
|
||||||
|
|
||||||
os.system('sed -i "s|<IOTRONIC-REALM>|s4t|g" /etc/iotronic/settings.json')
|
os.system('sed -i "s|<IOTRONIC-REALM>|s4t|g" /etc/iotronic/settings.json')
|
||||||
|
|
||||||
|
if test == 0:
|
||||||
|
#print("Configuration status: new")
|
||||||
|
os.system('sed -i "s|\\"code\\":.*|\\"code\\": \\"'
|
||||||
|
+ sys.argv[1] + '\\"|g" /etc/iotronic/settings.json')
|
||||||
|
print("Configuration completed")
|
||||||
|
else:
|
||||||
|
|
||||||
|
check_reg=os.system('grep -Rq "main-agent" /etc/iotronic/settings.json')
|
||||||
|
if check_reg == 0:
|
||||||
|
#print("Configuration status: configured")
|
||||||
|
os.system('sed -i "s|\\"code\\":.*|\\"code\\": \\"'
|
||||||
|
+ sys.argv[1] + '\\",|g" /etc/iotronic/settings.json')
|
||||||
|
else:
|
||||||
|
os.system('sed -i "s|\\"code\\":.*|\\"code\\": \\"'
|
||||||
|
+ sys.argv[1] + '\\"|g" /etc/iotronic/settings.json')
|
||||||
|
|
||||||
|
print("Configuration overwritten")
|
||||||
|
|
|
@ -5,6 +5,8 @@ import requests
|
||||||
|
|
||||||
r = requests.get(url = "http://localhost:1474/info")
|
r = requests.get(url = "http://localhost:1474/info")
|
||||||
|
|
||||||
data = r.json()
|
try:
|
||||||
|
data = r.json()
|
||||||
print(json.dumps(data, indent=4, sort_keys=True))
|
print(json.dumps(data, indent=4, sort_keys=True))
|
||||||
|
except:
|
||||||
|
print(r.text)
|
||||||
|
|
|
@ -101,7 +101,7 @@ print(' - logrotate configured.')
|
||||||
os.system('cp ' + py_dist_pack + '/iotronic_lightningrod/etc/systemd/system/'
|
os.system('cp ' + py_dist_pack + '/iotronic_lightningrod/etc/systemd/system/'
|
||||||
+ 's4t-lightning-rod.service '
|
+ 's4t-lightning-rod.service '
|
||||||
+ '/etc/systemd/system/lightning-rod.service')
|
+ '/etc/systemd/system/lightning-rod.service')
|
||||||
os.chmod('/etc/systemd/system/lightning-rod.service', 0o744)
|
|
||||||
print('Lightning-rod systemd script installed.')
|
print('Lightning-rod systemd script installed.')
|
||||||
|
|
||||||
|
|
||||||
|
|
1
tox.ini
1
tox.ini
|
@ -21,6 +21,7 @@ commands =
|
||||||
[testenv:pep8]
|
[testenv:pep8]
|
||||||
basepython = python3.8
|
basepython = python3.8
|
||||||
#commands = /usr/local/bin/flake8 {posargs}
|
#commands = /usr/local/bin/flake8 {posargs}
|
||||||
|
#commands = /usr/bin/flake8 {posargs}
|
||||||
commands = flake8 {posargs}
|
commands = flake8 {posargs}
|
||||||
|
|
||||||
[testenv:venv]
|
[testenv:venv]
|
||||||
|
|
|
@ -15,13 +15,33 @@ RUN echo $TZ > /etc/timezone && apt-get update && apt-get install -y tzdata && r
|
||||||
RUN apt-get update && apt-get install -y nginx python-certbot-nginx
|
RUN apt-get update && apt-get install -y nginx python-certbot-nginx
|
||||||
RUN sed -i 's/# server_names_hash_bucket_size 64;/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf
|
RUN sed -i 's/# server_names_hash_bucket_size 64;/server_names_hash_bucket_size 64;/g' /etc/nginx/nginx.conf
|
||||||
|
|
||||||
#RUN apt-get install -y certbot
|
|
||||||
|
|
||||||
RUN rm -rf /var/lib/apt/lists/*
|
RUN rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
ENV NODE_PATH=/usr/local/lib/node_modules
|
||||||
|
RUN apt update && apt install -y wget && wget https://deb.nodesource.com/setup_10.x
|
||||||
|
RUN chmod +x setup_10.x && ./setup_10.x
|
||||||
|
RUN apt-get install -y nodejs
|
||||||
|
|
||||||
RUN npm install -g --unsafe @mdslab/wstun@1.0.11 && npm cache --force clean
|
RUN npm install -g --unsafe @mdslab/wstun@1.0.11 && npm cache --force clean
|
||||||
|
|
||||||
RUN pip3 install iotronic-lightningrod
|
RUN git clone -b allowlist --depth 1 https://github.com/MDSLab/wstun.git /tmp/wstun/
|
||||||
|
RUN cp /tmp/wstun/bin/wstun.js /usr/lib/node_modules/@mdslab/wstun/bin/
|
||||||
|
RUN cp -r /tmp/wstun/lib/* /usr/lib/node_modules/@mdslab/wstun/lib/
|
||||||
|
#RUN apt update
|
||||||
|
#RUN apt install -y wget && wget https://deb.nodesource.com/setup_10.x
|
||||||
|
#RUN chmod +x setup_10.x && ./setup_10.x
|
||||||
|
#RUN apt-get install -y nodejs
|
||||||
|
#RUN npm i -g npm@latest
|
||||||
|
#RUN npm install -g --unsafe websocket@1.0.26 optimist@0.6.1 node-uuid@1.4.7 under_score log4js@1.1.1 && npm cache --force clean
|
||||||
|
#RUN cp /usr/local/lib/node_modules/@mdslab/wstun/bin/wstun.js /usr/local/bin/wstun
|
||||||
|
|
||||||
|
#RUN ln -s /usr/local/bin/wstun /usr/bin/wstun
|
||||||
|
|
||||||
|
|
||||||
|
#RUN pip3 install iotronic-lightningrod
|
||||||
|
RUN pip3 install --upgrade pip
|
||||||
|
COPY data/dist/iotronic_lightningrod-*.tar.gz /tmp/
|
||||||
|
RUN pip3 install /tmp/iotronic_lightningrod-*.tar.gz
|
||||||
|
|
||||||
RUN sed -i "s|listen 80 default_server;|listen 50000 default_server;|g" /etc/nginx/sites-available/default
|
RUN sed -i "s|listen 80 default_server;|listen 50000 default_server;|g" /etc/nginx/sites-available/default
|
||||||
RUN sed -i "s|80 default_server;|50000 default_server;|g" /etc/nginx/sites-available/default
|
RUN sed -i "s|80 default_server;|50000 default_server;|g" /etc/nginx/sites-available/default
|
||||||
|
@ -35,7 +55,7 @@ RUN /usr/local/bin/lr_install
|
||||||
|
|
||||||
VOLUME /var/lib/iotronic
|
VOLUME /var/lib/iotronic
|
||||||
|
|
||||||
RUN ln -s /usr/local/bin/wstun /usr/bin/wstun
|
#RUN ln -s /usr/local/bin/wstun /usr/bin/wstun
|
||||||
|
|
||||||
#CMD [ "/usr/sbin/nginx"]
|
#CMD [ "/usr/sbin/nginx"]
|
||||||
#CMD [ "/usr/local/bin/lightning-rod"]
|
#CMD [ "/usr/local/bin/lightning-rod"]
|
||||||
|
|
Loading…
Reference in New Issue