Azure/azure-iot-cli-extension

[bug] - UAMQP / monitor-events - Apple Silicon is not supported

Opened this issue ยท 4 comments

Describe the bug

When running this extension on a Mac using Apple Silicon, an error is thrown by UAMQP that the hardware is not supported.

To Reproduce

Use an Apple Silicon based Mac.
Install the az cli and the IoT extension
Try to use the extension, for example to monitor a hub

Expected behavior

It should work

Environment (please complete the following information):

  • OS: macOS 12.0.1 running on a M1-based MacBookPro
  • Shell: zsh
  • Az CLI version: 2.30.0
  • IoT extension version:0.11.0
  • Python version (if pip installed): 3.9.7

Additional context

Error message:

โžœ  ~ az iot hub monitor-events --hub-name animal-tracker
The command failed with an unexpected error. Here is the traceback:
dlopen(/Users/jim/.azure/cliextensions/azure-iot/uamqp/c_uamqp.cpython-310-darwin.so, 0x0002): tried: '/Users/jim/.azure/cliextensions/azure-iot/uamqp/c_uamqp.cpython-310-darwin.so' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e')), '/usr/local/lib/c_uamqp.cpython-310-darwin.so' (no such file), '/usr/lib/c_uamqp.cpython-310-darwin.so' (no such file)
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/azure-cli/2.30.0_1/libexec/lib/python3.10/site-packages/knack/cli.py", line 231, in invoke
    cmd_result = self.invocation.execute(args)
  File "/opt/homebrew/Cellar/azure-cli/2.30.0_1/libexec/lib/python3.10/site-packages/azure/cli/core/commands/__init__.py", line 657, in execute
    raise ex
  File "/opt/homebrew/Cellar/azure-cli/2.30.0_1/libexec/lib/python3.10/site-packages/azure/cli/core/commands/__init__.py", line 720, in _run_jobs_serially
    results.append(self._run_job(expanded_arg, cmd_copy))
  File "/opt/homebrew/Cellar/azure-cli/2.30.0_1/libexec/lib/python3.10/site-packages/azure/cli/core/commands/__init__.py", line 691, in _run_job
    result = cmd_copy(params)
  File "/opt/homebrew/Cellar/azure-cli/2.30.0_1/libexec/lib/python3.10/site-packages/azure/cli/core/commands/__init__.py", line 328, in __call__
    return self.handler(*args, **kwargs)
  File "/opt/homebrew/Cellar/azure-cli/2.30.0_1/libexec/lib/python3.10/site-packages/azure/cli/core/commands/command_operation.py", line 121, in handler
    return op(**command_args)
  File "/Users/jim/.azure/cliextensions/azure-iot/azext_iot/operations/hub.py", line 2942, in iot_hub_monitor_events
    _iot_hub_monitor_events(
  File "/Users/jim/.azure/cliextensions/azure-iot/azext_iot/operations/hub.py", line 3055, in _iot_hub_monitor_events
    from azext_iot.monitor.builders import hub_target_builder
  File "/Users/jim/.azure/cliextensions/azure-iot/azext_iot/monitor/builders/hub_target_builder.py", line 8, in <module>
    import uamqp
  File "/Users/jim/.azure/cliextensions/azure-iot/uamqp/__init__.py", line 12, in <module>
    from uamqp import c_uamqp  # pylint: disable=import-self
ImportError: dlopen(/Users/jim/.azure/cliextensions/azure-iot/uamqp/c_uamqp.cpython-310-darwin.so, 0x0002): tried: '/Users/jim/.azure/cliextensions/azure-iot/uamqp/c_uamqp.cpython-310-darwin.so' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e')), '/usr/local/lib/c_uamqp.cpython-310-darwin.so' (no such file), '/usr/lib/c_uamqp.cpython-310-darwin.so' (no such file)

This also appears to be a new issue - this was used earlier this year with no problems (before July 2021).

Update on working before - I wonder if the Azure CLI was running under Rosetta 2 before, so was ok with the x86_64 builds.

Issue raised for UAMQP for lack of Apple Silicon support: Azure/azure-uamqp-python#284

Update - I can make this work by:

  • Creating a new virtual environment
  • Installing uamqp in the virtual environment without using binaries, so it is rebuilt for arm64: pip install uamqp --no-binary uamqp --no-cache-dir
  • Copying the uamqp folder from my virtual environment into the extension at `~/.azure/cliextensions/azure-iot'

So as a fix - can the setup code for this extension be changed to install uamqp with the no-binary flag? Not sure how to do this in a setup.py.

For me, this was a better approach than having to copy-paste with #468 (comment).