8000 Board Linux shall have a way to be soft reseted (`reboot`) · Issue #26 · Rahix/tbot · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Board Linux shall have a way to be soft reseted (reboot) #26

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
niecore opened this issue Jul 24, 2020 · 6 comments
Open

Board Linux shall have a way to be soft reseted (reboot) #26

niecore opened this issue Jul 24, 2020 · 6 comments

Comments

@niecore
Copy link
niecore commented Jul 24, 2020

It would be great to trigger a soft reset with reboot for some testcases.
Unfortunately exec0 reboot will not terminate because the prompt will not be shown again.
The softreset function could handle the relogin as well.

@niecore niecore changed the title Board Linux shall have a way to be soft reseted (`reboot Board Linux shall have a way to be soft reseted (reboot) Jul 24, 2020
@Rahix
Copy link
Owner
Rahix commented Jul 24, 2020

My current pattern for soft-resets is this:

with contexlib.ExitStack() as cx:
    b = cx.enter_context(tbot.acquire_board(lh))
    lnx = cx.enter_context(tbot.acquire_linux(b))

    ...
    
    ch = lnx.open_channel("systemctl", "reboot")
    # Stuff the channel back into the board-machine ...
    b.ch = ch

    # Reinitialize the linux-machine which will wait for the reboot to
    # reach the login-prompt again.
    lnx = cx.enter_context(tbot.acquire_linux(b))

    ...

I know, this isn't the pretties way to do it and I was also thinking that maybe it would be useful to have a way for doing soft-resets with a single method call. But I'm not really sure how to model this without making a lot of assumptions about the user, so we'll have to see ...

For now, this explicit re-initialization is the pattern I would suggest you use.

@avylove
Copy link
avylove commented Jul 14, 2022

I wasn't able to get the example to work. It would hang once Linux would shutdown, but wouldn't power cycle.
This does seem to work for me

  re_poweroff = re.compile(b'reboot: Power down\s{0,10}')
  shutdown_cmd = ("sudo", "systemctl", "poweroff")

  with tbot.ctx.request(tbot.role.BoardLinux) as serial:
      with serial.run(*shutdown_cmd) as shutdown:
          shutdown.read_until_prompt(prompt=re_poweroff, timeout=60)
          shutdown._pre_terminate()
          shutdown._proxy_alive = False

I would prefer not to use private attributes, but I couldn't get it to work cleanly otherwise. I tried running serial.ch.read_until_prompt(), but it just hung like before.

Any advice on achieving something similar without accessing private attributes?

@Rahix
Copy link
Owner
Rahix commented Jul 15, 2022

I am not 100% sure what you are trying to do... You want to first power-off the system and then have tbot power-cycle it, is that correct? In that case, try something like this:

with tbot.ctx.request(tbot.role.BoardLinux, exclusive=True) as lnx:
    # Do something before reboot
    lnx.exec0("uname", "-a")

    # Power-down the system
    ch = lnx.open_channel("systemctl", "poweroff")
    ev = tbot.log.EventIO(["powerdown"], "System powering down...")
    with ch.with_stream(ev):
        ev.prefix = "   <> "
        ch.expect(["reboot: Power down", "reboot: System halted"])

with tbot.ctx.request(tbot.role.BoardLinux, reset=True) as lnx:
    # Do something after reboot
    lnx.exec0("uname", "-a")

FWIW, this issue was originally about performing a soft-reset without power-cycling the system. For that, things work a bit differently...

@avylove
Copy link
avylove commented Jul 21, 2022

Thanks! Using Channel.expect() is much cleaner.

For my use case, either a reboot or a shutdown will work. I just need the OS to shutdown cleanly and not just power cycle. The issue I had with the reboot is it just hung. Perhaps it also needs Channel.expect()?

@avylove
Copy link
avylove commented Aug 12, 2022

Turns out I do need to reboot. I tried to implement what you have in #26 (comment). It works if I'm just running additional commands on the serial console within that same context block, but, if I call other code after this that requests the LinuxBoard role and uses the channel, I'll get a ChannelTakenException. I'm guessing the global context is sharing the original machine object and not the second one?

@franzflasch
Copy link

I would also need to do a reboot without a power cylcle in between. How can this be done cleanly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
0