autoupdater-wifi-fallback 4.2 KB

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