Skip to content

Commit

Permalink
[fix] Store full backup of default UCI files
Browse files Browse the repository at this point in the history
Without this patch, OpenWISP will not store
complete UCI files when overwriting them.

This causes the removal of important UCI options
when templates are removed.
  • Loading branch information
nemesifier committed May 24, 2023
1 parent dcda6e9 commit 074d6a0
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 33 deletions.
36 changes: 6 additions & 30 deletions openwisp-config/files/sbin/openwisp-update-config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ local get_standard = function() return uci.cursor(standard_config_dir) end
local get_remote = function()
return uci.cursor(remote_config_dir, '/tmp/openwisp/.uci')
end
local get_check =
function() return uci.cursor(check_config_dir, '/tmp/openwisp/.uci') end
local get_check = function()
return uci.cursor(check_config_dir, '/tmp/openwisp/.uci')
end
local get_stored = function()
return uci.cursor(stored_config_dir, '/tmp/openwisp/.uci')
end
Expand Down Expand Up @@ -153,34 +154,9 @@ if lfs.attributes(remote_config_dir, 'mode') == 'directory' then
if lfs.attributes(remote_path, 'mode') == 'file' then
-- if there's no backup of the file yet, create one
if not utils.file_exists(stored_path) then
os.execute('cp ' .. standard_path .. ' ' .. stored_path)
local uci_sections = stored:get_all(file) or {}
for key, section in pairs(uci_sections) do
-- check if section is in remote configuration
local section_check = check:get(file, section['.name'])
if section_check then
-- check if options is in remote configuration
for option, value in pairs(section) do
if not utils.starts_with_dot(option) then
local option_check = check:get(file, section['.name'], option)
if option_check then
-- if option is in remote configuration, remove it
stored:delete(file, section['.name'], option)
end
end
end
-- remove entire section if empty
local result = stored:get_all(file, section['.name'])
if result and utils.is_uci_empty(result) then
stored:delete(file, section['.name'])
end
end
end
stored:commit(file)
-- remove uci file if empty
local uci_file = stored:get_all(file)
if uci_file and utils.is_table_empty(uci_file) then
os.remove(stored_path)
local uci_file = check:get_all(file)
if uci_file and not utils.is_table_empty(uci_file) then
os.execute('cp ' .. standard_path .. ' ' .. stored_path)
end
end
-- MERGE mode
Expand Down
Binary file modified openwisp-config/tests/good-config.tar.gz
Binary file not shown.
12 changes: 9 additions & 3 deletions openwisp-config/tests/test_update_config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ TestUpdateConfig = {
os.execute('cp ./update/system '..config_dir..'system')
os.execute('cp ./update/network '..config_dir..'network')
os.execute('cp ./update/wireless '..config_dir..'wireless')
os.execute('cp ./update/firewall '..config_dir..'firewall')
-- we expect these UCI files to be removed
os.execute('cp ./config/wireless-autoname '..remote_config_dir..'/wireless-autoname')
os.execute('cp ./wifi/wireless '..remote_config_dir..'/wireless')
Expand Down Expand Up @@ -65,11 +66,16 @@ function TestUpdateConfig.test_update()
local storedNetworkFile = io.open(stored_dir .. '/etc/config/network')
luaunit.assertNotNil(storedNetworkFile)
local storedNetworkContents = storedNetworkFile:read('*all')
-- ensure wg1 is not added that is downloaded from remote
luaunit.assertNil(string.find(storedNetworkContents, "config interface 'wg1'"))
-- ensure wan and wg0 are present
-- ensure stored
luaunit.assertNotNil(string.find(storedNetworkContents, "config interface 'wg1'"))
luaunit.assertNotNil(string.find(storedNetworkContents, "config interface 'wan'"))
luaunit.assertNotNil(string.find(storedNetworkContents, "config interface 'wg0'"))
-- ensure only options with differing values are stored
local storedFirewallFile = io.open(stored_dir .. '/etc/config/firewall')
luaunit.assertNotNil(storedFirewallFile)
local storedFirewallContents = storedFirewallFile:read('*all')
luaunit.assertNotNil(string.find(storedFirewallContents, "option forward 'REJECT'"))
luaunit.assertNotNil(string.find(storedFirewallContents, "option output 'ACCEPT'"))
-- check system
local systemFile = io.open(config_dir .. 'system')
luaunit.assertNotNil(systemFile)
Expand Down
5 changes: 5 additions & 0 deletions openwisp-config/tests/update/firewall
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
config defaults 'defaults'
option syn_flood '1'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'REJECT'

0 comments on commit 074d6a0

Please sign in to comment.