diff options
Diffstat (limited to 'meta-raptor/meta-asus/recipes-asus/rest-api')
10 files changed, 809 insertions, 0 deletions
diff --git a/meta-raptor/meta-asus/recipes-asus/rest-api/files/bmc_command.py b/meta-raptor/meta-asus/recipes-asus/rest-api/files/bmc_command.py new file mode 100644 index 0000000..d4dc877 --- /dev/null +++ b/meta-raptor/meta-asus/recipes-asus/rest-api/files/bmc_command.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# +# Copyright 2014-present Facebook. All Rights Reserved. +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals + +import os +import subprocess +import select +import sys +import time + +DEFAULT_TIMEOUT = 10 #sec + +# Note: Python 3.0 supports communicate() with a timeout option. +# If we upgrade to this version we will no longer need timed_communicate + +class TimeoutError(Exception): + def __init__(self, output, error): + super(TimeoutError, self).__init__('process timed out') + self.output = output + self.error = error + +class WaitTimeoutError(Exception): + pass + +def kill_process(proc): + proc.terminate() + try: + timed_wait(proc, 0.1) + except WaitTimeoutError: + proc.kill() + try: + timed_wait(proc, 0.1) + except WaitTimeoutError: + # This can happen if the process is stuck waiting inside a system + # call for a long time. There isn't much we can do unless we want + # to keep waiting forever. Just give up. The child process will + # remain around as a zombie until we exit. + pass + +def timed_wait(proc, timeout): + # There unfortunately isn't a great way to wait for a process with a + # timeout, other than polling. (Registering for SIGCHLD and sleeping might + # be one option, but that's fragile and not thread-safe.) + poll_interval = 0.1 + end_time = time.time() + timeout + while True: + if proc.poll() is not None: + return + time_left = max(end_time - time.time(), 0) + if time_left <= 0: + raise WaitTimeoutError() + time.sleep(min(time_left, poll_interval)) + +def timed_communicate(proc, timeout=DEFAULT_TIMEOUT): + end_time = time.time() + timeout + + p = select.poll() + outfd = proc.stdout.fileno() + errfd = proc.stderr.fileno() + p.register(outfd, select.POLLIN) + p.register(errfd, select.POLLIN) + results = {outfd: [], errfd: []} + remaining_fds = set([outfd, errfd]) + + bufsize = 4096 + while remaining_fds: + time_left = max(end_time - time.time(), 0) + r = p.poll(time_left * 1000) # poll() takes timeout in milliseconds + if not r: + kill_process(proc) + raise TimeoutError(b''.join(results[outfd]), + b''.join(results[errfd])) + for fd, flags in r: + # We didn't put the fds in non-blocking mode, but we know the fd + # has data to read, so os.read() will return immediately. + d = os.read(fd, bufsize) + if d: + results[fd].append(d) + else: + # EOF on this fd, stop listening on it + p.unregister(fd) + remaining_fds.remove(fd) + + try: + timed_wait(proc, max(end_time - time.time(), 0)) + except WaitTimeoutError: + kill_process(proc) + raise TimeoutError(b''.join(results[outfd]), + b''.join(results[errfd])) + + return b''.join(results[outfd]), b''.join(results[errfd]) diff --git a/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest.py b/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest.py new file mode 100644 index 0000000..876f03a --- /dev/null +++ b/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python +# +# Copyright 2017 Raptor Engineering, LLC +# Copyright 2014-present Facebook. All Rights Reserved. +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# + +from ctypes import * +import bottle +from cherrypy.wsgiserver import CherryPyWSGIServer +from cherrypy.wsgiserver.ssl_pyopenssl import pyOpenSSLAdapter +import datetime +import logging +import logging.config +import json +import ssl +import socket +import os +import rest_fruid +import rest_server +import rest_sensors +import rest_bmc +import rest_gpios +import rest_slotid + +CONSTANTS = { + 'certificate': '/usr/lib/ssl/certs/rest_server.pem', + 'key': '/usr/lib/ssl/private/rest_server_key.pem', + 'listen_address': '0.0.0.0', +} + +LOGGER_CONF = { + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + 'default': { + 'format': '%(message)s' + }, + }, + 'handlers': { + 'file_handler': { + 'level': 'INFO', + 'formatter':'default', + 'class': 'logging.handlers.RotatingFileHandler', + 'filename':'/tmp/rest.log', + 'maxBytes': 1048576, + 'backupCount': 3, + 'encoding': 'utf8' + }, + }, + 'loggers': { + '': { + 'handlers': ['file_handler'], + 'level': 'DEBUG', + 'propagate': True, + }, + } +} + +# Handler for root resource endpoint +@bottle.route('/api') +def rest_api(): + result = { + "Information": { + "Description": "Wedge RESTful API Entry", + }, + "Actions": [], + "Resources": [ "sys"], + } + + return result + +# Handler for sys resource endpoint +@bottle.route('/api/sys') +def rest_sys(): + result = { + "Information": { + "Description": "System", + }, + "Actions": [], + "Resources": [ "mb", "bmc", "server", "sensors", "gpios", + "slotid"], + } + + return result + +# Handler for sys/mb resource endpoint +@bottle.route('/api/sys/mb') +def rest_sys(): + result = { + "Information": { + "Description": "Mainboard", + }, + "Actions": [], + "Resources": [ "fruid"], + } + + return result + +# Handler for sys/mb/fruid resource endpoint +@bottle.route('/api/sys/mb/fruid') +def rest_fruid_hdl(): + return rest_fruid.get_fruid() + +# Handler for sys/bmc resource endpoint +@bottle.route('/api/sys/bmc') +def rest_bmc_hdl(): + return rest_bmc.get_bmc() + +# Handler for sys/server resource endpoint +@bottle.route('/api/sys/server') +def rest_server_hdl(): + return rest_server.get_server() + +# Handler for uServer resource endpoint +@bottle.route('/api/sys/server', method='POST') +def rest_server_act_hdl(): + data = json.load(request.body) + return rest_server.server_action(data) + +# Handler for sensors resource endpoint +@bottle.route('/api/sys/sensors') +def rest_sensors_hdl(): + return rest_sensors.get_sensors() + +# Handler for sensors resource endpoint +@bottle.route('/api/sys/gpios') +def rest_gpios_hdl(): + return rest_gpios.get_gpios() + +# Handler for sensors resource endpoint +@bottle.route('/api/sys/slotid') +def rest_slotid_hdl(): + return rest_slotid.get_slotid() + +# SSL Wrapper for Rest API +class SSLCherryPyServer(bottle.ServerAdapter): + def run(self, handler): + server = CherryPyWSGIServer((self.host, self.port), handler) + server.ssl_adapter = pyOpenSSLAdapter(CONSTANTS['certificate'], CONSTANTS['key']) + try: + server.start() + finally: + server.stop() + + +def log_after_request(): + try: + length = bottle.response.content_length + except: + try: + length = len(bottle.response.body) + except: + length = 0 + + logging.info('{} - - [{}] "{} {} {}" {} {}'.format( + bottle.request.environ.get('REMOTE_ADDR'), + datetime.datetime.now().strftime('%d/%b/%Y %H:%M:%S'), + bottle.request.environ.get('REQUEST_METHOD'), + bottle.request.environ.get('REQUEST_URI'), + bottle.request.environ.get('SERVER_PROTOCOL'), + bottle.response.status_code, + length)) + + +# Error logging to log file +class ErrorLogging(object): + def write(self, err): + logging.error(err) + + +# Middleware to log the requests +class LogMiddleware(object): + def __init__(self, app): + self.app = app + + def __call__(self, e, h): + e['wsgi.errors'] = ErrorLogging() + ret_val = self.app(e, h) + log_after_request() + return ret_val + +# overwrite the stderr and stdout to log to the file +bottle._stderr = logging.error +bottle._stdout = logging.info +logging.config.dictConfig(LOGGER_CONF) + +bottle_app = LogMiddleware(bottle.app()) +# Use SSL if the certificate and key exists. Otherwise, run without SSL. +if (os.access(CONSTANTS['key'], os.R_OK) and + os.access(CONSTANTS['certificate'], os.R_OK)): + bottle.run(host = CONSTANTS['listen_address'], port = 8443, server=SSLCherryPyServer, app=bottle_app) +else: + bottle.run(host = CONSTANTS['listen_address'], port = 8080, server='cherrypy', app=bottle_app) diff --git a/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_bmc.py b/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_bmc.py new file mode 100644 index 0000000..fe838b6 --- /dev/null +++ b/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_bmc.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# +# Copyright 2017 Raptor Engineering, LLC +# Copyright 2014-present Facebook. All Rights Reserved. +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# + + +from subprocess import * +import re + +# Handler for FRUID resource endpoint +def get_bmc(): + # Get BMC Reset Reason + wdt_counter = Popen('devmem 0x1e785010', \ + shell=True, stdout=PIPE).stdout.read() + wdt_counter = int(wdt_counter, 0) + + wdt_counter &= 0xff00 + + if wdt_counter: + por_flag = 0 + else: + por_flag = 1 + + if por_flag: + reset_reason = "Power ON Reset" + else: + reset_reason = "User Initiated Reset or WDT Reset" + + # Get BMC's Up Time + uptime = Popen('uptime', \ + shell=True, stdout=PIPE).stdout.read() + + # Get Usage information + data = Popen('top -b n1', \ + shell=True, stdout=PIPE).stdout.read() + adata = data.split('\n') + mem_usage = adata[0] + cpu_usage = adata[1] + + # Get OpenBMC version + version = "" + data = Popen('cat /etc/issue', \ + shell=True, stdout=PIPE).stdout.read() + ver = re.search(r'v([\w\d._-]*)\s', data) + if ver: + version = ver.group(1) + + result = { + "Information": { + "Description": "ASUS ASMB4iKVM BMC", + "Reset Reason": reset_reason, + "Uptime": uptime, + "Memory Usage": mem_usage, + "CPU Usage": cpu_usage, + "OpenBMC Version": version, + }, + "Actions": [], + "Resources": [], + } + + return result; + diff --git a/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_fruid.py b/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_fruid.py new file mode 100644 index 0000000..245afc4 --- /dev/null +++ b/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_fruid.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# +# Copyright 2017 Raptor Engineering, LLC +# Copyright 2014-present Facebook. All Rights Reserved. +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# + +import subprocess + +def get_fruid(): + + mac2str = lambda mac: ':'.join(['{:02X}'.format(b) for b in mac]) + + fruinfo = { "Version": subprocess.Popen(['fw_printenv', 'fru_version'], stdout=subprocess.PIPE).communicate()[0], + "Product Name": subprocess.Popen(['fw_printenv', 'fru_product'], stdout=subprocess.PIPE).communicate()[0], + "Product Part Number": subprocess.Popen(['fw_printenv', 'fru_product_pn'], stdout=subprocess.PIPE).communicate()[0], + "System Assembly Part Number": subprocess.Popen(['fw_printenv', 'fru_subassembly'], stdout=subprocess.PIPE).communicate()[0], + "ODM PCB Part Number": subprocess.Popen(['fw_printenv', 'fru_odm_pn'], stdout=subprocess.PIPE).communicate()[0], + "ODM PCB Serial Number": subprocess.Popen(['fw_printenv', 'fru_odm_serial'], stdout=subprocess.PIPE).communicate()[0], + "Product Production State": subprocess.Popen(['fw_printenv', 'fru_prod_stat'], stdout=subprocess.PIPE).communicate()[0], + "Product Version": subprocess.Popen(['fw_printenv', 'fru_prod_major_version'], stdout=subprocess.PIPE).communicate()[0], + "Product Sub-Version": subprocess.Popen(['fw_printenv', 'fru_prod_minor_version'], stdout=subprocess.PIPE).communicate()[0], + "Product Serial Number": subprocess.Popen(['fw_printenv', 'fru_prod_serial'], stdout=subprocess.PIPE).communicate()[0], + "Product Asset Tag": subprocess.Popen(['fw_printenv', 'fru_asset_tag'], stdout=subprocess.PIPE).communicate()[0], + "System Manufacturer": subprocess.Popen(['fw_printenv', 'fru_prod_manufacturer'], stdout=subprocess.PIPE).communicate()[0], + "System Manufacturing Date": subprocess.Popen(['fw_printenv', 'fru_manufacturing_date'], stdout=subprocess.PIPE).communicate()[0], + "PCB Manufacturer": subprocess.Popen(['fw_printenv', 'fru_pcb_manufacturer'], stdout=subprocess.PIPE).communicate()[0], + "Assembled At": subprocess.Popen(['fw_printenv', 'fru_assembled_at'], stdout=subprocess.PIPE).communicate()[0], + "Local MAC": subprocess.Popen(['fw_printenv', 'ethaddr'], stdout=subprocess.PIPE).communicate()[0], + "Location": subprocess.Popen(['fw_printenv', 'fru_location'], stdout=subprocess.PIPE).communicate()[0] + } + + result = { + "Information": fruinfo, + "Actions": [], + "Resources": [], + } + + return result diff --git a/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_gpios.py b/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_gpios.py new file mode 100644 index 0000000..dcbb436 --- /dev/null +++ b/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_gpios.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# +# Copyright 2017 Raptor Engineering, LLC +# Copyright 2014-present Facebook. All Rights Reserved. +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# + +from rest_fruid import get_fruid + +MAINBOARDS = ["KGPE-D16", "KCMA-D8"] + + +def read_gpio_sysfs(gpio): + with open('/sys/class/gpio/gpio%d/value' % gpio, 'r') as f: + val_string = f.read() + if val_string == '1\n': + return 1 + if val_string == '0\n': + return 0 + return None + + +def read_asus_gpio(): + bhinfo = {} + return bhinfo + + +def get_gpios(): + fruinfo = get_fruid() + gpioinfo = {} + if fruinfo["Information"]["Product Name"] in MAINBOARDS: + gpioinfo["back_ports"] = read_asus_gpio() + return gpioinfo diff --git a/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_sensors.py b/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_sensors.py new file mode 100644 index 0000000..01e8f89 --- /dev/null +++ b/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_sensors.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# +# Copyright 2017 Raptor Engineering, LLC +# Copyright 2014-present Facebook. All Rights Reserved. +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# + +import json +import re +import subprocess +import bmc_command + +# Handler for sensors resource endpoint +def get_sensors(): + result = [] + proc = subprocess.Popen(['sensors'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + try: + data, err = bmc_command.timed_communicate(proc) + except bmc_command.TimeoutError as ex: + data = ex.output + err = ex.error + + data = re.sub(r'\(.+?\)', '', data) + data = re.sub(r' sensor = .*', '', data) + for edata in data.split('\n\n'): + adata = edata.split('\n', 1) + sresult = {} + if (len(adata) < 2): + break; + sresult['name'] = adata[0] + for sdata in adata[1].split('\n'): + tdata = sdata.split(':') + if (len(tdata) < 2): + continue + sresult[tdata[0].strip()] = tdata[1].strip() + result.append(sresult) + + fresult = { + "Information": result, + "Actions": [], + "Resources": [], + } + return fresult diff --git a/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_server.py b/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_server.py new file mode 100644 index 0000000..7a334a6 --- /dev/null +++ b/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_server.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +# +# Copyright 2017 Raptor Engineering, LLC +# Copyright 2014-present Facebook. All Rights Reserved. +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# + + +import os +from subprocess import * + +# Handler for mainboard resource endpoint +def get_server(): + ret = Popen('/usr/local/bin/asus_power.sh status', \ + shell=True, stdout=PIPE).stdout.read() + status = ret.rsplit()[-1] + + result = { + "Information": { "status": status }, + "Actions": ["power-on", "power-off", "power-reset"], + "Resources": [], + } + + return result + +def server_action(data): + if data["action"] == 'power-on': + ret = Popen('/usr/local/bin/asus_power.sh status', \ + shell=True, stdout=PIPE).stdout.read() + status = ret.rsplit()[-1] + if status == 'on': + res = 'failure' + reason = 'already on' + else: + ret = Popen('/usr/local/bin/asus_power.sh on', \ + shell=True, stdout=PIPE).stdout.read() + res = "success" + elif data["action"] == 'power-off': + ret = Popen('/usr/local/bin/asus_power.sh off', \ + shell=True, stdout=PIPE).stdout.read() + res = "success" + elif data["action"] == 'power-reset': + ret = Popen('/usr/local/bin/asus_power.sh reset', \ + shell=True, stdout=PIPE).stdout.read() + res = "success" + else: + res = 'failure' + reason = 'invalid action' + + if res == 'failure': + result = { "result": res, "reason": reason} + else: + result = { "result": res } + + return result diff --git a/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_slotid.py b/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_slotid.py new file mode 100644 index 0000000..1b03b91 --- /dev/null +++ b/meta-raptor/meta-asus/recipes-asus/rest-api/files/rest_slotid.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# +# Copyright 2017 Raptor Engineering, LLC +# Copyright 2014-present Facebook. All Rights Reserved. +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# + +import subprocess + +# Handler for sensors resource endpoint +def get_slotid(): + p = subprocess.Popen('source /usr/local/bin/openbmc-utils.sh;' + 'asus_slot_id $(asus_board_type)', + shell=True, stdout=subprocess.PIPE) + out, err = p.communicate() + try: + slot = int(out.strip('\n')) + except: + slot = 0 + return { 'slotid' : slot } diff --git a/meta-raptor/meta-asus/recipes-asus/rest-api/files/setup-rest-api.sh b/meta-raptor/meta-asus/recipes-asus/rest-api/files/setup-rest-api.sh new file mode 100644 index 0000000..2b274dc --- /dev/null +++ b/meta-raptor/meta-asus/recipes-asus/rest-api/files/setup-rest-api.sh @@ -0,0 +1,79 @@ +#!/bin/sh +# +# Copyright 2014-present Facebook. All Rights Reserved. +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# + +### BEGIN INIT INFO +# Provides: setup-rest-api +# Required-Start: +# Required-Stop: +# Default-Start: S +# Default-Stop: +# Short-Description: Set REST API handler +### END INIT INFO + +# source function library +. /etc/init.d/functions + +ACTION="$1" +CMD="/usr/local/bin/rest.py" +case "$ACTION" in + start) + echo -n "Setting up REST API handler: " + pid=$(ps | grep -v grep | grep $CMD | awk '{print $1}') + if [ $pid ]; then + echo "already running" + else + $CMD > /tmp/rest_start.log 2>&1 & + echo "done." + fi + ;; + stop) + echo -n "Stopping REST API handler: " + pid=$(ps | grep -v grep | grep $CMD | awk '{print $1}') + if [ $pid ]; then + kill $pid + fi + echo "done." + ;; + restart) + echo -n "Restarting REST API handler: " + pid=$(ps | grep -v grep | grep $CMD | awk '{print $1}') + if [ $pid ]; then + kill $pid + fi + sleep 1 + $CMD > /tmp/rest_start.log 2>&1 & + echo "done." + ;; + status) + if [[ -n $(ps | grep -v grep | grep $CMD | awk '{print $1}') ]]; then + echo "REST API handler is running" + else + echo "REST API is stopped" + fi + ;; + *) + N=${0##*/} + N=${N#[SK]??} + echo "Usage: $N {start|stop|status|restart}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/meta-raptor/meta-asus/recipes-asus/rest-api/rest-api_0.1.bb b/meta-raptor/meta-asus/recipes-asus/rest-api/rest-api_0.1.bb new file mode 100644 index 0000000..53675b7 --- /dev/null +++ b/meta-raptor/meta-asus/recipes-asus/rest-api/rest-api_0.1.bb @@ -0,0 +1,70 @@ +# Copyright 2017 Raptor Engineering, LLC +# Copyright 2014-present Facebook. All Rights Reserved. +# +# This program file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +SUMMARY = "Rest API Daemon" +DESCRIPTION = "Daemon to handle RESTful interface." +SECTION = "base" +PR = "r1" +LICENSE = "GPLv2" +LIC_FILES_CHKSUM = "file://rest.py;beginline=6;endline=19;md5=0b1ee7d6f844d472fa306b2fee2167e0" + + +DEPENDS_append = " update-rc.d-native" + +SRC_URI = "file://setup-rest-api.sh \ + file://rest.py \ + file://rest_bmc.py \ + file://rest_fruid.py \ + file://rest_gpios.py \ + file://rest_server.py \ + file://rest_sensors.py \ + file://rest_slotid.py \ + file://bmc_command.py \ + " + +S = "${WORKDIR}" + +binfiles = "rest.py rest_bmc.py rest_fruid.py rest_gpios.py rest_server.py rest_sensors.py bmc_command.py rest_slotid.py setup-rest-api.sh" + +pkgdir = "rest-api" + +do_install() { + dst="${D}/usr/local/fbpackages/${pkgdir}" + bin="${D}/usr/local/bin" + install -d $dst + install -d $bin + for f in ${binfiles}; do + install -m 755 $f ${dst}/$f + ln -snf ../fbpackages/${pkgdir}/$f ${bin}/$f + done + for f in ${otherfiles}; do + install -m 644 $f ${dst}/$f + done + install -d ${D}${sysconfdir}/init.d + install -d ${D}${sysconfdir}/rcS.d + install -m 755 setup-rest-api.sh ${D}${sysconfdir}/init.d/setup-rest-api.sh + update-rc.d -r ${D} setup-rest-api.sh start 95 2 3 4 5 . +} + +FBPACKAGEDIR = "${prefix}/local/fbpackages" + +FILES_${PN} = "${FBPACKAGEDIR}/rest-api ${prefix}/local/bin ${sysconfdir} " + +# Inhibit complaints about .debug directories for the fand binary: + +INHIBIT_PACKAGE_DEBUG_SPLIT = "1" +INHIBIT_PACKAGE_STRIP = "1" |