initial configmode

This commit is contained in:
Nils Schneider 2012-05-22 19:28:02 +02:00 committed by Matthias Schiffer
commit b8ebdc3498
16 changed files with 411 additions and 0 deletions

39
luci/config-mode/Makefile Normal file
View File

@ -0,0 +1,39 @@
# Copyright (C) 2012 Nils Schneider <nils at nilsschneider.net>
# This is free software, licensed under the Apache 2.0 license.
include $(TOPDIR)/rules.mk
PKG_NAME:=configmode
PKG_RELEASE:=0.0.1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
define Package/configmode
SECTION:=luci
CATEGORY:=LuCI
SUBMENU:=9. Freifunk
TITLE:=Luci based configmode for userfriendly setup of new meshnodes
DEPENDS:=+firewall
endef
define Package/configmode/description
Luci based configmode
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/configmode/install
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,configmode))

View File

@ -0,0 +1,4 @@
config wizard
option enabled '1'

View File

@ -0,0 +1,12 @@
module("luci.controller.ffhl.index", package.seeall)
function index()
entry({}, call("maybe_wizard"), "luebeck.freifunk.net", 20).dependent=false
end
function maybe_wizard()
-- This function should figure out whether the wizard already ran succesfully
-- and redirect to the wizard or the status page.
luci.http.redirect(luci.dispatcher.build_url("wizard", "welcome"))
end

View File

@ -0,0 +1,29 @@
module("luci.controller.ffhl.wizard", package.seeall)
function index()
local uci = luci.model.uci.cursor()
if uci:get_first("ffhl", "wizard", "enabled") == "1" then
entry({"wizard", "welcome"}, template("ffhl-wizard/welcome"), "Willkommen", 10).dependent=false
entry({"wizard", "password"}, form("ffhl-wizard/password"), "Passwort", 20).dependent=false
entry({"wizard", "hostname"}, form("ffhl-wizard/hostname"), "Hostname", 30).dependent=false
entry({"wizard", "meshvpn"}, form("ffhl-wizard/meshvpn"), "Mesh-VPN", 40).dependent=false
entry({"wizard", "meshvpn", "pubkey"}, template("ffhl-wizard/meshvpn-key"), "Mesh-VPN Key", 1).dependent=false
entry({"wizard", "completed"}, template("ffhl-wizard/completed"), "Fertig", 50).dependent=false
entry({"wizard", "completed", "reboot"}, call("reboot"), "reboot", 1).dependent=false
end
end
function reboot()
local uci = luci.model.uci.cursor()
uci:foreach("ffhl", "wizard", function(s)
uci:set("ffhl", s[".name"], "enabled", "0")
end
)
uci:save("ffhl")
uci:commit("ffhl")
-- luci.sys.reboot()
end

View File

@ -0,0 +1,38 @@
local uci = luci.model.uci.cursor()
local nav = require "luci.tools.ffhl-wizard.nav"
local f = SimpleForm("hostname", "Name deines Freifunkknotens", "Als nächstes solltest du einem Freifunkknoten einen individuellen Namen geben. Dieser hilft dir und auch uns den Überblick zu behalten.")
f.template = "ffhl-wizard/wizardform"
hostname = f:field(Value, "hostname", "Hostname")
hostname.value = uci:get_first("system", "system", "hostname")
hostname.rmempty = false
function hostname.validate(self, value, section)
return value
end
function f.handle(self, state, data)
if state == FORM_VALID then
local stat = true
uci:foreach("system", "system", function(s)
stat = stat and uci:set("system", s[".name"], "hostname", data.hostname)
end
)
stat = stat and uci:save("system")
stat = stat and uci:commit("system")
if stat then
nav.maybe_redirect_to_successor()
f.message = "Hostname geändert!"
else
f.errmessage = "Fehler!"
end
end
return true
end
return f

View File

