saltstack / salt

Software to automate the management and configuration of any infrastructure or application at scale. Get access to the Salt software package repository here:
https://repo.saltproject.io/
Apache License 2.0
14.09k stars 5.47k forks source link

[BUG] ipmi.get_health: NameError: name 'unicode' is not defined #60793

Open darkpixel opened 3 years ago

darkpixel commented 3 years ago

Description The get_health method of the ipmi module throws NameError: name 'unicode' is not defined when querying my SuperMicro IPMI.

[root@salt ~]# salt 'uslogsdnas01.--redacted--.local' ipmi.get_health api_host=--redacted-ip-- api_user='admin' api_pass='--redacted-password--'
uslogsdnas01.--redacted--.local:
    The minion function caused an exception: Traceback (most recent call last):
      File "/usr/lib/python3/dist-packages/salt/minion.py", line 1905, in _thread_return
        function_name, function_args, executors, opts, data
      File "/usr/lib/python3/dist-packages/salt/minion.py", line 1861, in _execute_job_function
        return_data = self.executors[fname](opts, data, func, args, kwargs)
      File "/usr/lib/python3/dist-packages/salt/loader.py", line 1241, in __call__
        return self.loader.run(run_func, *args, **kwargs)
      File "/usr/lib/python3/dist-packages/salt/loader.py", line 2274, in run
        return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
      File "/usr/lib/python3/dist-packages/salt/loader.py", line 2289, in _run_as
        return _func_or_method(*args, **kwargs)
      File "/usr/lib/python3/dist-packages/salt/executors/direct_call.py", line 12, in execute
        return func(*args, **kwargs)
      File "/usr/lib/python3/dist-packages/salt/loader.py", line 1241, in __call__
        return self.loader.run(run_func, *args, **kwargs)
      File "/usr/lib/python3/dist-packages/salt/loader.py", line 2274, in run
        return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
      File "/usr/lib/python3/dist-packages/salt/loader.py", line 2289, in _run_as
        return _func_or_method(*args, **kwargs)
      File "/usr/lib/python3/dist-packages/salt/modules/ipmi.py", line 611, in get_health
        return s.get_health()
      File "/usr/lib/python3/dist-packages/pyghmi/ipmi/command.py", line 660, in get_health
        for reading in self.get_sensor_data():
      File "/usr/lib/python3/dist-packages/pyghmi/ipmi/command.py", line 858, in get_sensor_data
        self._sdr = sdr.SDR(self)
      File "/usr/lib/python3/dist-packages/pyghmi/ipmi/sdr.py", line 610, in __init__
        self.read_info()
      File "/usr/lib/python3/dist-packages/pyghmi/ipmi/sdr.py", line 641, in read_info
        self.get_sdr()
      File "/usr/lib/python3/dist-packages/pyghmi/ipmi/sdr.py", line 715, in get_sdr
        self.add_sdr(sdrdata)
      File "/usr/lib/python3/dist-packages/pyghmi/ipmi/sdr.py", line 734, in add_sdr
        newent = SDREntry(sdrbytes, self.ipmicmd)
      File "/usr/lib/python3/dist-packages/pyghmi/ipmi/sdr.py", line 276, in __init__
        self.fru_decode(entrybytes[5:])
      File "/usr/lib/python3/dist-packages/pyghmi/ipmi/sdr.py", line 310, in fru_decode
        self.fru_name = self.tlv_decode(entry[10], entry[11:])
      File "/usr/lib/python3/dist-packages/pyghmi/ipmi/sdr.py", line 575, in tlv_decode
        return unicode(struct.pack("%dB" % len(data), *data), "utf_8")
    NameError: name 'unicode' is not defined

