AWS IoT GreengrassにDevice Defender コンポーネントをデプロイした際に発生したエラーを解消した

2023.02.02

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。CX事業本部Delivery部のakkyです。

IoT GreengrassにDevice Defenderコンポーネントをデプロイしようとしたところ、デプロイが失敗してしまいました。

今回は、このエラーを解消しましたので、記録しておきます。

環境

  • PINE A64(aarch64)
  • Armbian/Debian 11 Bullseye

今回の事象は、RaspberryPiなど他のARMマシン(x86以外のCPU)でも同様に発生する可能性があります。

作業

コンポーネントのログは、インストールに失敗した場合でもログディレクトリに入っていました。 今回は/greengrass/v2/logs/aws.greengrass.DeviceDefender.logを見てみます。

2023-02-02T07:37:29.059Z [WARN] (Copier) aws.greengrass.DeviceDefender: stderr. ERROR: Could not build wheels for psutil, which is required to install pyproject.toml-based projects. {scriptName=services.aws.greengrass.DeviceDefender.lifecycle.install.script, serviceName=aws.greengrass.DeviceDefender, currentState=NEW}
2023-02-02T07:37:30.857Z [INFO] (Copier) aws.greengrass.DeviceDefender: stdout. Error installing dependencies. Please set 'UseInstaller' to 'False' and pre-install 'awsiotsdk', 'cbor' and 'psutil'. {scriptName=services.aws.greengrass.DeviceDefender.lifecycle.install.script, serviceName=aws.greengrass.DeviceDefender, currentState=NEW}

まず、pipをアップデートしましたが、変化ありませんでした。

エラーメッセージを読むと、psutilがエラーを吐いているようなので、こちらをチェックしてみると・・・

# pip install psutil
Collecting psutil
  Using cached psutil-5.9.4.tar.gz (485 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: psutil
  Building wheel for psutil (pyproject.toml) ... error
  error: subprocess-exited-with-error

  × Building wheel for psutil (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [45 lines of output]
      running bdist_wheel
      running build
      running build_py
      creating build
      creating build/lib.linux-aarch64-cpython-39
      creating build/lib.linux-aarch64-cpython-39/psutil
      copying psutil/_pswindows.py -> build/lib.linux-aarch64-cpython-39/psutil
      copying psutil/_pssunos.py -> build/lib.linux-aarch64-cpython-39/psutil
      copying psutil/_psposix.py -> build/lib.linux-aarch64-cpython-39/psutil
      copying psutil/_psosx.py -> build/lib.linux-aarch64-cpython-39/psutil
      copying psutil/_pslinux.py -> build/lib.linux-aarch64-cpython-39/psutil
      copying psutil/_psbsd.py -> build/lib.linux-aarch64-cpython-39/psutil
      copying psutil/_psaix.py -> build/lib.linux-aarch64-cpython-39/psutil
      copying psutil/_compat.py -> build/lib.linux-aarch64-cpython-39/psutil
      copying psutil/_common.py -> build/lib.linux-aarch64-cpython-39/psutil
      copying psutil/__init__.py -> build/lib.linux-aarch64-cpython-39/psutil
      creating build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_windows.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_unicode.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_testutils.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_system.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_sunos.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_process.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_posix.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_osx.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_misc.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_memleaks.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_linux.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_contracts.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_connections.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_bsd.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/test_aix.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/runner.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/__main__.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      copying psutil/tests/__init__.py -> build/lib.linux-aarch64-cpython-39/psutil/tests
      running build_ext
      building 'psutil._psutil_linux' extension
      creating build/temp.linux-aarch64-cpython-39
      creating build/temp.linux-aarch64-cpython-39/psutil
      aarch64-linux-gnu-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -ffile-prefix-map=/build/python3.9-PN012d/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -fPIC -DPSUTIL_POSIX=1 -DPSUTIL_SIZEOF_PID_T=4 -DPSUTIL_VERSION=594 -DPy_LIMITED_API=0x03060000 -DPSUTIL_LINUX=1 -I/usr/include/python3.9 -c psutil/_psutil_common.c -o build/temp.linux-aarch64-cpython-39/psutil/_psutil_common.o
      psutil/_psutil_common.c:9:10: fatal error: Python.h: No such file or directory
          9 | #include <Python.h>
            |          ^~~~~~~~~~
      compilation terminated.
      error: command '/usr/bin/aarch64-linux-gnu-gcc' failed with exit code 1
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for psutil
Failed to build psutil
ERROR: Could not build wheels for psutil, which is required to install pyproject.toml-based projects

PyPIを見ると、psutilのLinux用バイナリパッケージはx86_64とi686用しかなく、arm64はない(macOS用のみ)なので、バイナリからビルドしようとしたが、Pythonのヘッダがないのでコケたということのようです。

python3-devを入れればビルドできるようになるはずです。ビルドツールをインストールしていない場合は、build-essentialも入れる必要があるかと思います。

apt install python3-dev
# pip install psutil
Collecting psutil
  Using cached psutil-5.9.4.tar.gz (485 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: psutil
  Building wheel for psutil (pyproject.toml) ... done
  Created wheel for psutil: filename=psutil-5.9.4-cp39-abi3-linux_aarch64.whl size=276537 sha256=9249b43100386058cab50e370de5eb5b2bc194552c140387afa1277fdd719cbf
  Stored in directory: /root/.cache/pip/wheels/b3/e1/ef/72253145950aea37e83c8c13a844c583e2b575f1c93598901d
Successfully built psutil
Installing collected packages: psutil
Successfully installed psutil-5.9.4

念のため、cborとawsiotsdkもインストールしてみましたが、こちらはインストールできました。

# pip install cbor
Collecting cbor
  Using cached cbor-1.0.0-py3-none-any.whl
Installing collected packages: cbor
Successfully installed cbor-1.0.0
# pip install awsiotsdk
Collecting awsiotsdk
  Using cached awsiotsdk-1.12.4-py3-none-any.whl (66 kB)
Collecting awscrt==0.16.9
  Using cached awscrt-0.16.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (7.0 MB)
Installing collected packages: awscrt, awsiotsdk
Successfully installed awscrt-0.16.9 awsiotsdk-1.12.4

これで再びデプロイすると、今度は成功しました。(エラーメッセージにはUseInstallerをFalseにするようにとありましたが、何もしなくても成功しました)

2023-02-02T07:54:42.584Z [INFO] (Copier) aws.greengrass.DeviceDefender: stdout. Collector running on device: ******. {scriptName=services.aws.greengrass.DeviceDefender.lifecycle.run.script, serviceName=aws.greengrass.DeviceDefender, currentState=RUNNING}
2023-02-02T07:54:42.585Z [INFO] (Copier) aws.greengrass.DeviceDefender: stdout. Metrics topic: $aws/things/******/defender/metrics/json. {scriptName=services.aws.greengrass.DeviceDefender.lifecycle.run.script, serviceName=aws.greengrass.DeviceDefender, currentState=RUNNING}
2023-02-02T07:54:42.586Z [INFO] (Copier) aws.greengrass.DeviceDefender: stdout. Sampling interval: 300 seconds. {scriptName=services.aws.greengrass.DeviceDefender.lifecycle.run.script, serviceName=aws.greengrass.DeviceDefender, currentState=RUNNING}
2023-02-02T07:54:42.944Z [INFO] (Copier) aws.greengrass.DeviceDefender: stdout. Published to the IoT core.... {scriptName=services.aws.greengrass.DeviceDefender.lifecycle.run.script, serviceName=aws.greengrass.DeviceDefender, currentState=RUNNING}

以上