import enum
import attr
from ..factory import target_factory
from .common import Strategy, StrategyError
[docs]class Status(enum.Enum):
unknown = 0
off = 1
uboot = 2
shell = 3
[docs]@target_factory.reg_driver
@attr.s(eq=False)
class UBootStrategy(Strategy):
"""UbootStrategy - Strategy to switch to uboot or shell"""
bindings = {
"power": "PowerProtocol",
"console": "ConsoleProtocol",
"uboot": "UBootDriver",
"shell": "ShellDriver",
}
status = attr.ib(default=Status.unknown)
[docs] def __attrs_post_init__(self):
super().__attrs_post_init__()
[docs] def transition(self, status):
if not isinstance(status, Status):
status = Status[status]
if status == Status.unknown:
raise StrategyError(f"can not transition to {status}")
elif status == self.status:
return # nothing to do
elif status == Status.off:
self.target.deactivate(self.console)
self.target.activate(self.power)
self.power.off()
elif status == Status.uboot:
self.transition(Status.off)
self.target.activate(self.console)
# cycle power
self.power.cycle()
# interrupt uboot
self.target.activate(self.uboot)
elif status == Status.shell:
# transition to uboot
self.transition(Status.uboot)
self.uboot.boot("")
self.uboot.await_boot()
self.target.activate(self.shell)
self.shell.run("systemctl is-system-running --wait")
else:
raise StrategyError(f"no transition found from {self.status} to {status}")
self.status = status
[docs] def force(self, status):
if not isinstance(status, Status):
status = Status[status]
if status == Status.off:
self.target.activate(self.power)
elif status == Status.uboot:
self.target.activate(self.uboot)
elif status == Status.shell:
self.target.activate(self.shell)
else:
raise StrategyError("can not force state {}".format(status))
self.status = status