2

I'm having some issues with the pyghmi python library, which is used for sending IPMI commands with python scripts. My goal is to implement an HTTP API to send IPMI commands through HTTP requests.

I am already able to create a Session and send a few commands with the library, but if the Session remains IDLE for 30 seconds, it logged itself out. When the Session is logged out, I can't create a new one : I get an error "Session is logged out", or a deadlock.

How can I do if I want to have a server that is always up and create Session when it receives requests, if I can't create new Session when the previous one is logged out ?

What I've tried :

from pyghmi.ipmi import command

ipmi = command.Command(ip, user, passwd)
res = ipmi.get_power()
print(res)

# wait 30 seconds

res2 = ipmi.get_power() # get "Session logged out" error

ipmi2 = command.Command(ip, user, paswd) # Deadlock if wait < 30 seconds, else no error

res3 = ipmi2.get_power() # get "Session logged out" error

# Impossible to create new command.Command() Session, every command will give "logged out" error

The other problem is that I can't use the asynchronous way by giving an "onlogon callback" function in the command.Command() call, because I will need the callback return value in the caller and that's not possible with this sort of thread behavior.

Edit: I already tried some examples provided here but it's always one-time run scripts, whereas I'm looking for something that can stay "up" forever.

  • This question seems promising to the community. Just a minor suggestion, try to address [`pyghmi ` documentation](https://pypi.org/project/pyghmi/). – Francisco Maria Calisto Mar 15 '21 at 13:30
  • 2
    Yes you are right, I already check all the documentation I could find and the main problem is here : there is not enough documentation about pyghmi I think ... There are some examples provided [here](https://opendev.org/x/pyghmi/src/branch/master/pyghmi/cmd/pyghmiutil.py) but it's always one-time run scripts, whereas I'm looking for something that can stay "up" forever. I think I will E-mail the pyghmi's main contributor. – Anteunis Charles Mar 15 '21 at 13:41
  • Thank you for your comment. Based on what you are saying, just try to improve your question telling to the community what you just said here in your last comment. It will help and improve your question. – Francisco Maria Calisto Mar 15 '21 at 20:43

3 Answers3

1

So I finally achieved a sort of solution. I emailed the Pyghmi's main contributor and he said that this lib was not suited for a multi- and reuseable- Session implementation (there is currently an open issue "Session reuse" on Pyghmi repository).

First "solution": use processes

My goal was to create an HTTP API. To avoid the Session timeout issue, I create a new Process (not Thread) for every new request. That works fine, but I did not keep this solution because it is to heavy and sockets consuming. It seems that by creating processes, the memory used by Pyghmi is not shared between processes (that's the goal of processes) so every Session utilisation is not a reuse but a creation.

Second "solution" : use Confluent

Confluent is a tool developed by Lenovo that allow to control hardware via HTTP. It uses a sort of patched version of Pyghmi as backend for IPMI calls. Confluent documentation here.

Once installed and configured on a server, Confluent worked well to control IPMI devices via HTTP. I packaged it in a Docker image along with an ipmi_simulator for testing purposes : confluent dockerized.

  • Regarding multi session use, i understand, but I don't understand why the guy might have said it is not suitable for reusable sessions, because the Housekeeper thread and the documentation about "long lived use" was there three years ago. I did not go back further to check. – Hoov Nov 10 '22 at 23:18
1

The solution today is to run Command.eventloop() after creating the connection. It is documented in ipmi/command.py, which has a very trivial Housekeeper class which in the current version 1.5.53 is actually just a renamed Thread class, with no additional features. It merely runs the eventloop.

The implementation looks like this. One of those mentioned house keeping tasks is sending keepalive messages, if enabled which it is by default and can be influence by supplying keepalive=True at Command instantiation:

class Housekeeper(threading.Thread):                                                
    """A Maintenance thread for housekeeping

    Long lived use of pyghmi may warrant some recurring asynchronous behavior.
    This stock thread provides a simple minimal context for these housekeeping
    tasks to run in.  To use, do 'pyghmi.ipmi.command.Maintenance().start()'
    and from that point forward, pyghmi should execute any needed ongoing
    tasks automatically as needed.  This is an alternative to calling
    wait_for_rsp or eventloop in a thread of the callers design.
    """

    def run(self):
        Command.eventloop()

Hoov
  • 133
  • 1
  • 9
0

Look this.

@staticmethod
def ipmi_close():
    import pyghmi.ipmi.private.session as ipmi_session

    ipmi_session.iothread.join()
    ipmi_session.iothread = None
    ipmi_session.iothreadready = False
    ipmi_session.iothreadwaiters.clear()

    for socket in ipmi_session.iosockets:
        socket.close()
    ipmi_session.iosockets.clear()

    ipmi_session.Session.socketpool.clear()
    ipmi_session.Session.initting_sessions.clear()
    ipmi_session.Session.bmc_handlers.clear()
    ipmi_session.Session.waiting_sessions.clear()
    ipmi_session.Session.initting_sessions.clear()
    ipmi_session.Session.keepalive_sessions.clear()
    ipmi_session.Session.peeraddr_to_nodes.clear()
    ipmi_session.Session.iterwaiters.clear()
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 25 '23 at 09:06