Versions Report Minion:

    Salt Version:
              Salt: 3003.2

    Dependency Versions:
              cffi: Not Installed
          cherrypy: Not Installed
          dateutil: 2.7.3
         docker-py: Not Installed
             gitdb: Not Installed
         gitpython: Not Installed
            Jinja2: 2.10
           libgit2: Not Installed
          M2Crypto: 0.31.0
              Mako: Not Installed
           msgpack: 0.5.6
      msgpack-pure: Not Installed
      mysql-python: Not Installed
         pycparser: Not Installed
          pycrypto: 2.6.1
      pycryptodome: 3.6.1
            pygit2: Not Installed
            Python: 3.7.3 (default, Jan 22 2021, 20:04:44)
      python-gnupg: Not Installed
            PyYAML: 3.13
             PyZMQ: 17.1.2
             smmap: Not Installed
           timelib: Not Installed
           Tornado: 4.5.3
               ZMQ: 4.3.1

    System Versions:
              dist: debian 10 buster
            locale: UTF-8
           machine: x86_64
           release: 5.4.128-1-pve
            system: Linux
           version: Debian GNU/Linux 10 buster
lukasraska commented 3 years ago

@darkpixel the exception seems to originate inside pyghmi library (see the last lines of stacktrace), which is most probably caused by outdated version that doesn't fully support Python 3

While Debian Buster has python3-pyghmi (which I think is the one you have installed) - https://packages.debian.org/buster/python3-pyghmi , it contains the unicode function that is no longer available in Python 3.

My guess would be to try to use the newest version (https://opendev.org/x/pyghmi) and report this to the Debian maintainers, so they can fix it from their side

darkpixel commented 3 years ago

Thanks @lukasraska ! I am using the python3 version. I don't see anything in their bug tracker about it, but they're using launchpad. Launchpad and I have issues after they deactivated and renamed my account and refused to fix it. ;) Someone else will have to report it to them.

lukasraska commented 3 years ago

