diff --git a/.gitignore b/.gitignore index 8a2455a..6860d29 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ packages/ *.apk +.on-save.json diff --git a/APKBUILD b/APKBUILD index 45d9cf4..751a39e 100755 --- a/APKBUILD +++ b/APKBUILD @@ -1,27 +1,26 @@ # Contributor: Paolo Asperti # Maintainer: Paolo Asperti pkgname=acf-openpdu -pkgver=0.1 +pkgver=0.3 pkgrel=1 -pkgdesc="Linux installation caching system" -url="https://github.com/paspo/installinux" +pkgdesc="ACF interface for the OpenPDU project" +url="https://github.com/openpdu/acf-openpdu" arch="noarch" license="GPL2" -depends="acf-core" +depends="acf-core openpdu lua-cjson" makedepends="" install="acf-openpdu.post-install" subpackages="" source="" +options="!check" -package() { - mkdir -p "$pkgdir" +build() { + : } package() { + mkdir -p "$pkgdir" # 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.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 diff --git a/README b/README index 5b5300c..944242b 100755 --- a/README +++ b/README @@ -7,12 +7,12 @@ Under "OpenPDU" you can control your outlets. DONE: * Basic Outlet Status (almost everything hardcoded :( ) * 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 + * configuration file editing TODO: - * configuration file - * editing socket parameters + * editing outlet parameters * everything else (there's a long list) BUGS: diff --git a/acf-app/openpdu-boardsconf-html.lsp b/acf-app/openpdu-boardsconf-html.lsp new file mode 120000 index 0000000..207f324 --- /dev/null +++ b/acf-app/openpdu-boardsconf-html.lsp @@ -0,0 +1 @@ +../expert-html.lsp \ No newline at end of file diff --git a/acf-app/openpdu-controller.lua b/acf-app/openpdu-controller.lua index 1cce39b..489e859 100755 --- a/acf-app/openpdu-controller.lua +++ b/acf-app/openpdu-controller.lua @@ -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") 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 diff --git a/acf-app/openpdu-model.lua b/acf-app/openpdu-model.lua index 5e9d03d..704f845 100755 --- a/acf-app/openpdu-model.lua +++ b/acf-app/openpdu-model.lua @@ -2,87 +2,66 @@ local mymodule = {} posix = require("posix") 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 i=1,8 do - config[i]={socket=i,status="unknown",description="Socket " .. tostring(i),actions={"on","off"}} +for Index, Value in pairs( o.outlets ) do + if (Value.powerstatus) then + s = "On" + else + s = "Off" + end + outlets[Value.outlet+1] = {outlet=Value.outlet,status=s,description=Value.description,actions={"on","off"}} end -config[1].gpio=1 -config[2].gpio=2 -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.updatestatus() - return cfe({ type="structure", value=config, label="Outlets" }) + return cfe({ type="structure", value=outlets, label="Outlets" }) end -mymodule.updatestatus = function() - for i=1,8 do - 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 +mymodule.setpower = function(outlet, power, ret) + return modelfunctions.run_executable({"/usr/bin/openpdu", "setpower", outlet, power}) end mymodule.get_setpower = function(self, clientdata) - local socket = cfe({label="Socket", value=clientdata.socket or ""}) - return cfe({ type="group", label="Set Socket Power state", value={socket=socket} }) + local outlet = cfe({label="Outlet", value=clientdata.outlet or ""}) + return cfe({ type="group", label="Set Outlet Power state", value={outlet=outlet} }) end mymodule.setpoweron = function(self, r) - mymodule.setpower(r.value.socket.value, 1, r) + mymodule.setpower(r.value.outlet.value, 1, r) return r end mymodule.setpoweroff = function(self, r) - mymodule.setpower(r.value.socket.value, 0, r) + mymodule.setpower(r.value.outlet.value, 0, r) return r 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 diff --git a/acf-app/openpdu-outletsconf-html.lsp b/acf-app/openpdu-outletsconf-html.lsp new file mode 120000 index 0000000..207f324 --- /dev/null +++ b/acf-app/openpdu-outletsconf-html.lsp @@ -0,0 +1 @@ +../expert-html.lsp \ No newline at end of file diff --git a/acf-app/openpdu-status-html.lsp b/acf-app/openpdu-status-html.lsp index 22914cd..7091010 100755 --- a/acf-app/openpdu-status-html.lsp +++ b/acf-app/openpdu-status-html.lsp @@ -25,7 +25,7 @@ <% local header_level = htmlviewfunctions.displaysectionstart(view, page_info) %> - + <% 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}) for i,item in ipairs(view.value) do %> - + <% if viewlibrary.check_permission("edit") or viewlibrary.check_permission("power") then %> <% end %> diff --git a/acf-app/openpdu.menu b/acf-app/openpdu.menu index 2594bb5..a5da7b2 100755 --- a/acf-app/openpdu.menu +++ b/acf-app/openpdu.menu @@ -1,2 +1,4 @@ #CAT GROUP/DESC TAB ACTION Applications 20OpenPDU Status status +Applications 20OpenPDU Outlets outletsconf +Applications 20OpenPDU Boards boardsconf diff --git a/acf-app/openpdu.roles b/acf-app/openpdu.roles index 5d6072f..c3e5bae 100755 --- a/acf-app/openpdu.roles +++ b/acf-app/openpdu.roles @@ -1,4 +1,4 @@ USER=openpdu:status EDITOR=openpdu:status -EXPERT=openpdu:status -ADMIN=openpdu:status,openpdu:edit,openpdu:power,openpdu:poweron,openpdu:poweroff +EXPERT=openpdu:status,openpdu:outletsconf,openpdu:boardsconf +ADMIN=openpdu:status,openpdu:edit,openpdu:outletsconf,openpdu:boardsconf,openpdu:power,openpdu:poweron,openpdu:poweroff diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..d78e4a0 --- /dev/null +++ b/docker/Dockerfile @@ -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"] + diff --git a/docker/build.sh b/docker/build.sh new file mode 100755 index 0000000..db0b835 --- /dev/null +++ b/docker/build.sh @@ -0,0 +1 @@ +docker build . -t acf-openpdu:latest diff --git a/docker/start.sh b/docker/start.sh new file mode 100755 index 0000000..a00b80c --- /dev/null +++ b/docker/start.sh @@ -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 + diff --git a/etc/local.d/openpdu.start b/etc/local.d/openpdu.start deleted file mode 100755 index de15e1f..0000000 --- a/etc/local.d/openpdu.start +++ /dev/null @@ -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 diff --git a/etc/openpdu/openpdu.conf b/etc/openpdu/openpdu.conf deleted file mode 100755 index e69de29..0000000
Socket #Outlet # Status Description
<%= html.html_escape(item.socket) %><%= html.html_escape(item.outlet) %> <%= html.html_escape(item.status) %> <%= html.html_escape(item.description) %> - <% local socket = cfe({type="hidden", value=item.socket}) %> + <% local outlet = cfe({type="hidden", value=item.outlet}) %> <% 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 %> <% 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={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 ON", action="poweron" }), page_info, -1) + htmlviewfunctions.displayitem(cfe({type="form", value={outlet=outlet, redir=redir}, label="", option="Power OFF", action="poweroff" }), page_info, -1) end %>