[虚拟化/云][全栈demo] 为qemu增加一个PCI的watchdog外设(八)

时间:2023-03-09 19:15:38
[虚拟化/云][全栈demo] 为qemu增加一个PCI的watchdog外设(八)

目的:

1. 通过网页读取watchdog的信息

2. 通过网页设置watchdog

准备工作:

1. 选择一个web框架,选用 cherrypy

$ sudo apt-get install python-cherrypy3

2. 熟悉 RESTFUL , 参考 RESR_API(Mark McLoughlin) redhat  REST API 指导

步骤:

我们选择了一个cherrypy作为web框架。 cherrypy的部署简单。

这只是个demo,没有实现MVC,大家自己练习。

此外也没有实现模板,距离一个正式的网站还差的很远。

界面实现如下:

[虚拟化/云][全栈demo] 为qemu增加一个PCI的watchdog外设(八)

代码如下:

代码中,喂狗代码采用了一个线程。需要改进。

发现不是很好,因为每个wsgi的请求都是一个线程。

最好是采用cherrypy提供的background, 或者将该逻辑独立为一个单例模式。

watchdog.py

     import cherrypy
import json
import time
import threading index_html = """
<html>
<head>
<style type="text/css">
.watchdog-state {
display: inline-block;
height: 16px;
width: 16px;
border-radius: 8px;
margin-left: 10px;
margin-right: 10px;
}
.up {
background: linear-gradient(to bottom, #BFD255 0%%, #8EB92A 50%%,
#72AA00 51%%, #9ECB2D 100%%) repeat scroll 0 0 transparent;
} .down {
background: linear-gradient(to bottom, #AFAFAF 0%%, #AFAFAF 50%%,
#AFAFAF 51%%, #AFAFAF 100%%) repeat scroll 0 0 transparent;
}
</style>
</head> <body>
<script type="text/javascript">
function requestJSON(url, suc, done, err) {
var xmlhttp;
xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", url, true);
xmlhttp.setRequestHeader("Content-type", "application/json");
xmlhttp.setRequestHeader("dataType", "application/json");
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
var responseContext = xmlhttp.responseText;
var jsonobj=eval('('+responseContext+')');
suc(jsonobj);
} else{
// alert("readyState: " + xmlhttp.readyState + "status" + xmlhttp.status);
}
}
xmlhttp.send();
} function operationWatchdog()
{
// alert("operationWatchdog");
var url = "watchdog/deactivate";
var action = document.getElementById("watchdog-action");
if (action.innerHTML == "Activate"){
url = "watchdog/activate";
}
requestJSON(url, function(data){
// alert(data.value);
});
if (action.innerHTML == "Activate"){
action.innerHTML = "Deactivate";
} else {
action.innerHTML = "Activate";
}
var status = document.getElementById("watch-status");
if (status.className.match("up$")){
status.className = "watchdog-state down";
} else{
status.className = "watchdog-state up";
}
}
function FeedWatchod()
{
// alert("FeedWatchod");
var url = "watchdog/feedstop";
var feed = document.getElementById("feed-watchdog");
if (feed.innerHTML == "Start"){
url = "watchdog/feedstart";
}
requestJSON(url, function(data){
//alert(data.value);
});
if (feed.innerHTML == "Start"){
feed.innerHTML = "Stop";
} else {
feed.innerHTML = "Start";
}
}
</script>
<div>
Status of watchdog: <span id="watch-status" class="watchdog-state %s"> </span>
<button id="watchdog-action" type="button" onclick="operationWatchdog()">%s</button>
</div>
<div>
Feed watchdog:
<button id="feed-watchdog" type="button" onclick="FeedWatchod()">Start</button>
</div>
</body>
</html> """ def jsonObj(data):
cherrypy.response.headers['Content-Type'] = 'application/json;charset=utf-8'
return json.dumps(data, indent=2, separators=(',', ':')) watchdog_hadle = open("/dev/cwd_demo", "w+")
def watchdogStatus():
vals = watchdog_hadle.readlines();
return vals[0] == ['B\x01\n'] def watchdogAction(action):
watchdog_hadle.write(action)
watchdog_hadle.flush() class WelcomePage(object):
def __init__(self):
self.watchdog = Watchdog() def index(self):
watchdog_state = "down"
watchdog_action = "Activate"
if watchdogStatus():
watchdog_state = "up"
watchdog_action = "Deactivate"
a = index_html % (watchdog_state, watchdog_action)
print a
return a
index.exposed = True def default(*args, **kwargs):
data = {"hello": "world"}
return jsonObj(data)
default.exposed = True class Watchdog(object):
exposed = True
feed_running = False
feed_thread = None def __init__(self):
pass @classmethod
def worker(cls):
while cls.feed_running:
print "worker"
watchdogAction('t')
time.sleep(1)
return @cherrypy.expose
def index(self, *args, **kwargs):
data = {"value": False}
data = {"value": watchdogStatus()}
return jsonObj(data) @cherrypy.tools.accept(media='application/json')
@cherrypy.expose
def activate(self, *args, **kwargs):
watchdogAction('a')
print "activate"
raise cherrypy.InternalRedirect("/watchdog") @cherrypy.tools.accept(media='application/json')
@cherrypy.expose
def deactivate(self, *args, **kwargs):
watchdogAction('d')
print "deactivate"
raise cherrypy.InternalRedirect("/watchdog") @cherrypy.tools.accept(media='application/json')
@cherrypy.expose
def feedstart(self, *args, **kwargs):
watchdogAction('t')
print "feed start"
if self.__class__.feed_thread == None:
self.__class__.feed_thread = threading.Thread(
target=self.__class__.worker)
if self.__class__.feed_running == False:
self.__class__.feed_running = True
self.__class__.feed_thread.start()
raise cherrypy.InternalRedirect("/watchdog") @cherrypy.expose
def feedstop(self, *args, **kwargs):
print "feed stop"
if self.__class__.feed_thread.isAlive():
self.__class__.feed_running = False
self.__class__.feed_thread.join(1.5)
self.__class__.feed_thread = None
raise cherrypy.InternalRedirect("/watchdog") if __name__ == '__main__':
# CherryPy always starts with app.root when trying to map request URIs
# to objects, so we need to mount a request handler root. A request
# to '/' will be mapped to HelloWorld().index().
cherrypy.quickstart(WelcomePage())
else:
# This branch is for the test suite; you can ignore it.
cherrypy.tree.mount(WelcomePage())