Implement factory_reset sys_call

pull/974/head
Connor Rigby 2019-04-18 13:41:14 -07:00
parent 1b31c32b3d
commit cb1c8b43ad
No known key found for this signature in database
GPG Key ID: 29A88B24B70456E0
3 changed files with 69 additions and 78 deletions

View File

@ -40,7 +40,7 @@ defmodule FarmbotOS.SysCalls do
end
def factory_reset do
FarmbotOS.System.factory_reset("Factory reset requested by sequence or frontent")
FarmbotOS.System.factory_reset("Factory reset requested by sequence or frontent", true)
:ok
end

View File

@ -6,26 +6,6 @@ defmodule FarmbotOS.SysCalls.ChangeOwnership do
alias FarmbotCore.{Asset, EctoMigrator}
alias FarmbotExt.Bootstrap.Authorization
def restart do
Logger.info("Stopping app: :farmbot")
_ = Application.stop(:farmbot)
Logger.info("Stopping app: :farmbot_ext")
_ = Application.stop(:farmbot_ext)
Logger.info("Stopping app: :farmbot_core")
_ = Application.stop(:farmbot_core)
Logger.info("Starting ap: :farmbot_core")
_ = Application.ensure_all_started(:farmbot_core)
Logger.info("Starting ap: :farmbot_ext")
_ = Application.ensure_all_started(:farmbot_ext)
Logger.info("Starting ap: :farmbot")
_ = Application.ensure_all_started(:farmbot)
end
def change_ownership(email, secret, server) do
server = server || get_config_value(:string, "authorization", "server")
@ -36,7 +16,7 @@ defmodule FarmbotOS.SysCalls.ChangeOwnership do
_ = clean_assets()
_ = clean_farmwares()
FarmbotCore.Logger.warn(1, "Going down for reboot")
Supervisor.start_child(:elixir_sup, {Task, &restart/0})
Supervisor.start_child(:elixir_sup, {Task, &FarmbotOS.System.soft_restart/0})
:ok
{:error, _} ->

View File

@ -3,7 +3,8 @@ defmodule FarmbotOS.System do
Common functionality that should be implemented by a system
"""
require FarmbotCore.Logger
alias FarmbotCore.{Asset, Project}
require Logger
alias FarmbotCore.Asset
error_msg = """
Please configure `:system_tasks`!
@ -20,6 +21,26 @@ defmodule FarmbotOS.System do
@doc "Shuts down the machine."
@callback shutdown() :: any
def soft_restart do
Logger.info("Stopping app: :farmbot")
_ = Application.stop(:farmbot)
Logger.info("Stopping app: :farmbot_ext")
_ = Application.stop(:farmbot_ext)
Logger.info("Stopping app: :farmbot_core")
_ = Application.stop(:farmbot_core)
Logger.info("Starting ap: :farmbot_core")
_ = Application.ensure_all_started(:farmbot_core)
Logger.info("Starting ap: :farmbot_ext")
_ = Application.ensure_all_started(:farmbot_ext)
Logger.info("Starting ap: :farmbot")
_ = Application.ensure_all_started(:farmbot)
end
@doc "Reads the last shutdown is there was one."
def last_shutdown_reason do
file = Path.join(@data_path, "last_shutdown_reason")
@ -30,6 +51,43 @@ defmodule FarmbotOS.System do
end
end
@doc "Remove all configuration data, and reboot."
@spec factory_reset(any) :: no_return
def factory_reset(reason, force \\ false) do
if force || should_factory_reset?() do
try_lock_fw()
write_file(reason)
_ = FarmbotCore.EctoMigrator.drop()
_ = Supervisor.start_child(:elixir_sup, {Task, &FarmbotOS.System.soft_restart/0})
:ok
else
FarmbotCore.Logger.error(1, "Factory Reset disabled.")
:ok
end
end
@doc "Reboot."
@spec reboot(any) :: no_return
def reboot(reason) do
try_lock_fw()
write_file(reason)
@system_tasks.reboot()
end
@doc "Shutdown."
@spec shutdown(any) :: no_return
def shutdown(reason) do
try_lock_fw()
write_file(reason)
@system_tasks.shutdown()
end
defp write_file(reason) do
file = Path.join(@data_path, "last_shutdown_reason")
if reason, do: File.write!(file, inspect(reason)), else: File.rm_rf(file)
end
# Check if the FarmbotFirmware process is alive
defp try_lock_fw do
if Process.whereis(FarmbotFirmware) do
FarmbotCore.Logger.warn(1, "Trying to emergency lock firmware before powerdown")
@ -39,61 +97,14 @@ defmodule FarmbotOS.System do
end
end
@doc "Remove all configuration data, and reboot."
@spec factory_reset(any) :: no_return
def factory_reset(reason) do
if Project.env() == :dev do
# credo:disable-for-next-line
require IEx
IEx.pry()
# This is wrapped in a try/catch because it's possible that
# the `Asset.Repo` server is not running. We want to ensure if it isn't
# Running, we are still able to reset.
defp should_factory_reset? do
try do
if Asset.fbos_config(:disable_factory_reset), do: false, else: true
catch
_, _ -> true
end
if Process.whereis(FarmbotCore) do
if Asset.fbos_config().disable_factory_reset do
reboot(reason)
else
do_reset(reason)
end
else
do_reset(reason)
end
end
defp do_reset(reason) do
Application.stop(:farmbot_ext)
Application.stop(:farmbot_core)
for p <- Path.wildcard(Path.join(@data_path, "*")) do
File.rm_rf!(p)
end
reboot(reason)
end
@doc "Reboot."
@spec reboot(any) :: no_return
def reboot(reason) do
write_file(reason)
try_lock_fw()
@system_tasks.reboot()
end
@doc "Shutdown."
@spec shutdown(any) :: no_return
def shutdown(reason) do
write_file(reason)
try_lock_fw()
@system_tasks.shutdown()
end
defp write_file(nil) do
file = Path.join(@data_path, "last_shutdown_reason")
File.rm_rf(file)
end
defp write_file(reason) do
IO.puts("Farmbot powering down: #{reason}")
file = Path.join(@data_path, "last_shutdown_reason")
File.write!(file, inspect(reason))
end
end