import latest version #2
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
packages/
|
packages/
|
||||||
*.apk
|
*.apk
|
||||||
|
.on-save.json
|
||||||
|
17
APKBUILD
17
APKBUILD
@ -1,27 +1,26 @@
|
|||||||
# Contributor: Paolo Asperti <paolo@asperti.com>
|
# Contributor: Paolo Asperti <paolo@asperti.com>
|
||||||
# Maintainer: Paolo Asperti <paolo@asperti.com>
|
# Maintainer: Paolo Asperti <paolo@asperti.com>
|
||||||
pkgname=acf-openpdu
|
pkgname=acf-openpdu
|
||||||
pkgver=0.1
|
pkgver=0.3
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Linux installation caching system"
|
pkgdesc="ACF interface for the OpenPDU project"
|
||||||
url="https://github.com/paspo/installinux"
|
url="https://github.com/openpdu/acf-openpdu"
|
||||||
arch="noarch"
|
arch="noarch"
|
||||||
license="GPL2"
|
license="GPL2"
|
||||||
depends="acf-core"
|
depends="acf-core openpdu lua-cjson"
|
||||||
makedepends=""
|
makedepends=""
|
||||||
install="acf-openpdu.post-install"
|
install="acf-openpdu.post-install"
|
||||||
subpackages=""
|
subpackages=""
|
||||||
source=""
|
source=""
|
||||||
|
options="!check"
|
||||||
|
|
||||||
package() {
|
build() {
|
||||||
mkdir -p "$pkgdir"
|
:
|
||||||
}
|
}
|
||||||
|
|
||||||
package() {
|
package() {
|
||||||
|
mkdir -p "$pkgdir"
|
||||||
# make DESTDIR=$pkgdir install || return 1
|
# make DESTDIR=$pkgdir install || return 1
|
||||||
install -Dm644 etc/openpdu/openpdu.conf "$pkgdir"/etc/openpdu/openpdu.conf
|
|
||||||
install -Dm755 etc/local.d/openpdu.start "$pkgdir"/etc/local.d/openpdu.start
|
|
||||||
|
|
||||||
install -Dm644 acf-app/openpdu.menu "$pkgdir"/usr/share/acf/app/openpdu/openpdu.menu
|
install -Dm644 acf-app/openpdu.menu "$pkgdir"/usr/share/acf/app/openpdu/openpdu.menu
|
||||||
install -Dm644 acf-app/openpdu.roles "$pkgdir"/usr/share/acf/app/openpdu/openpdu.roles
|
install -Dm644 acf-app/openpdu.roles "$pkgdir"/usr/share/acf/app/openpdu/openpdu.roles
|
||||||
install -Dm644 acf-app/openpdu-controller.lua "$pkgdir"/usr/share/acf/app/openpdu/openpdu-controller.lua
|
install -Dm644 acf-app/openpdu-controller.lua "$pkgdir"/usr/share/acf/app/openpdu/openpdu-controller.lua
|
||||||
|
6
README
6
README
@ -7,12 +7,12 @@ Under "OpenPDU" you can control your outlets.
|
|||||||
DONE:
|
DONE:
|
||||||
* Basic Outlet Status (almost everything hardcoded :( )
|
* Basic Outlet Status (almost everything hardcoded :( )
|
||||||
* Power control (ON/OFF) for each socket
|
* Power control (ON/OFF) for each socket
|
||||||
* All the sockets are powered ON on boot
|
* All the outlets are powered ON on boot
|
||||||
* ACF package
|
* ACF package
|
||||||
|
* configuration file editing
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
* configuration file
|
* editing outlet parameters
|
||||||
* editing socket parameters
|
|
||||||
* everything else (there's a long list)
|
* everything else (there's a long list)
|
||||||
|
|
||||||
BUGS:
|
BUGS:
|
||||||
|
1
acf-app/openpdu-boardsconf-html.lsp
Symbolic link
1
acf-app/openpdu-boardsconf-html.lsp
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../expert-html.lsp
|
@ -16,4 +16,12 @@ mymodule.poweroff = function(self)
|
|||||||
return self.handle_form(self, self.model.get_setpower, self.model.setpoweroff, self.clientdata, "commitpower", "Action result")
|
return self.handle_form(self, self.model.get_setpower, self.model.setpoweroff, self.clientdata, "commitpower", "Action result")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function mymodule.outletsconf(self)
|
||||||
|
return self.handle_form(self, self.model.get_outletsFiledetails, self.model.update_outletsFiledetails, self.clientdata, "Save", "Edit Outlets Config File", "Configuration Set")
|
||||||
|
end
|
||||||
|
|
||||||
|
function mymodule.boardsconf(self)
|
||||||
|
return self.handle_form(self, self.model.get_boardsFiledetails, self.model.update_boardsFiledetails, self.clientdata, "Save", "Edit Boards Config File", "Configuration Set")
|
||||||
|
end
|
||||||
|
|
||||||
return mymodule
|
return mymodule
|
||||||
|
@ -2,87 +2,66 @@ local mymodule = {}
|
|||||||
|
|
||||||
posix = require("posix")
|
posix = require("posix")
|
||||||
fs = require("acf.fs")
|
fs = require("acf.fs")
|
||||||
|
json = require('cjson')
|
||||||
|
modelfunctions = require("modelfunctions")
|
||||||
|
|
||||||
local configpath = "/etc/openpdu/"
|
local outletsConfigfile = "/etc/openpdu/outlets.conf"
|
||||||
|
local boardsConfigfile = "/etc/openpdu/boards.conf"
|
||||||
|
local s = modelfunctions.run_executable({"/usr/bin/openpdu", "outlets", "-j"})
|
||||||
|
local o = json.decode(s)
|
||||||
|
local outlets = {}
|
||||||
|
|
||||||
local config = {}
|
for Index, Value in pairs( o.outlets ) do
|
||||||
for i=1,8 do
|
if (Value.powerstatus) then
|
||||||
config[i]={socket=i,status="unknown",description="Socket " .. tostring(i),actions={"on","off"}}
|
s = "On"
|
||||||
|
else
|
||||||
|
s = "Off"
|
||||||
end
|
end
|
||||||
config[1].gpio=1
|
outlets[Value.outlet+1] = {outlet=Value.outlet,status=s,description=Value.description,actions={"on","off"}}
|
||||||
config[2].gpio=2
|
end
|
||||||
config[3].gpio=3
|
|
||||||
config[4].gpio=7
|
|
||||||
config[5].gpio=8
|
|
||||||
config[6].gpio=9
|
|
||||||
config[7].gpio=11
|
|
||||||
config[8].gpio=12
|
|
||||||
|
|
||||||
mymodule.status = function()
|
mymodule.status = function()
|
||||||
mymodule.updatestatus()
|
return cfe({ type="structure", value=outlets, label="Outlets" })
|
||||||
return cfe({ type="structure", value=config, label="Outlets" })
|
|
||||||
end
|
end
|
||||||
|
|
||||||
mymodule.updatestatus = function()
|
mymodule.setpower = function(outlet, power, ret)
|
||||||
for i=1,8 do
|
return modelfunctions.run_executable({"/usr/bin/openpdu", "setpower", outlet, power})
|
||||||
f = "/sys/class/gpio/gpio" .. tostring(config[i].gpio) .. "/value"
|
|
||||||
v = fs.read_file(f)
|
|
||||||
if (tonumber(v) == 0) then
|
|
||||||
s = "On"
|
|
||||||
elseif (tonumber(v) == 1) then
|
|
||||||
s = "Off"
|
|
||||||
else
|
|
||||||
s = "unknown (" .. v .. ")"
|
|
||||||
end
|
|
||||||
config[i].status = s
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
mymodule.setpower = function(socket, power, ret)
|
|
||||||
-- Check to make sure the socket is valid
|
|
||||||
if (socket == nil) then
|
|
||||||
ret.errtxt = "Socket cannot be nil"
|
|
||||||
elseif (not type(socket) == "number") then
|
|
||||||
ret.errtxt = "Socket must be a number"
|
|
||||||
elseif (tonumber(socket) < 0) then
|
|
||||||
ret.errtxt = "Socket must be >0"
|
|
||||||
elseif (tonumber(socket) > 8) then
|
|
||||||
ret.errtxt = "Socket must be <=8"
|
|
||||||
end
|
|
||||||
|
|
||||||
-- If it is, poweron the socket
|
|
||||||
if (ret.errtxt == nil ) then
|
|
||||||
f = "/sys/class/gpio/gpio" .. tostring(config[tonumber(socket)].gpio) .. "/value"
|
|
||||||
if (power == 1) then
|
|
||||||
ret.descr = "Socket " .. tostring(socket) .. " Powered ON"
|
|
||||||
p = "0"
|
|
||||||
else
|
|
||||||
ret.descr = "Socket " .. tostring(socket) .. " Powered OFF"
|
|
||||||
p = "1"
|
|
||||||
end
|
|
||||||
v = fs.write_file(f, p)
|
|
||||||
return ret
|
|
||||||
end
|
|
||||||
|
|
||||||
return ret
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mymodule.get_setpower = function(self, clientdata)
|
mymodule.get_setpower = function(self, clientdata)
|
||||||
local socket = cfe({label="Socket", value=clientdata.socket or ""})
|
local outlet = cfe({label="Outlet", value=clientdata.outlet or ""})
|
||||||
return cfe({ type="group", label="Set Socket Power state", value={socket=socket} })
|
return cfe({ type="group", label="Set Outlet Power state", value={outlet=outlet} })
|
||||||
end
|
end
|
||||||
|
|
||||||
mymodule.setpoweron = function(self, r)
|
mymodule.setpoweron = function(self, r)
|
||||||
mymodule.setpower(r.value.socket.value, 1, r)
|
mymodule.setpower(r.value.outlet.value, 1, r)
|
||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
|
|
||||||
mymodule.setpoweroff = function(self, r)
|
mymodule.setpoweroff = function(self, r)
|
||||||
mymodule.setpower(r.value.socket.value, 0, r)
|
mymodule.setpower(r.value.outlet.value, 0, r)
|
||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function mymodule.get_outletsFiledetails()
|
||||||
|
return modelfunctions.getfiledetails(outletsConfigfile)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mymodule.update_outletsFiledetails(self, filedetails)
|
||||||
|
return modelfunctions.setfiledetails(self, filedetails, {outletsConfigfile})
|
||||||
|
end
|
||||||
|
|
||||||
|
function mymodule.get_boardsFiledetails()
|
||||||
|
return modelfunctions.getfiledetails(boardsConfigfile)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mymodule.update_boardsFiledetails(self, filedetails)
|
||||||
|
return modelfunctions.setfiledetails(self, filedetails, {boardsConfigfile})
|
||||||
|
end
|
||||||
|
|
||||||
return mymodule
|
return mymodule
|
||||||
|
1
acf-app/openpdu-outletsconf-html.lsp
Symbolic link
1
acf-app/openpdu-outletsconf-html.lsp
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../expert-html.lsp
|
@ -25,7 +25,7 @@
|
|||||||
<% local header_level = htmlviewfunctions.displaysectionstart(view, page_info) %>
|
<% local header_level = htmlviewfunctions.displaysectionstart(view, page_info) %>
|
||||||
<table id="list" class="tablesorter"><thead>
|
<table id="list" class="tablesorter"><thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Socket #</th>
|
<th>Outlet #</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
<% if viewlibrary.check_permission("edit") or viewlibrary.check_permission("power") then %>
|
<% if viewlibrary.check_permission("edit") or viewlibrary.check_permission("power") then %>
|
||||||
@ -37,18 +37,18 @@
|
|||||||
local redir = cfe({type="hidden", value=page_info.orig_action})
|
local redir = cfe({type="hidden", value=page_info.orig_action})
|
||||||
for i,item in ipairs(view.value) do %>
|
for i,item in ipairs(view.value) do %>
|
||||||
<tr>
|
<tr>
|
||||||
<td><%= html.html_escape(item.socket) %></td>
|
<td><%= html.html_escape(item.outlet) %></td>
|
||||||
<td><%= html.html_escape(item.status) %></td>
|
<td><%= html.html_escape(item.status) %></td>
|
||||||
<td><%= html.html_escape(item.description) %></td>
|
<td><%= html.html_escape(item.description) %></td>
|
||||||
<% if viewlibrary.check_permission("edit") or viewlibrary.check_permission("power") then %>
|
<% if viewlibrary.check_permission("edit") or viewlibrary.check_permission("power") then %>
|
||||||
<td>
|
<td>
|
||||||
<% local socket = cfe({type="hidden", value=item.socket}) %>
|
<% local outlet = cfe({type="hidden", value=item.outlet}) %>
|
||||||
<% if viewlibrary.check_permission("edit") then
|
<% if viewlibrary.check_permission("edit") then
|
||||||
htmlviewfunctions.displayitem(cfe({type="link", value={socket=socket, redir=redir}, label="", option="Edit", action="edit" }), page_info, -1)
|
htmlviewfunctions.displayitem(cfe({type="link", value={outlet=outlet, redir=redir}, label="", option="Edit", action="edit" }), page_info, -1)
|
||||||
end %>
|
end %>
|
||||||
<% if viewlibrary.check_permission("poweron") or viewlibrary.check_permission("poweroff") then
|
<% if viewlibrary.check_permission("poweron") or viewlibrary.check_permission("poweroff") then
|
||||||
htmlviewfunctions.displayitem(cfe({type="form", value={socket=socket, redir=redir}, label="", option="Power ON", action="poweron" }), page_info, -1)
|
htmlviewfunctions.displayitem(cfe({type="form", value={outlet=outlet, redir=redir}, label="", option="Power ON", action="poweron" }), page_info, -1)
|
||||||
htmlviewfunctions.displayitem(cfe({type="form", value={socket=socket, redir=redir}, label="", option="Power OFF", action="poweroff" }), page_info, -1)
|
htmlviewfunctions.displayitem(cfe({type="form", value={outlet=outlet, redir=redir}, label="", option="Power OFF", action="poweroff" }), page_info, -1)
|
||||||
end %>
|
end %>
|
||||||
</td>
|
</td>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
#CAT GROUP/DESC TAB ACTION
|
#CAT GROUP/DESC TAB ACTION
|
||||||
Applications 20OpenPDU Status status
|
Applications 20OpenPDU Status status
|
||||||
|
Applications 20OpenPDU Outlets outletsconf
|
||||||
|
Applications 20OpenPDU Boards boardsconf
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
USER=openpdu:status
|
USER=openpdu:status
|
||||||
EDITOR=openpdu:status
|
EDITOR=openpdu:status
|
||||||
EXPERT=openpdu:status
|
EXPERT=openpdu:status,openpdu:outletsconf,openpdu:boardsconf
|
||||||
ADMIN=openpdu:status,openpdu:edit,openpdu:power,openpdu:poweron,openpdu:poweroff
|
ADMIN=openpdu:status,openpdu:edit,openpdu:outletsconf,openpdu:boardsconf,openpdu:power,openpdu:poweron,openpdu:poweroff
|
||||||
|
17
docker/Dockerfile
Normal file
17
docker/Dockerfile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
FROM alpine:3.7
|
||||||
|
|
||||||
|
ADD https://repo.openpdu.org/alpine/devel@openpdu.org-5a7816cb.rsa.pub /etc/apk/keys
|
||||||
|
|
||||||
|
RUN echo "https://repo.openpdu.org/alpine/v3.7/main" >> /etc/apk/repositories && \
|
||||||
|
apk --no-cache -U upgrade && \
|
||||||
|
apk --no-cache -U add acf-openpdu alpine-base && \
|
||||||
|
echo root:root | chpasswd && \
|
||||||
|
setup-acf
|
||||||
|
|
||||||
|
#ADD start.sh /
|
||||||
|
|
||||||
|
EXPOSE 443
|
||||||
|
|
||||||
|
#ENTRYPOINT ["/bin/sh"]
|
||||||
|
ENTRYPOINT ["/usr/sbin/mini_httpd","-D","-C","/etc/mini_httpd/mini_httpd.conf"]
|
||||||
|
|
1
docker/build.sh
Executable file
1
docker/build.sh
Executable file
@ -0,0 +1 @@
|
|||||||
|
docker build . -t acf-openpdu:latest
|
3
docker/start.sh
Executable file
3
docker/start.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
MYDIR=$(cd "$(dirname "$0")/../acf-app" ; pwd -P)
|
||||||
|
docker run --rm -d -v "$MYDIR:/usr/share/acf/app/openpdu/" -p 443 acf-openpdu:latest
|
||||||
|
|
@ -1,21 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
OUT1=1
|
|
||||||
OUT2=2
|
|
||||||
OUT3=3
|
|
||||||
OUT4=7
|
|
||||||
OUT5=8
|
|
||||||
OUT6=9
|
|
||||||
OUT7=11
|
|
||||||
OUT8=12
|
|
||||||
|
|
||||||
for n in $(seq 1 8) ; do
|
|
||||||
eval "echo \$OUT$n > /sys/class/gpio/export"
|
|
||||||
eval "echo out > /sys/class/gpio/gpio\$OUT$n/direction"
|
|
||||||
|
|
||||||
# 0=on 1=off :)
|
|
||||||
VAL=0
|
|
||||||
|
|
||||||
eval "echo $VAL > /sys/class/gpio/gpio\$OUT$n/value"
|
|
||||||
sleep 0.2
|
|
||||||
done
|
|
Loading…
Reference in New Issue
Block a user