autoupdater-wifi-fallback 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #!/usr/bin/lua
  2. local fs = require 'nixio.fs'
  3. local uci = require('simple-uci').cursor()
  4. local site = require 'gluon.site_config'
  5. local autil = require 'autoupdater-wifi-fallback.util'
  6. local util = require 'gluon.util'
  7. local configname = 'autoupdater-wifi-fallback'
  8. local force = false
  9. local min_uptime_secs = 3600
  10. local branch_name = uci:get('autoupdater', 'settings', 'branch')
  11. local function parse_args()
  12. local i = 1
  13. while arg[i] do
  14. if arg[i] == '-f' then
  15. force = true
  16. elseif arg[i] == '-b' then
  17. i=i+1
  18. if not arg[i] then
  19. io.stderr:write('Error parsing command line: expected branch name\n')
  20. os.exit(1)
  21. end
  22. branch_name = arg[i]
  23. else
  24. io.stderr:write("Error parsing command line: unexpected argument '" .. arg[i] .. "'\n")
  25. os.exit(1)
  26. end
  27. i = i+1
  28. end
  29. end
  30. local function preflight_check()
  31. if not uci:get_bool(configname, 'settings', 'enabled') then
  32. return false
  33. end
  34. if not uci:get_bool('autoupdater', 'settings', 'enabled') then
  35. return false
  36. end
  37. if tonumber(fs.readfile('/proc/uptime'):match('^([^ ]+) ')) < min_uptime_secs then
  38. return false
  39. end
  40. return true
  41. end
  42. local function connectivity_check()
  43. local f = io.open('/sys/kernel/debug/batman_adv/bat0/gateways', 'r')
  44. if f then
  45. for line in f:lines() do
  46. local gateway_mac = line:match('^=?>? +([0-9a-f:]+)')
  47. if gateway_mac then
  48. if os.execute('batctl ping -t5 -c1 ' .. gateway_mac .. ' > /dev/null 2>&1') == 0 then
  49. return true
  50. end
  51. end
  52. end
  53. f:close()
  54. end
  55. -- connectivity check against updateserver
  56. for _, host in ipairs(get_update_hosts(branch_name)) do
  57. if os.execute('ping -w2 -c1 ' .. host .. ' > /dev/null 2>&1') == 0 then
  58. return true
  59. end
  60. end
  61. io.popen('logger -s -t autoupdater-wifi-fallback -p local0.info "connectivity check failed"')
  62. return false
  63. end
  64. local function run_autoupdater()
  65. io.popen('logger -s -t autoupdater-wifi-fallback -p local0.info "execute the autoupdater"')
  66. os.execute('/usr/sbin/autoupdater -f -b ' .. branch_name)
  67. end
  68. local function switch_to_fallback_mode(radio, ssid, bssid)
  69. io.popen('logger -s -t autoupdater-wifi-fallback -p local0.info "connect to ' .. radio .. ' ' .. ssid .. ' ' .. bssid .. '"')
  70. uci:delete_all('wireless', 'wifi-iface')
  71. uci:section('wireless', 'wifi-iface', 'fallback', {
  72. device = radio,
  73. network = 'fallback',
  74. mode = 'sta',
  75. disabled = false,
  76. macaddr = util.generate_mac(3, 10),
  77. bssid = bssid,
  78. ssid = ssid,
  79. ifname = 'fallback',
  80. encryption = 'none',
  81. })
  82. uci:set('wireless', radio, 'disabled', false)
  83. uci:save('wireless')
  84. os.execute('wifi')
  85. os.execute('sleep 5')
  86. uci:revert('wireless')
  87. os.execute('sleep 20')
  88. end
  89. local function revert_to_standard_mode()
  90. io.popen('logger -s -t autoupdater-wifi-fallback -p local0.info "going back to standard mode"')
  91. os.execute('/etc/init.d/network restart')
  92. os.execute('sleep 30')
  93. end
  94. parse_args()
  95. if not uci:get('autoupdater', branch_name) then
  96. io.stderr:write("Can't find configuration for branch '" .. branch_name .. "'\n")
  97. os.exit(1)
  98. end
  99. if (force or preflight_check()) and not connectivity_check() then
  100. local offset = 2 * 3600
  101. local unreachable_since = os.time()
  102. if not uci:get('autoupdater-wifi-fallback', 'settings', 'unreachable_since') then
  103. uci:set(configname, 'settings', 'unreachable_since', unreachable_since)
  104. else
  105. uci:set(configname, 'settings', 'last_run', unreachable_since)
  106. unreachable_since = uci:get(configname, 'settings', 'unreachable_since')
  107. end
  108. uci:save(configname)
  109. if force or tonumber(unreachable_since) + offset < os.time() then
  110. io.popen('logger -s -t autoupdater-wifi-fallback -p local0.info "going to fallback mode"')
  111. for radio, netlist in pairs(get_available_wifi_networks()) do
  112. for _, net in ipairs(netlist) do
  113. switch_to_fallback_mode(radio, net.ssid, net.bssid)
  114. if run_autoupdater() == 0 then
  115. break
  116. end
  117. end
  118. end
  119. -- this is only reached if no updated happened
  120. revert_to_standard_mode()
  121. end
  122. else
  123. uci:delete(configname, 'settings', 'unreachable_since')
  124. uci:delete(configname, 'settings', 'last_run')
  125. uci:save(configname)
  126. end