NEW WebService module; Device Manager improved; installation procedures updated.
Change-Id: I40a70948b830edc387cef6032f6f9fea036ec66f
This commit is contained in:
parent
1b20493251
commit
76f9b5372b
|
@ -12,4 +12,5 @@ ChangeLog
|
||||||
*.md
|
*.md
|
||||||
.eggs
|
.eggs
|
||||||
dist
|
dist
|
||||||
__pycache__
|
iotronic_lightningrod/modules/test.py
|
||||||
|
iotronic_lightningrod/modules/vfs_*
|
|
@ -6,6 +6,8 @@ include etc/systemd/system/s4t-lightning-rod.service
|
||||||
include etc/logrotate.d/lightning-rod.log
|
include etc/logrotate.d/lightning-rod.log
|
||||||
include scripts/lr_install
|
include scripts/lr_install
|
||||||
include scripts/lr_configure
|
include scripts/lr_configure
|
||||||
|
include scripts/device_bkp_rest
|
||||||
|
include iotronic_lightningrod/proxies/configs/*
|
||||||
|
|
||||||
include AUTHORS
|
include AUTHORS
|
||||||
include ChangeLog
|
include ChangeLog
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
|
lightningrod_home = /var/lib/iotronic
|
||||||
|
skip_cert_verify = True
|
||||||
debug = True
|
debug = True
|
||||||
|
proxy = nginx
|
||||||
log_file = /var/log/iotronic/lightning-rod.log
|
log_file = /var/log/iotronic/lightning-rod.log
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import json
|
import json
|
||||||
|
@ -48,6 +48,7 @@ class Board(object):
|
||||||
self.location = {}
|
self.location = {}
|
||||||
|
|
||||||
self.device = None
|
self.device = None
|
||||||
|
self.proxy = None
|
||||||
|
|
||||||
self.wamp_config = None
|
self.wamp_config = None
|
||||||
self.extra = {}
|
self.extra = {}
|
||||||
|
@ -77,9 +78,6 @@ class Board(object):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
LOG.info("Lightning-rod home:")
|
|
||||||
LOG.info(" - " + CONF.lightningrod_home)
|
|
||||||
|
|
||||||
# Load all settings.json file
|
# Load all settings.json file
|
||||||
self.iotronic_config = self.loadConf()
|
self.iotronic_config = self.loadConf()
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
|
@ -33,13 +33,17 @@ def manageTimeout(error_message, action):
|
||||||
os._exit(1)
|
os._exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
class NginxError(Exception):
|
||||||
|
|
||||||
|
def __init__(self, message):
|
||||||
|
super(NginxError, self).__init__(message)
|
||||||
|
|
||||||
|
|
||||||
class TimeoutError(Exception):
|
class TimeoutError(Exception):
|
||||||
|
|
||||||
def __init__(self, message, action):
|
def __init__(self, message, action):
|
||||||
# Call the base class constructor with the parameters it needs
|
|
||||||
super(TimeoutError, self).__init__(message)
|
super(TimeoutError, self).__init__(message)
|
||||||
|
|
||||||
# Now for your custom code...
|
|
||||||
self.action = action
|
self.action = action
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
|
@ -13,13 +13,12 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
import six
|
import six
|
||||||
|
|
|
@ -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 RaspberryGpio(Gpio.Gpio):
|
||||||
|
def __init__(self):
|
||||||
|
super(RaspberryGpio, self).__init__("raspberry")
|
||||||
|
LOG.info("Raspberry GPIO module importing...")
|
||||||
|
|
||||||
|
# Enable GPIO
|
||||||
|
def EnableGPIO(self):
|
||||||
|
result = " - GPIO not available for 'raspberry' device!"
|
||||||
|
LOG.info(result)
|
||||||
|
|
||||||
|
def DisableGPIO(self):
|
||||||
|
result = " - GPIO not available for 'raspberry' device!"
|
||||||
|
LOG.info(result)
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
@ -29,9 +29,9 @@ class ServerGpio(Gpio.Gpio):
|
||||||
|
|
||||||
# Enable GPIO
|
# Enable GPIO
|
||||||
def EnableGPIO(self):
|
def EnableGPIO(self):
|
||||||
result = ' - GPIO not available for server device!'
|
result = " - GPIO not available for 'server' device!"
|
||||||
LOG.info(result)
|
LOG.info(result)
|
||||||
|
|
||||||
def DisableGPIO(self):
|
def DisableGPIO(self):
|
||||||
result = ' - GPIO not available for server device!'
|
result = " - GPIO not available for 'server' device!"
|
||||||
LOG.info(result)
|
LOG.info(result)
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
|
|
@ -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 raspberry
|
||||||
|
|
||||||
|
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__("raspberry")
|
||||||
|
|
||||||
|
raspberry.RaspberryGpio().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
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
from iotronic_lightningrod.devices import Device
|
from iotronic_lightningrod.devices import Device
|
||||||
from iotronic_lightningrod.devices.gpio import yun
|
from iotronic_lightningrod.devices.gpio import yun
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
# Autobahn imports
|
# Autobahn imports
|
||||||
import asyncio
|
import asyncio
|
||||||
|
@ -47,16 +47,25 @@ LOG = logging.getLogger(__name__)
|
||||||
lr_opts = [
|
lr_opts = [
|
||||||
cfg.StrOpt('lightningrod_home',
|
cfg.StrOpt('lightningrod_home',
|
||||||
default='/var/lib/iotronic',
|
default='/var/lib/iotronic',
|
||||||
help=('Lightning Home Data')),
|
help=('Lightning-rod Home Data')),
|
||||||
cfg.BoolOpt('skip_cert_verify',
|
cfg.BoolOpt('skip_cert_verify',
|
||||||
default=True,
|
default=True,
|
||||||
help=('Flag for skipping the verification of the server cert '
|
help=('Flag for skipping the verification of the server cert '
|
||||||
'(for the auto-signed ones)')),
|
'(for the auto-signed ones)')),
|
||||||
|
]
|
||||||
|
|
||||||
|
proxy_opts = [
|
||||||
|
cfg.StrOpt(
|
||||||
|
'proxy',
|
||||||
|
choices=[('nginx', ('nginx proxy')), ],
|
||||||
|
help=('Proxy for WebServices Manager')
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
CONF.register_opts(lr_opts)
|
CONF.register_opts(lr_opts)
|
||||||
|
CONF.register_opts(proxy_opts)
|
||||||
|
|
||||||
|
|
||||||
SESSION = None
|
SESSION = None
|
||||||
global board
|
global board
|
||||||
|
@ -64,6 +73,7 @@ board = None
|
||||||
reconnection = False
|
reconnection = False
|
||||||
RPC = {}
|
RPC = {}
|
||||||
RPC_devices = {}
|
RPC_devices = {}
|
||||||
|
RPC_proxies = {}
|
||||||
|
|
||||||
# ASYNCIO
|
# ASYNCIO
|
||||||
loop = None
|
loop = None
|
||||||
|
@ -168,7 +178,7 @@ def modulesLoader(session):
|
||||||
# LOG.debug(ext.name)
|
# LOG.debug(ext.name)
|
||||||
|
|
||||||
if (ext.name == 'gpio') & (board.type == 'server'):
|
if (ext.name == 'gpio') & (board.type == 'server'):
|
||||||
LOG.info('- GPIO module disabled for laptop devices')
|
LOG.info("- GPIO module disabled for 'server' devices")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
mod = ext.plugin(board, session)
|
mod = ext.plugin(board, session)
|
||||||
|
@ -448,7 +458,7 @@ def wampConnect(wamp_conf):
|
||||||
LOG.info("\n\n\nBoard is becoming operative...\n\n\n")
|
LOG.info("\n\n\nBoard is becoming operative...\n\n\n")
|
||||||
board.updateStatus("operative")
|
board.updateStatus("operative")
|
||||||
board.loadSettings()
|
board.loadSettings()
|
||||||
LOG.info("WAMP status @ firt connection:" +
|
LOG.info("WAMP status @ first connection:" +
|
||||||
"\n- board = " + str(board.status) +
|
"\n- board = " + str(board.status) +
|
||||||
"\n- reconnection = " + str(reconnection) +
|
"\n- reconnection = " + str(reconnection) +
|
||||||
"\n- connected = " + str(connected)
|
"\n- connected = " + str(connected)
|
||||||
|
@ -674,21 +684,41 @@ def Bye():
|
||||||
|
|
||||||
|
|
||||||
def LogoLR():
|
def LogoLR():
|
||||||
LOG.info('')
|
|
||||||
LOG.info('##############################')
|
LOG.info('##############################')
|
||||||
LOG.info(' Stack4Things Lightning-rod')
|
LOG.info(' Stack4Things Lightning-rod')
|
||||||
LOG.info('##############################')
|
LOG.info('##############################')
|
||||||
|
|
||||||
|
|
||||||
|
def checkIotronicConf(lr_CONF):
|
||||||
|
try:
|
||||||
|
if(lr_CONF.log_file == None):
|
||||||
|
LOG.warning("'log_file' is not specified!")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print("View logs in " + lr_CONF.log_file)
|
||||||
|
return True
|
||||||
|
except Exception as err:
|
||||||
|
print(err)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class LightningRod(object):
|
class LightningRod(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
|
LogoLR()
|
||||||
|
|
||||||
|
LOG.info("LR available modules: ")
|
||||||
|
for ep in pkg_resources.iter_entry_points(group='s4t.modules'):
|
||||||
|
LOG.info(" - " + str(ep))
|
||||||
|
|
||||||
logging.register_options(CONF)
|
logging.register_options(CONF)
|
||||||
DOMAIN = "s4t-lightning-rod"
|
DOMAIN = "s4t-lightning-rod"
|
||||||
CONF(project='iotronic')
|
CONF(project='iotronic')
|
||||||
logging.setup(CONF, DOMAIN)
|
logging.setup(CONF, DOMAIN)
|
||||||
|
|
||||||
|
if (checkIotronicConf(CONF)):
|
||||||
|
|
||||||
if CONF.debug:
|
if CONF.debug:
|
||||||
txaio.start_logging(level="debug")
|
txaio.start_logging(level="debug")
|
||||||
|
|
||||||
|
@ -699,15 +729,19 @@ class LightningRod(object):
|
||||||
global board
|
global board
|
||||||
board = Board()
|
board = Board()
|
||||||
|
|
||||||
LOG.info('Info:')
|
LOG.info('Lightning-rod configurations:')
|
||||||
LOG.info(' - Logs: /var/log/s4t-lightning-rod.log')
|
LOG.info(' - Logs: ' + CONF.log_file)
|
||||||
current_time = board.getTimestamp()
|
LOG.info(" - Current time: " + board.getTimestamp())
|
||||||
LOG.info(" - Current time: " + current_time)
|
LOG.info(" - Home: " + CONF.lightningrod_home)
|
||||||
|
LOG.info(" - WebServices Proxy: " + CONF.proxy)
|
||||||
|
|
||||||
self.w = WampManager(board.wamp_config)
|
self.w = WampManager(board.wamp_config)
|
||||||
|
|
||||||
self.w.start()
|
self.w.start()
|
||||||
|
|
||||||
|
else:
|
||||||
|
Bye()
|
||||||
|
|
||||||
def stop_handler(self, signum, frame):
|
def stop_handler(self, signum, frame):
|
||||||
LOG.info("LR is shutting down...")
|
LOG.info("LR is shutting down...")
|
||||||
self.w.stop()
|
self.w.stop()
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
import six
|
import six
|
||||||
|
|
|
@ -13,16 +13,20 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import imp
|
import importlib as imp
|
||||||
import inspect
|
import inspect
|
||||||
import os
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
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 SESSION
|
from iotronic_lightningrod.lightningrod import SESSION
|
||||||
from iotronic_lightningrod.modules import Module
|
from iotronic_lightningrod.modules import Module
|
||||||
|
from iotronic_lightningrod.modules import utils
|
||||||
|
|
||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
@ -36,15 +40,19 @@ class DeviceManager(Module.Module):
|
||||||
# Module declaration
|
# Module declaration
|
||||||
super(DeviceManager, self).__init__("DeviceManager", board)
|
super(DeviceManager, self).__init__("DeviceManager", board)
|
||||||
|
|
||||||
|
self.device_session = session
|
||||||
|
|
||||||
device_type = board.type
|
device_type = board.type
|
||||||
|
|
||||||
path = package_path + "/devices/" + device_type + ".py"
|
path = package_path + "/devices/" + device_type + ".py"
|
||||||
|
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
|
|
||||||
device_module = imp.load_source("device", path)
|
device_module = imp.import_module(
|
||||||
|
"iotronic_lightningrod.devices." + device_type
|
||||||
|
)
|
||||||
|
|
||||||
LOG.info(" - Device " + device_type + " module imported!")
|
LOG.info(" - Device '" + device_type + "' module imported!")
|
||||||
|
|
||||||
device = device_module.System()
|
device = device_module.System()
|
||||||
|
|
||||||
|
@ -60,7 +68,7 @@ class DeviceManager(Module.Module):
|
||||||
board.device = device
|
board.device = device
|
||||||
|
|
||||||
else:
|
else:
|
||||||
LOG.warning("Device " + device_type + " not supported!")
|
LOG.warning("Device '" + device_type + "' not supported!")
|
||||||
|
|
||||||
def finalize(self):
|
def finalize(self):
|
||||||
pass
|
pass
|
||||||
|
@ -82,3 +90,52 @@ class DeviceManager(Module.Module):
|
||||||
SESSION.register(meth[1], rpc_addr)
|
SESSION.register(meth[1], rpc_addr)
|
||||||
|
|
||||||
LOG.info(" --> " + str(meth[0]) + " registered!")
|
LOG.info(" --> " + str(meth[0]) + " registered!")
|
||||||
|
|
||||||
|
async def DevicePing(self):
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED")
|
||||||
|
return datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f')
|
||||||
|
|
||||||
|
async def DeviceReboot(self):
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED")
|
||||||
|
|
||||||
|
command = "reboot"
|
||||||
|
subprocess.call(command, shell=True)
|
||||||
|
|
||||||
|
return datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f')
|
||||||
|
|
||||||
|
async def DeviceHostname(self):
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED")
|
||||||
|
|
||||||
|
command = "hostname"
|
||||||
|
# subprocess.call(command, shell=True)
|
||||||
|
|
||||||
|
out = subprocess.Popen(
|
||||||
|
command,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE
|
||||||
|
)
|
||||||
|
|
||||||
|
output = out.communicate()[0].decode('utf-8').strip()
|
||||||
|
print(output)
|
||||||
|
|
||||||
|
return str(output) + "@" + \
|
||||||
|
str(datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f'))
|
||||||
|
|
||||||
|
"""
|
||||||
|
async def DeviceWampDisconnect(self):
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED")
|
||||||
|
|
||||||
|
import threading, time
|
||||||
|
|
||||||
|
def delayDisconnection():
|
||||||
|
time.sleep(5)
|
||||||
|
SESSION.disconnect()
|
||||||
|
|
||||||
|
threading.Thread(target=delayDisconnection).start()
|
||||||
|
|
||||||
|
return "Device disconnection in 5 seconds..."
|
||||||
|
"""
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import imp
|
import importlib as imp
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import queue
|
import queue
|
||||||
|
@ -166,7 +166,11 @@ class PluginManager(Module.Module):
|
||||||
|
|
||||||
if os.path.exists(plugin_filename):
|
if os.path.exists(plugin_filename):
|
||||||
|
|
||||||
task = imp.load_source("plugin", plugin_filename)
|
# task = imp.load_source("plugin", plugin_filename)
|
||||||
|
task = imp.machinery.SourceFileLoader(
|
||||||
|
"plugin",
|
||||||
|
plugin_filename
|
||||||
|
).load_module()
|
||||||
|
|
||||||
if os.path.exists(plugin_params_file):
|
if os.path.exists(plugin_params_file):
|
||||||
|
|
||||||
|
@ -362,7 +366,10 @@ class PluginManager(Module.Module):
|
||||||
# Import plugin (as python module)
|
# Import plugin (as python module)
|
||||||
if os.path.exists(plugin_filename):
|
if os.path.exists(plugin_filename):
|
||||||
|
|
||||||
task = imp.load_source("plugin", plugin_filename)
|
task = imp.machinery.SourceFileLoader(
|
||||||
|
"plugin",
|
||||||
|
plugin_filename
|
||||||
|
).load_module()
|
||||||
|
|
||||||
LOG.info(" - Plugin '" + plugin_uuid + "' imported!")
|
LOG.info(" - Plugin '" + plugin_uuid + "' imported!")
|
||||||
|
|
||||||
|
@ -527,7 +534,11 @@ class PluginManager(Module.Module):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
task = imp.load_source("plugin", plugin_filename)
|
# task = imp.load_source("plugin", plugin_filename)
|
||||||
|
task = imp.machinery.SourceFileLoader(
|
||||||
|
"plugin",
|
||||||
|
plugin_filename
|
||||||
|
).load_module()
|
||||||
|
|
||||||
LOG.info(" - Plugin " + plugin_uuid + " imported!")
|
LOG.info(" - Plugin " + plugin_uuid + " imported!")
|
||||||
|
|
||||||
|
@ -751,7 +762,11 @@ class PluginManager(Module.Module):
|
||||||
if os.path.exists(plugin_filename):
|
if os.path.exists(plugin_filename):
|
||||||
|
|
||||||
# Import plugin python module
|
# Import plugin python module
|
||||||
task = imp.load_source("plugin", plugin_filename)
|
# task = imp.load_source("plugin", plugin_filename)
|
||||||
|
task = imp.machinery.SourceFileLoader(
|
||||||
|
"plugin",
|
||||||
|
plugin_filename
|
||||||
|
).load_module()
|
||||||
|
|
||||||
if parameters is None:
|
if parameters is None:
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import errno
|
import errno
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
|
@ -38,6 +38,6 @@ class Test(Module.Module):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
async def add(self, x, y):
|
async def add(self, x, y):
|
||||||
c = await x + y
|
c = x + y
|
||||||
LOG.info("DEVICE add result: " + str(c))
|
LOG.info("DEVICE add result: " + str(c))
|
||||||
return c
|
return c
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import inspect
|
import inspect
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import errno
|
import errno
|
||||||
from fuse import FuseOSError
|
from fuse import FuseOSError
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import errno
|
import errno
|
||||||
import os
|
import os
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
# Copyright 2017 MDSLAB - University of Messina
|
||||||
|
# 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 iotronic_lightningrod.modules import Module
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
from oslo_log import log as logging
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
|
||||||
|
import importlib as imp
|
||||||
|
import inspect
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
from iotronic_lightningrod.config import package_path
|
||||||
|
from iotronic_lightningrod.lightningrod import RPC_proxies
|
||||||
|
from iotronic_lightningrod.lightningrod import SESSION
|
||||||
|
from iotronic_lightningrod.modules import utils
|
||||||
|
import iotronic_lightningrod.wampmessage as WM
|
||||||
|
|
||||||
|
|
||||||
|
class WebServiceManager(Module.Module):
|
||||||
|
|
||||||
|
def __init__(self, board, session):
|
||||||
|
super(WebServiceManager, self).__init__("WebServiceManager", board)
|
||||||
|
|
||||||
|
LOG.info(" - Proxy used: " + CONF.proxy.upper())
|
||||||
|
|
||||||
|
proxy_type = CONF.proxy
|
||||||
|
path = package_path + "/proxies/" + proxy_type + ".py"
|
||||||
|
|
||||||
|
if os.path.exists(path):
|
||||||
|
|
||||||
|
proxy_module = imp.import_module("iotronic_lightningrod.proxies."
|
||||||
|
+ proxy_type)
|
||||||
|
LOG.info(" --> " + proxy_type.upper() + " module imported!")
|
||||||
|
|
||||||
|
proxy = proxy_module.ProxyManager()
|
||||||
|
|
||||||
|
proxy_meth_list = inspect.getmembers(
|
||||||
|
proxy,
|
||||||
|
predicate=inspect.ismethod
|
||||||
|
)
|
||||||
|
|
||||||
|
RPC_proxies[proxy_type] = proxy_meth_list
|
||||||
|
|
||||||
|
board.proxy = proxy
|
||||||
|
|
||||||
|
self._proxyWampRegister(proxy_meth_list, board)
|
||||||
|
|
||||||
|
else:
|
||||||
|
LOG.warning("Proxy '" + proxy_type + "' not supported!")
|
||||||
|
|
||||||
|
def finalize(self):
|
||||||
|
|
||||||
|
proxy_status = json.loads(self.board.proxy._proxyInfo())
|
||||||
|
LOG.info("--> Proxy " + self.board.proxy.type.upper()
|
||||||
|
+ " status:\n Active: " + str(proxy_status['status'])
|
||||||
|
+ "\n Info: " + str(proxy_status['log']))
|
||||||
|
|
||||||
|
LOG.info("Webservice exposed on device:")
|
||||||
|
active_webservice_list = self.board.proxy._webserviceList()
|
||||||
|
if len(active_webservice_list) != 0:
|
||||||
|
for ws in active_webservice_list:
|
||||||
|
LOG.info("-> " + ws)
|
||||||
|
else:
|
||||||
|
LOG.info("-> NO WebService!")
|
||||||
|
|
||||||
|
LOG.info("WebService Manager initialized!")
|
||||||
|
|
||||||
|
def restore(self):
|
||||||
|
LOG.info("WebService Manager restored.")
|
||||||
|
|
||||||
|
def _proxyWampRegister(self, proxy_meth_list, board):
|
||||||
|
|
||||||
|
LOG.info(" - " + str(board.proxy.type).upper()
|
||||||
|
+ " proxy registering RPCs:")
|
||||||
|
|
||||||
|
for meth in proxy_meth_list:
|
||||||
|
if (meth[0] != "__init__") & (meth[0] != "finalize") \
|
||||||
|
& (meth[0] != "restore"):
|
||||||
|
# LOG.info(" - " + str(meth[0]))
|
||||||
|
rpc_addr = u'iotronic.' + board.uuid + '.' + meth[0]
|
||||||
|
# LOG.debug(" --> " + str(rpc_addr))
|
||||||
|
if not meth[0].startswith('_'):
|
||||||
|
SESSION.register(meth[1], rpc_addr)
|
||||||
|
LOG.info(" --> " + str(meth[0]))
|
||||||
|
|
||||||
|
async def ExposeWebservice(self, service_name, local_port):
|
||||||
|
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED")
|
||||||
|
|
||||||
|
response = self.board.proxy._exposeWebservice(service_name, local_port)
|
||||||
|
|
||||||
|
response = json.loads(response)
|
||||||
|
|
||||||
|
if(response['result'] == "SUCCESS"):
|
||||||
|
message = "Webservice '" + service_name + "' successfully exposed!"
|
||||||
|
LOG.info("--> " + str(message))
|
||||||
|
w_msg = WM.WampSuccess(response)
|
||||||
|
else:
|
||||||
|
message = "Error exposing webservice '" + service_name + "'"
|
||||||
|
LOG.warning("--> " + str(response['message']))
|
||||||
|
w_msg = WM.WampWarning(response)
|
||||||
|
|
||||||
|
return w_msg.serialize()
|
||||||
|
|
||||||
|
async def UnexposeWebservice(self, service_name):
|
||||||
|
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED")
|
||||||
|
|
||||||
|
response = self.board.proxy._disableWebservice(service_name)
|
||||||
|
|
||||||
|
response = json.loads(response)
|
||||||
|
|
||||||
|
if (response['result'] == "SUCCESS"):
|
||||||
|
LOG.info("--> " + str(response['message']))
|
||||||
|
w_msg = WM.WampSuccess(response)
|
||||||
|
else:
|
||||||
|
LOG.warning("--> " + str(response['message']))
|
||||||
|
w_msg = WM.WampWarning(response)
|
||||||
|
|
||||||
|
return w_msg.serialize()
|
||||||
|
|
||||||
|
async def BoardDnsCertsSetup(self, board_dns, owner_email):
|
||||||
|
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED")
|
||||||
|
|
||||||
|
message = self.board.proxy._proxyBoardDnsSetup(board_dns, owner_email)
|
||||||
|
w_msg = WM.WampSuccess(message)
|
||||||
|
|
||||||
|
return w_msg.serialize()
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
import six
|
import six
|
||||||
|
@ -23,19 +23,6 @@ from oslo_log import log as logging
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
from twisted.internet.defer import inlineCallbacks
|
|
||||||
|
|
||||||
@inlineCallbacks
|
|
||||||
def sendNotification(msg=None):
|
|
||||||
try:
|
|
||||||
res = yield SESSION.call(u'agent.stack4things.echo', msg)
|
|
||||||
LOG.info("NOTIFICATION " + str(res))
|
|
||||||
except Exception as e:
|
|
||||||
LOG.warning("NOTIFICATION error: {0}".format(e))
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(abc.ABCMeta)
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
class Plugin(threading.Thread):
|
class Plugin(threading.Thread):
|
||||||
|
|
||||||
|
@ -63,13 +50,6 @@ class Plugin(threading.Thread):
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self._is_running = False
|
self._is_running = False
|
||||||
|
|
||||||
"""
|
|
||||||
def Done(self):
|
|
||||||
self.setStatus("COMPLETED")
|
|
||||||
sendNotification(msg="hello!")
|
|
||||||
self.checkStatus()
|
|
||||||
"""
|
|
||||||
|
|
||||||
def checkStatus(self):
|
def checkStatus(self):
|
||||||
# LOG.debug("Plugin " + self.name + " check status: " + self.status)
|
# LOG.debug("Plugin " + self.name + " check status: " + self.status)
|
||||||
return self.status
|
return self.status
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import _pickle as pickle
|
import _pickle as pickle
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import httplib2
|
import httplib2
|
||||||
import json
|
import json
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
{"name":"LR"}
|
|
@ -27,6 +27,6 @@ class Worker(Plugin.Plugin):
|
||||||
super(Worker, self).__init__(uuid, name, q_result, params)
|
super(Worker, self).__init__(uuid, name, q_result, params)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
LOG.info("Input parameters: " + str(self.params))
|
LOG.info("Input parameters: " + str(self.params['name']))
|
||||||
LOG.info("Plugin " + self.name + " process completed!")
|
LOG.info("Plugin " + self.name + " process completed!")
|
||||||
self.q_result.put("ZERO RESULT")
|
self.q_result.put("ECHO RESULT: "+str(self.params['name']))
|
|
@ -1 +0,0 @@
|
||||||
{}
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
# 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 abc
|
||||||
|
import six
|
||||||
|
|
||||||
|
from oslo_log import log as logging
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
|
class Proxy(object):
|
||||||
|
"""Base class for proxies supported by Iotornic.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, proxy_type):
|
||||||
|
self.type = proxy_type
|
||||||
|
|
||||||
|
def finalize(self):
|
||||||
|
pass
|
|
@ -0,0 +1,7 @@
|
||||||
|
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";
|
|
@ -0,0 +1,7 @@
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
|
||||||
|
server_name BOARD_DNS;
|
||||||
|
include conf.d/iotronic/*;
|
||||||
|
}
|
|
@ -0,0 +1,374 @@
|
||||||
|
# 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 iotronic_lightningrod.proxies import Proxy
|
||||||
|
|
||||||
|
from oslo_log import log as logging
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import site
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
|
||||||
|
from iotronic_lightningrod.common.exception import NginxError
|
||||||
|
from iotronic_lightningrod.modules import utils
|
||||||
|
import iotronic_lightningrod.wampmessage as WM
|
||||||
|
from subprocess import call
|
||||||
|
|
||||||
|
|
||||||
|
class ProxyManager(Proxy.Proxy):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(ProxyManager, self).__init__("nginx")
|
||||||
|
|
||||||
|
def finalize(self):
|
||||||
|
"""Function called at the end of module loading (after RPC registration).
|
||||||
|
|
||||||
|
:return:
|
||||||
|
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _proxyInfo(self):
|
||||||
|
|
||||||
|
nginxMsg = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
stat = subprocess.Popen('systemctl status nginx.service',
|
||||||
|
shell=True, stdout=subprocess.PIPE)
|
||||||
|
stdout_list = str(stat.communicate()[0]).split('\n')
|
||||||
|
for line in stdout_list:
|
||||||
|
if 'Active:' in line:
|
||||||
|
|
||||||
|
nginxMsg['log'] = line.split('\\n')[2].replace(" ", "")
|
||||||
|
|
||||||
|
if '(running)' in line:
|
||||||
|
nginxMsg['status'] = True
|
||||||
|
else:
|
||||||
|
nginxMsg['status'] = False
|
||||||
|
|
||||||
|
nginxMsg = json.dumps(nginxMsg)
|
||||||
|
|
||||||
|
return nginxMsg
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
LOG.error("Error check NGINX status: " + str(err))
|
||||||
|
nginxMsg['log'] = str(err)
|
||||||
|
nginxMsg['status'] = False
|
||||||
|
nginxMsg = json.dumps(nginxMsg)
|
||||||
|
return nginxMsg
|
||||||
|
|
||||||
|
def _proxyStatus(self):
|
||||||
|
|
||||||
|
nginxMsg = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
stat = subprocess.Popen(
|
||||||
|
'systemctl status nginx.service',
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE
|
||||||
|
)
|
||||||
|
stdout_list = str(stat.communicate()[0]).split('\n')
|
||||||
|
for line in stdout_list:
|
||||||
|
if 'Active:' in line:
|
||||||
|
if '(running)' in line:
|
||||||
|
nginxMsg['log'] = "NGINX is running"
|
||||||
|
nginxMsg['status'] = True
|
||||||
|
# LOG.info("--> " + nginxMsg['log'])
|
||||||
|
else:
|
||||||
|
nginxMsg['log'] = "NGINX is not running"
|
||||||
|
nginxMsg['status'] = False
|
||||||
|
# LOG.warning("--> " + nginxMsg['log'])
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
nginxMsg['log'] = "Error check NGINX status: " + str(err)
|
||||||
|
nginxMsg['status'] = True
|
||||||
|
# LOG.error("--> " + nginxMsg['log'])
|
||||||
|
|
||||||
|
return json.dumps(nginxMsg)
|
||||||
|
|
||||||
|
def _proxyReload(self):
|
||||||
|
|
||||||
|
nginxMsg = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
stat = subprocess.call('service nginx reload', shell=True)
|
||||||
|
|
||||||
|
if stat != 0:
|
||||||
|
raise NginxError(str(stat))
|
||||||
|
|
||||||
|
else:
|
||||||
|
nginxMsg['log'] = "NGINX successfully reloaded"
|
||||||
|
nginxMsg['code'] = stat
|
||||||
|
LOG.info("--> " + nginxMsg['log'])
|
||||||
|
|
||||||
|
except NginxError:
|
||||||
|
nginxMsg['log'] = "NGINX reloading error"
|
||||||
|
nginxMsg['code'] = stat
|
||||||
|
LOG.warning("--> " + nginxMsg['log'])
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
nginxMsg['log'] = "NGINX Generic error: " + str(err)
|
||||||
|
nginxMsg['code'] = stat
|
||||||
|
LOG.warning("--> " + nginxMsg['log'])
|
||||||
|
|
||||||
|
nginxMsg = json.dumps(nginxMsg)
|
||||||
|
return nginxMsg
|
||||||
|
|
||||||
|
def _proxyRestart(self):
|
||||||
|
|
||||||
|
nginxMsg = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
stat = os.system('systemctl restart nginx')
|
||||||
|
|
||||||
|
if stat != 0:
|
||||||
|
raise NginxError(str(stat))
|
||||||
|
|
||||||
|
else:
|
||||||
|
nginxMsg['log'] = "NGINX successfully restart"
|
||||||
|
nginxMsg['code'] = stat
|
||||||
|
LOG.info("--> " + nginxMsg['log'])
|
||||||
|
|
||||||
|
except NginxError:
|
||||||
|
nginxMsg['log'] = "NGINX restarting error"
|
||||||
|
nginxMsg['code'] = stat
|
||||||
|
LOG.warning("--> " + nginxMsg['log'])
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
nginxMsg['log'] = "NGINX generic error: " + str(err)
|
||||||
|
nginxMsg['code'] = stat
|
||||||
|
LOG.warning("--> " + nginxMsg['log'])
|
||||||
|
|
||||||
|
return json.dumps(nginxMsg)
|
||||||
|
|
||||||
|
def _proxyBoardDnsSetup(self, board_dns, owner_email):
|
||||||
|
|
||||||
|
nginxMsg = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
py_dist_pack = site.getsitepackages()[0]
|
||||||
|
|
||||||
|
iotronic_nginx_path = "/etc/nginx/conf.d/iotronic"
|
||||||
|
iotronic_nginx_default = "/etc/nginx/conf.d/iotronic/default"
|
||||||
|
|
||||||
|
if not os.path.exists(iotronic_nginx_path):
|
||||||
|
os.makedirs(iotronic_nginx_path)
|
||||||
|
|
||||||
|
nginx_default = '''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";'''
|
||||||
|
|
||||||
|
with open(iotronic_nginx_default, "w") as text_file:
|
||||||
|
text_file.write("%s" % nginx_default)
|
||||||
|
|
||||||
|
iotronic_nginx_avl_path = "/etc/nginx/sites-available/iotronic"
|
||||||
|
|
||||||
|
string = '''server {{
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
server_name {0};
|
||||||
|
include conf.d/iotronic/*;
|
||||||
|
}}'''.format(board_dns)
|
||||||
|
|
||||||
|
with open(iotronic_nginx_avl_path, "w") as text_file:
|
||||||
|
text_file.write("%s" % string)
|
||||||
|
|
||||||
|
os.system(
|
||||||
|
'ln -s '
|
||||||
|
'/etc/nginx/sites-available/iotronic '
|
||||||
|
'/etc/nginx/sites-enabled/'
|
||||||
|
)
|
||||||
|
|
||||||
|
time.sleep(3)
|
||||||
|
self._proxyReload()
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
command = '/usr/bin/certbot -n ' \
|
||||||
|
'--redirect --authenticator webroot ' \
|
||||||
|
'--installer nginx -w /var/www/html/ ' \
|
||||||
|
'--domain ' + board_dns + ' --agree-tos ' \
|
||||||
|
'--email ' + owner_email
|
||||||
|
|
||||||
|
LOG.debug(command)
|
||||||
|
call(command, shell=True)
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
nginxMsg['log'] = "NGINX DNS setup error: " + str(err)
|
||||||
|
nginxMsg['code'] = ""
|
||||||
|
LOG.warning("--> " + nginxMsg['log'])
|
||||||
|
|
||||||
|
return json.dumps(nginxMsg)
|
||||||
|
|
||||||
|
def _exposeWebservice(self, service_name, local_port):
|
||||||
|
|
||||||
|
nginxMsg = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
nginx_path = "/etc/nginx/conf.d/iotronic"
|
||||||
|
|
||||||
|
if not os.path.exists(nginx_path):
|
||||||
|
os.makedirs(nginx_path)
|
||||||
|
|
||||||
|
fp = nginx_path + "/" + service_name
|
||||||
|
|
||||||
|
string = '''location /{0}/ {{
|
||||||
|
proxy_pass http://localhost:{1}/;
|
||||||
|
include conf.d/iotronic/default;
|
||||||
|
}}
|
||||||
|
|
||||||
|
location /{0} {{
|
||||||
|
rewrite ^ $scheme://$http_host/{0}/ redirect;
|
||||||
|
}}
|
||||||
|
'''.format(service_name, local_port)
|
||||||
|
|
||||||
|
with open(fp, "w") as ws_nginx_conf:
|
||||||
|
ws_nginx_conf.write("%s" % string)
|
||||||
|
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
nginxMsg['message'] = "Webservice '" + service_name + \
|
||||||
|
"' configuration injected in NGINX."
|
||||||
|
nginxMsg['result'] = "SUCCESS"
|
||||||
|
LOG.info("--> " + nginxMsg['message'])
|
||||||
|
|
||||||
|
self._proxyReload()
|
||||||
|
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
nginxMsg['message'] = "Error exposing Webservice '" + \
|
||||||
|
service_name + \
|
||||||
|
"' configuration in NGINX: {}".format(e)
|
||||||
|
nginxMsg['result'] = "ERROR"
|
||||||
|
LOG.warning("--> " + nginxMsg['message'])
|
||||||
|
|
||||||
|
return json.dumps(nginxMsg)
|
||||||
|
|
||||||
|
def _disableWebservice(self, service_name):
|
||||||
|
|
||||||
|
nginxMsg = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
nginx_path = "/etc/nginx/conf.d/iotronic"
|
||||||
|
service_path = nginx_path + "/" + service_name
|
||||||
|
|
||||||
|
if os.path.exists(service_path):
|
||||||
|
|
||||||
|
os.remove(service_path)
|
||||||
|
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
nginxMsg['message'] = "webservice '" \
|
||||||
|
+ service_name + "' disabled."
|
||||||
|
nginxMsg['result'] = "SUCCESS"
|
||||||
|
# LOG.info("--> " + nginxMsg['message'])
|
||||||
|
|
||||||
|
self._proxyReload()
|
||||||
|
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
else:
|
||||||
|
nginxMsg['message'] = "webservice file " \
|
||||||
|
+ service_path + " does not exist"
|
||||||
|
nginxMsg['result'] = "ERROR"
|
||||||
|
# LOG.info("--> " + nginxMsg['message'])
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
nginxMsg['message'] = "Error disabling Webservice '" + \
|
||||||
|
service_name + "': {}".format(e)
|
||||||
|
nginxMsg['result'] = "ERROR"
|
||||||
|
# LOG.warning("--> " + nginxMsg['message'])
|
||||||
|
|
||||||
|
return json.dumps(nginxMsg)
|
||||||
|
|
||||||
|
def _webserviceList(self):
|
||||||
|
|
||||||
|
nginx_path = "/etc/nginx/conf.d/iotronic"
|
||||||
|
|
||||||
|
if os.path.exists(nginx_path):
|
||||||
|
service_list = [f for f in os.listdir(nginx_path)
|
||||||
|
if os.path.isfile(os.path.join(nginx_path, f))]
|
||||||
|
|
||||||
|
service_list.remove('default')
|
||||||
|
else:
|
||||||
|
service_list = []
|
||||||
|
|
||||||
|
return service_list
|
||||||
|
|
||||||
|
async def NginxInfo(self):
|
||||||
|
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED")
|
||||||
|
|
||||||
|
message = self._proxyInfo()
|
||||||
|
w_msg = WM.WampSuccess(message)
|
||||||
|
|
||||||
|
return w_msg.serialize()
|
||||||
|
|
||||||
|
async def NginxStatus(self):
|
||||||
|
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED")
|
||||||
|
|
||||||
|
message = self._proxyStatus()
|
||||||
|
w_msg = WM.WampSuccess(message)
|
||||||
|
|
||||||
|
return w_msg.serialize()
|
||||||
|
|
||||||
|
async def NginxReload(self):
|
||||||
|
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED")
|
||||||
|
|
||||||
|
message = self._proxyReload()
|
||||||
|
w_msg = WM.WampSuccess(message)
|
||||||
|
|
||||||
|
return w_msg.serialize()
|
||||||
|
|
||||||
|
async def NginxRestart(self):
|
||||||
|
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED")
|
||||||
|
|
||||||
|
message = self._proxyRestart()
|
||||||
|
w_msg = WM.WampSuccess(message)
|
||||||
|
|
||||||
|
return w_msg.serialize()
|
||||||
|
|
||||||
|
async def NginxIotronicConf(self):
|
||||||
|
|
||||||
|
rpc_name = utils.getFuncName()
|
||||||
|
LOG.info("RPC " + rpc_name + " CALLED")
|
||||||
|
|
||||||
|
message = self._proxyIotronicConf()
|
||||||
|
w_msg = WM.WampSuccess(message)
|
||||||
|
|
||||||
|
return w_msg.serialize()
|
|
@ -13,7 +13,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
__author__ = "Nicola Peditto <npeditto@unime.it"
|
__author__ = "Nicola Peditto <n.peditto@gmail.com>"
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Option chosen: "$1 $2
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$1" = "backup" ]; then
|
||||||
|
if [ "$#" -ne 1 ]; then
|
||||||
|
echo "You have to specify: 'restore' <BACKUP_FILE> "
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
# BACKUP
|
||||||
|
echo "Backing up Iotronic configuration"
|
||||||
|
now_date=`date '+%Y%m%d%H%M%S'`
|
||||||
|
device=`cat /etc/iotronic/settings.json | grep name | awk '{print $2}' | tr -d \" | tr -d ,`
|
||||||
|
bkp_filename="bkp_"$device"_"$now_date".tar.gz"
|
||||||
|
echo "-> backup filename: " $bkp_filename
|
||||||
|
tar zcvf $bkp_filename /var/lib/iotronic /etc/iotronic /etc/letsencrypt /etc/nginx > /dev/null
|
||||||
|
|
||||||
|
elif [ "$1" = "restore" ]; then
|
||||||
|
if [ "$#" -ne 2 ]; then
|
||||||
|
echo "You have to specify: 'restore' <BACKUP_FILE> "
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
# RESTORE
|
||||||
|
echo "Restoring Iotronic configuration"
|
||||||
|
tar -xvzf $2 -C /
|
||||||
|
|
||||||
|
service nginx restart
|
||||||
|
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
echo -e "\nCompleted!"
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "You have to specify:"
|
||||||
|
echo " - for backup: 'backup'"
|
||||||
|
echo " - for restore: 'restore' <backup-filename-to-restore>"
|
||||||
|
exit
|
||||||
|
fi
|
|
@ -22,8 +22,8 @@ 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|<REGISTRATION-TOKEN>|'
|
os.system('sed -i "s|\\"code\\":.*|\\"code\\": \\"'
|
||||||
+ sys.argv[1] + '|g" /etc/iotronic/settings.json')
|
+ sys.argv[1] + '\\"|g" /etc/iotronic/settings.json')
|
||||||
os.system('sed -i "s|ws://<WAMP-SERVER>:<WAMP-PORT>/|'
|
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')
|
||||||
|
|
|
@ -18,10 +18,18 @@
|
||||||
import os
|
import os
|
||||||
import site
|
import site
|
||||||
|
|
||||||
|
if os.path.exists('/iotronic_lightningrod/'):
|
||||||
|
print("Cleaning install folders...")
|
||||||
|
os.system('rm -rf ' + site.getsitepackages()[0]
|
||||||
|
+ '/iotronic_lightningrod/etc')
|
||||||
|
os.system('rm -rf ' + site.getsitepackages()[0]
|
||||||
|
+ '/iotronic_lightningrod/templates')
|
||||||
|
print("Moving installation folders...")
|
||||||
|
os.system('mv -f /iotronic_lightningrod/* '
|
||||||
|
+ site.getsitepackages()[0] + '/iotronic_lightningrod/')
|
||||||
|
|
||||||
py_dist_pack = site.getsitepackages()[0]
|
py_dist_pack = site.getsitepackages()[0]
|
||||||
print(py_dist_pack)
|
print("Python packages folder: " + py_dist_pack)
|
||||||
|
|
||||||
|
|
||||||
print('Iotronic environment creation:')
|
print('Iotronic environment creation:')
|
||||||
if not os.path.exists('/etc/iotronic/'):
|
if not os.path.exists('/etc/iotronic/'):
|
||||||
|
|
|
@ -4,7 +4,7 @@ summary = Implementation of the Lightning-rod, the Stack4Things board-side probe
|
||||||
description-file =
|
description-file =
|
||||||
README.rst
|
README.rst
|
||||||
author = Nicola Peditto, Fabio Verboso
|
author = Nicola Peditto, Fabio Verboso
|
||||||
author-email = unime.mdslab@gmail.com
|
author-email = n.peditto@gmail.com
|
||||||
home-page = http://stack4things.unime.it/
|
home-page = http://stack4things.unime.it/
|
||||||
classifier =
|
classifier =
|
||||||
Environment :: OpenStack
|
Environment :: OpenStack
|
||||||
|
@ -21,7 +21,7 @@ classifier =
|
||||||
[files]
|
[files]
|
||||||
packages =
|
packages =
|
||||||
iotronic_lightningrod
|
iotronic_lightningrod
|
||||||
data_files =
|
data-files =
|
||||||
bin/ = scripts/*
|
bin/ = scripts/*
|
||||||
/iotronic_lightningrod/templates = templates/*
|
/iotronic_lightningrod/templates = templates/*
|
||||||
/iotronic_lightningrod/etc/iotronic = etc/iotronic/iotronic.conf
|
/iotronic_lightningrod/etc/iotronic = etc/iotronic/iotronic.conf
|
||||||
|
@ -65,8 +65,9 @@ s4t.modules =
|
||||||
plugin = iotronic_lightningrod.modules.plugin_manager:PluginManager
|
plugin = iotronic_lightningrod.modules.plugin_manager:PluginManager
|
||||||
device = iotronic_lightningrod.modules.device_manager:DeviceManager
|
device = iotronic_lightningrod.modules.device_manager:DeviceManager
|
||||||
service = iotronic_lightningrod.modules.service_manager:ServiceManager
|
service = iotronic_lightningrod.modules.service_manager:ServiceManager
|
||||||
network = iotronic_lightningrod.modules.network_manager:NetworkManager
|
# network = iotronic_lightningrod.modules.network_manager:NetworkManager
|
||||||
# vfs = iotronic_lightningrod.modules.vfs_manager:VfsManager
|
webservice = iotronic_lightningrod.modules.webservice_manager:WebServiceManager
|
||||||
|
# vfs = iotronic_lightningrod.modules.vfs_manager:VfsManager
|
||||||
|
|
||||||
[options]
|
[options]
|
||||||
build_scripts =
|
build_scripts =
|
||||||
|
|
Loading…
Reference in New Issue