こんにちは。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}
以上