Switch to rpcd based uci apply/rollback workflow which helps to avoid soft- bricking devices by requiring an explicit confirmation call after config apply. When a user now clicks "Save & Apply", LuCI first issues a call to uci apply which commits and reloads configuration, then goes into a polling countdown mode where it repeatedly attempts to call uci confirm. If the committed configuration is sane, the confirm call will go through and cancel rpcd's pending rollback timer. If the configuration change leads to a loss of connectivity (e.g. due to bad firewall rules or similar), the rollback mechanism will kick in after the timeout and revert configuration files and pending changes to the pre-apply state. In order to cover such rare cases where a lost of connectivity is expected and desired, the user is offered an "unchecked" apply option after timing out, which allows committing and applying the changes anyway, without the extra safety checks. As a consequence of this change, the luci-reload mechanism is now completely unsused since rpcd uses ubus config reload signals to reload affected services, which means that only procd-enabled services will receive proper reload treatment with the new workflow. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
58 lines
2.7 KiB
HTML
58 lines
2.7 KiB
HTML
<%- if firstmap and messages then local msg; for _, msg in ipairs(messages) do -%>
|
|
<div class="errorbox"><%=pcdata(msg)%></div>
|
|
<%- end end -%>
|
|
|
|
<div class="cbi-map" id="cbi-<%=self.config%>">
|
|
<% if self.title and #self.title > 0 then %><h2 name="content"><%=self.title%></h2><% end %>
|
|
<% if self.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %>
|
|
<%- if firstmap and (applymap or confirmmap) then -%>
|
|
<%+cbi/apply_widget%>
|
|
<% cbi_apply_widget(redirect) %>
|
|
<div class="alert-message" id="cbi_apply_status" style="display:none"></div>
|
|
<script type="text/javascript">
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
<% if confirmmap then -%>
|
|
uci_confirm(true, Date.now() + <%=confirmmap%> * 1000);
|
|
<%- else -%>
|
|
uci_apply(true);
|
|
<%- end %>
|
|
});
|
|
</script>
|
|
<%- end -%>
|
|
|
|
<% if self.tabbed then %>
|
|
<ul class="cbi-tabmenu map">
|
|
<%- self.selected_tab = luci.http.formvalue("tab.m-" .. self.config) %>
|
|
<% for i, section in ipairs(self.children) do %>
|
|
<%- if not self.selected_tab then self.selected_tab = section.sectiontype end %>
|
|
<li id="tab.m-<%=self.config%>.<%=section.section or section.sectiontype%>" class="cbi-tab<%=(section.sectiontype == self.selected_tab) and '' or '-disabled'%>">
|
|
<a onclick="this.blur(); return cbi_t_switch('m-<%=self.config%>', '<%=section.section or section.sectiontype%>')" href="<%=REQUEST_URI%>?tab.m-<%=self.config%>=<%=section.section or section.sectiontype%>"><%=section.title or section.section or section.sectiontype %></a>
|
|
<% if section.sectiontype == self.selected_tab then %><input type="hidden" id="tab.m-<%=self.config%>" name="tab.m-<%=self.config%>" value="<%=section.section or section.sectiontype%>" /><% end %>
|
|
</li>
|
|
<% end %>
|
|
</ul>
|
|
<br />
|
|
<% for i, section in ipairs(self.children) do %>
|
|
<div class="cbi-tabcontainer" id="container.m-<%=self.config%>.<%=section.section or section.sectiontype%>"<% if section.sectiontype ~= self.selected_tab then %> style="display:none"<% end %>>
|
|
<% section:render() %>
|
|
</div>
|
|
<script type="text/javascript">cbi_t_add('m-<%=self.config%>', '<%=section.section or section.sectiontype%>')</script>
|
|
<% end %>
|
|
|
|
<% if not self.save then -%>
|
|
<div class="cbi-section-error">
|
|
<% for _, section in ipairs(self.children) do %>
|
|
<% if section.error and section.error[section.section] then -%>
|
|
<ul><li>
|
|
<%:One or more invalid/required values on tab%>: <%=section.title or section.section or section.sectiontype%>
|
|
</li></ul>
|
|
<%- end %>
|
|
<% end %>
|
|
</div>
|
|
<%- end %>
|
|
<% else %>
|
|
<%- self:render_children() %>
|
|
<% end %>
|
|
|
|
<br />
|
|
</div>
|