@darkpixel I don't think Debian is using Launchpad (I believe it's mostly for Ubuntu projects), rather there is reportbug program in Debian that can be used (https://www.debian.org/Bugs/Reporting), so would be worth trying that.

If you're not able to report it even with the reportbug, I can just spin up some VM with Debian 10 and report it myself. Might be also good idea to include link to this Salt issue for reference.

Also as I don't know how long it might take for Debian to fix this upstream, so as a workaround it seems to be fairly easy to build the current upstream version as deb package, for example in Docker:

$ docker run --rm -it debian:10 bash
root@7c8c2e178153:/# apt update
...

root@7c8c2e178153:/# apt install git python-stdeb python3-stdeb python3-setuptools -y
...

root@7c8c2e178153:/# git clone https://opendev.org/x/pyghmi.git && cd pyghmi
Cloning into 'pyghmi'...
remote: Enumerating objects: 7006, done.
remote: Counting objects: 100% (7006/7006), done.
remote: Compressing objects: 100% (2207/2207), done.
remote: Total 7006 (delta 5252), reused 6463 (delta 4763)
Receiving objects: 100% (7006/7006), 1.17 MiB | 1.52 MiB/s, done.
Resolving deltas: 100% (5252/5252), done.

root@7c8c2e178153:/pyghmi# ./builddeb
...
dpkg-deb: building package 'python3-pyghmi' in '../python3-pyghmi_1.5.29~dev1.gg611b8f3-1_all.deb'.
dpkg-deb: building package 'python-pyghmi' in '../python-pyghmi_1.5.29~dev1.gg611b8f3-1_all.deb'.
...

root@7c8c2e178153:/pyghmi# ls ../*.deb
../python-pyghmi_1.5.29~dev1.gg611b8f3-1_all.deb  ../python3-pyghmi_1.5.29~dev1.gg611b8f3-1_all.deb

root@7c8c2e178153:/pyghmi# dpkg -i ../python3-pyghmi_1.5.29~dev1.gg611b8f3-1_all.deb
Selecting previously unselected package python3-pyghmi.
(Reading database ... 21863 files and directories currently installed.)
Preparing to unpack .../python3-pyghmi_1.5.29~dev1.gg611b8f3-1_all.deb ...
Unpacking python3-pyghmi (1.5.29~dev1.gg611b8f3-1) ...
Setting up python3-pyghmi (1.5.29~dev1.gg611b8f3-1) ...

root@7c8c2e178153:/pyghmi# python3
Python 3.7.3 (default, Jan 22 2021, 20:04:44) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyghmi.ipmi.sdr
>>> entry = pyghmi.ipmi.sdr.SDREntry((0x00, 0x00, 0x51, 0x00), 'test')
>>> entry.tlv_decode(0, (0x00,))
'\x00'

As I don't have currently any machine with IPMI I could test it against, I just mocked the input data for the SDREntry to call the tlv_decode in order to test that it actually does something, rather than testing it works without any issues. But I believe it should work better than the current Debian version.

darkpixel commented 1 year ago

Currently get_health (and pretty much every other IPMI-related command) isn't working. It looks like pyghmi throws an exception and salt doesn't know what to do with it.

$ salt-call -l debug ipmi.get_health
<snip>
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] LazyLoaded ipmi.get_users
[DEBUG   ] LazyLoaded direct_call.execute
[DEBUG   ] LazyLoaded config.get
[ERROR   ] An un-handled exception was caught by salt's global exception handler:
IpmiException: None
Traceback (most recent call last):
  File "/usr/bin/salt-call", line 11, in <module>
    load_entry_point('salt==3004', 'console_scripts', 'salt-call')()
  File "/usr/lib/python3/dist-packages/salt/scripts.py", line 432, in salt_call
    client.run()
  File "/usr/lib/python3/dist-packages/salt/cli/call.py", line 55, in run
    caller.run()
  File "/usr/lib/python3/dist-packages/salt/cli/caller.py", line 111, in run
    ret = self.call()
  File "/usr/lib/python3/dist-packages/salt/cli/caller.py", line 218, in call
    ret["return"] = self.minion.executors[fname](
  File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 149, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 1201, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 1216, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/salt/executors/direct_call.py", line 10, in execute
    return func(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 149, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 1201, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 1216, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/salt/modules/ipmi.py", line 887, in get_users
    with _IpmiCommand(**kwargs) as c:
  File "/usr/lib/python3/dist-packages/salt/modules/ipmi.py", line 73, in __init__
    self.o = command.Command(
  File "/usr/lib/python3/dist-packages/pyghmi/ipmi/command.py", line 177, in __init__
    self.ipmi_session = session.Session(bmc=bmc,
  File "/usr/lib/python3/dist-packages/pyghmi/ipmi/private/session.py", line 550, in __init__
    raise exc.IpmiException(self.errormsg)
pyghmi.exceptions.IpmiException: None
Traceback (most recent call last):
  File "/usr/bin/salt-call", line 11, in <module>
    load_entry_point('salt==3004', 'console_scripts', 'salt-call')()
  File "/usr/lib/python3/dist-packages/salt/scripts.py", line 432, in salt_call
    client.run()
  File "/usr/lib/python3/dist-packages/salt/cli/call.py", line 55, in run
    caller.run()
  File "/usr/lib/python3/dist-packages/salt/cli/caller.py", line 111, in run
    ret = self.call()
  File "/usr/lib/python3/dist-packages/salt/cli/caller.py", line 218, in call
    ret["return"] = self.minion.executors[fname](
  File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 149, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 1201, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 1216, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/salt/executors/direct_call.py", line 10, in execute
    return func(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 149, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 1201, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 1216, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/salt/modules/ipmi.py", line 887, in get_users
    with _IpmiCommand(**kwargs) as c:
  File "/usr/lib/python3/dist-packages/salt/modules/ipmi.py", line 73, in __init__
    self.o = command.Command(
  File "/usr/lib/python3/dist-packages/pyghmi/ipmi/command.py", line 177, in __init__
    self.ipmi_session = session.Session(bmc=bmc,
  File "/usr/lib/python3/dist-packages/pyghmi/ipmi/private/session.py", line 550, in __init__
    raise exc.IpmiException(self.errormsg)
pyghmi.exceptions.IpmiException: None