@ -0,0 +1,39 @@
local uci = luci.model.uci.cursor()
local nav = require "luci.tools.ffhl-wizard.nav"
local f = SimpleForm("meshvpn", "Mesh-VPN", "Um deinen Freifunkknoten auch über das Internet mit anderen Knoten zu verbinden, muss das Mesh-VPN aktiviert werden.</p><p>Dadurch ist es möglich das Freifunknetz auch ohne WLAN Verbindung zu anderen Knoten zu nutzen.")
f.template = "ffhl-wizard/wizardform"
meshvpn = f:field(Flag, "meshvpn", "Mesh-VPN aktivieren?")
meshvpn.default = string.format("%d", uci:get("fastd", "ffhl_mesh_vpn", "enabled"))
meshvpn.rmempty = false
function f.handle(self, state, data)
if state == FORM_VALID then
local stat = false
uci:set("fastd", "ffhl_mesh_vpn", "enabled", data.meshvpn)
uci:save("fastd")
uci:commit("fastd")
if data.meshvpn == "1" then
luci.sys.call("/etc/init.d/haveged start")
local f = io.popen("fastd --generate-key --machine-readable", "r")
local secret = f:read("*a")
f:close()
luci.sys.call("/etc/init.d/haveged stop")
uci:set("fastd", "ffhl_mesh_vpn", "secret", secret)
uci:save("fastd")
uci:commit("fastd")
luci.http.redirect(luci.dispatcher.build_url("wizard", "meshvpn", "pubkey"))
else
nav.maybe_redirect_to_successor()
end
end
return true
end
return f

View File

@ -0,0 +1,36 @@
local nav = require "luci.tools.ffhl-wizard.nav"
f = SimpleForm("password", "Administrator Passwort setzen", "Damit nur du Zugriff auf deinen Freifunkknoten hast, solltest du jetzt ein Passwort vergeben.</p><p>Bitte wähle ein sicheres Passwort. Sonst könnten Leute wilden Scheiß machen, den du nicht willst!")
f.template = "ffhl-wizard/wizardform"
pw1 = f:field(Value, "pw1", "Passwort")
pw1.password = true
pw1.rmempty = false
pw2 = f:field(Value, "pw2", "Wiederholung")
pw2.password = true
pw2.rmempty = false
function pw2.validate(self, value, section)
return pw1:formvalue(section) == value and value
end
function f.handle(self, state, data)
if state == FORM_VALID then
local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
if stat then
nav.maybe_redirect_to_successor()
f.message = "Passwort geändert!"
else
f.errmessage = "Fehler!"
end
data.pw1 = nil
data.pw2 = nil
end
return true
end
return f

View File

@ -0,0 +1,43 @@
module("luci.tools.ffhl-wizard.nav", package.seeall)
function maybe_redirect_to_successor()
local pre, suc = get()
if suc then
luci.http.redirect(luci.dispatcher.build_url("wizard", suc.href))
end
end
function get()
local disp = require "luci.dispatcher"
local request = disp.context.path
local category = request[1]
local cattree = category and disp.node(category)
local childs = disp.node_childs(cattree)
local predecessor = nil
local successor = nil
if #childs > 0 then
local found_pre = false
for i, r in ipairs(childs) do
local nnode = cattree.nodes[r]
nnode.href = r
if r == request[2] then
found_pre = true
elseif found_pre and successor == nil then
successor = nnode
end
if not found_pre then
predecessor = nnode
end
end
end
return predecessor, successor
end

View File

@ -0,0 +1,14 @@
<%
local disp = require "luci.dispatcher"
%>
<%+header%>
<h2>Konfiguration abgeschlossen</h2>
<p>Die Konfiguration deines Freifunkknotens ist nun abgeschlossen.<p>
<p>Damit sie aktiv wird, muss der Knoten neugestartet werden.</p>
<p>
<a href="<%=disp.build_url("wizard", "completed", "reboot")%>">Jetzt neustarten!</a>
</p>
<%+footer%>

View File

@ -0,0 +1,19 @@
<% local xtime
if exectime then
xtime = (string.format("%.2fs", os.clock() - exectime))
end %>
<footer class="footer">
<p><a href="http://luci.subsignal.org">Powered by <%= luci.__appname__ .. " (" .. luci.__version__ .. ")" %></a>
<% if xtime then %>
<br/>
Script execution time: <%=xtime%>
<% end %>
</p>
</footer>
</div>
</body>
</html>

View File

@ -0,0 +1,24 @@
<%
local fs = require "luci.fs"
local sys = require "luci.sys"
local http = require "luci.http"
local disp = require "luci.dispatcher"
local hostname = sys.hostname()
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" type="text/css" media="screen" href="/wizard/bootstrap.css" />
<title><%=striptags( hostname )%> - Wizard</title>
</head>
<body class="lang_<%=luci.i18n.context.lang%>">
<div class="container">
<div class="page-header">
<h1>Freifunk Wizard</h1>
</div>

View File

@ -0,0 +1,15 @@
<%
local disp = require "luci.dispatcher"
local f = io.popen("/etc/init.d/fastd show-key ffhl_mesh_vpn", "r")
local key = f:read("*a")
f:close()
%>
<%+header%>
<h2>Schlüsselaustausch</h2>
<p>Dies ist der öffentliche Schlüssel deines Freifunkknotens. Bitte schicke ihn an freifunk.luebeck@asta.uni-luebeck.de um ihn auf den Freifunkservern eintragen zu lassen. Sobald der Schlüssel eingetragen wurde, kann dein Knoten das Mesh-VPN nutzen.</p>
<pre>
<%=key%>
</pre>
<%+ffhl-wizard/nav%>
<%+footer%>

View File

@ -0,0 +1,16 @@
<%
local nav = require "luci.tools.ffhl-wizard.nav"
local predecessor, successor = nav.get()
%>
<% if predecessor then %>
<a href="<%=luci.dispatcher.build_url("wizard", predecessor.href)%>">
Zurück
</a>
<% end %>
<% if not have_form and successor then %>
<a href="<%=luci.dispatcher.build_url("wizard", successor.href)%>">
Weiter
</a>
<% end %>

View File

@ -0,0 +1,14 @@
<%
local disp = require "luci.dispatcher"
%>
<%+ffhl-wizard/header%>
<section>
<h1>Passwort setzen</h1>
<p>Hier steht noch kein Text, der den Benutzer auffordert ein Passwort zu setzen.<p>
<div class="form-actions">
<a class="btn btn-primary" href="#">Weiter</a>
<a class="btn" href="<%=disp.build_url("wizard")%>">Zurück</a>
</div>
</section>
<%+ffhl-wizard/footer%>

View File

@ -0,0 +1,8 @@
<%
local disp = require "luci.dispatcher"
%>
<%+header%>
<h2>Willkommen auf deinem Freifunkknoten!</h2>
<p>Dieser Wizard hilft dir deinen Freifunkknoten einzurichten.</p>
<%+ffhl-wizard/nav%>
<%+footer%>

View File

@ -0,0 +1,61 @@
<% if not self.embedded then %>
<form method="post" enctype="multipart/form-data" action="<%=REQUEST_URI%>">
<div>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<input type="hidden" name="cbi.submit" value="1" />
</div>
<% end %>
<div class="cbi-map" id="cbi-<%=self.config%>">
<% if self.title and #self.title > 0 then %><h2><a id="content" name="content"><%=self.title%></a></h2><% end %>
<% if self.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %>
<% self:render_children() %>
<br />
</div>
<%- if self.message then %>
<div><%=self.message%></div>
<%- end %>
<%- if self.errmessage then %>
<div class="error"><%=self.errmessage%></div>
<%- end %>
<% if not self.embedded then %>
<div>
<%-
if type(self.hidden) == "table" then
for k, v in pairs(self.hidden) do
-%>
<input type="hidden" id="<%=k%>" name="<%=k%>" value="<%=pcdata(v)%>" />
<%-
end
end
%>
<% if redirect then %>
<div style="float:left">
<input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" />
</div>
<% end %>
<%- if self.flow and self.flow.skip then %>
<input class="cbi-button cbi-button-skip" type="submit" name="cbi.skip" value="<%:Skip%>" />
<% end %>
<%- if self.submit ~= false then %>
<input class="cbi-button cbi-button-save" type="submit" value="
<%- if not self.submit then -%>Weiter<%-else-%><%=self.submit%><%end-%>
" />
<% end %>
<%- if self.reset ~= false then %>
<input class="cbi-button cbi-button-reset" type="reset" value="
<%- if not self.reset then -%><%-:Reset-%><%-else-%><%=self.reset%><%end-%>
" />
<% end %>
<%- if self.cancel ~= false and self.on_cancel then %>
<input class="cbi-button cbi-button-reset" type="submit" name="cbi.cancel" value="
<%- if not self.cancel then -%><%-:Cancel-%><%-else-%><%=self.cancel%><%end-%>
" />
<% end %>
<script type="text/javascript">cbi_d_update();</script>
</div>
</form>
<% end %>
<% have_form = true %>
<%+ffhl-wizard/nav%>