今回はおま環なお話。
iPadから照明をコントロールするため、Raspberry Pi Zero Wと4chリレーや、ESP easy化したSONOFFを壁の中に埋め込み、GPIOを使って壁のスイッチからも、iPadのHomeからも、AndroidやWebページ上のHomeAssistatからも操作できるようにしています。
リビングの照明はRaspberry Pi Zero Wでコントロールしていますが、それらのデバイスを司り、Homeアプリに中継するHomebrigeというミドルウェアは、Gentoo Linuxサーバーに設定しています。
先日、何気なくGentoo Linuxにインストールされているソフトウェアをバージョンアップすべく、emerge -uDN @worldを実行したところ、いつになく呆気なく、500以上のパッケージがノーエラーでバージョンアップできました。
そこで、再起動をかけたところ、なんだかcron.hourlyが毎時間エラーレポートをメールで送信してきています。
cron.hourlyには、homebridgeのプロセスに異常があった場合、再起動するように仕掛けてます。(それくらい不安定だった。)
が、どうやらnode.jsがバージョンアップされたためにエラーが起きていたらしいのです。
homebridge porosess is not found. Starting homebridge /usr/local/lib/node_modules/homebridge/lib/logger.js:9 const chalk_1 = __importDefault(require("chalk")); ^ Error [ERR_REQUIRE_ESM]: require() of ES Module /usr/local/lib/node_modules/homebridge/node_modules/chalk/source/index.js from /usr/local/lib/node_modules/homebridge/lib/logger.js not supported. Instead change the require of index.js in /usr/local/lib/node_modules/homebridge/lib/logger.js to a dynamic import() which is available in all CommonJS modules. at Object.<anonymous> (/usr/local/lib/node_modules/homebridge/lib/logger.js:9:33)
そこで、これらを解消しようと、まずnpmでhomebridgeをアップデートしようとしました。
gentoo / # npm update homebridge npm WARN npm npm does not support Node.js v20.11.0 npm WARN npm You should probably upgrade to a newer version of node as we npm WARN npm can't make any promises that npm will work with this version. npm WARN npm Supported releases of Node.js are the latest release of 4, 6, 7, 8. npm WARN npm You can find the latest version at https://nodejs.org/ npm ERR! cb.apply is not a function npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/2024-02-27T14_26_31_191Z-debug.log
意訳すると「このnpmはNode.js v20.11.0をサポートしてないよ。node.jsをアップデートしないとダメだよ。このnpmはnode.jsのバージョン4,6,7,8をサポートしてるよ。」
って、ここに入っているnode.jsはgentooでは最新のv20なんですけど・・・。
そして、自分の所業を遡ると、こんなことが書いてました。
これを読むと、「useフラグにnpmをつけてnodejsをemergeすると、勝手にnpmも入ってくるよ」と。
ということは、今使っているnpmは何らかの理由で(理由は忘れた)、オーバーレイインストールしたか、無理矢理手動インストールしたかのどちらかです。
npmはどこにあるのか?
gentoo / # npm -v 5.5.1 gentoo / # which npm /usr/local/bin/npm gentoo / # ls -al /usr/local/bin/npm lrwxrwxrwx 1 root root 38 11月 14 2017 npm -> ../lib/node_modules/npm/bin/npm-cli.js
実態であるnpm-cli.jsのバージョンが古いんですね。しかも、/usr/local/libにインストールしているということは、公式リポジトリ以外からインストールしているっていうことですね。
npmをUSEフラグに記述しているので、node.jsのアップデート時に、最新のnpmがどこかにインストールされているはずです。
gentoo / # find / -name npm-cli.js /var/tmp/portage/net-libs/nodejs-20.8.1/work/node-v20.8.1/deps/npm/bin/npm-cli.js /var/tmp/portage/net-libs/nodejs-20.8.1/work/node-v20.8.1/deps/npm/test/bin/npm-cli.js /var/tmp/portage/net-libs/nodejs-20.9.0/work/node-v20.9.0/deps/npm/bin/npm-cli.js /var/tmp/portage/net-libs/nodejs-20.9.0/work/node-v20.9.0/deps/npm/test/bin/npm-cli.js /usr/local/n/versions/node/8.9.1/lib/node_modules/npm/bin/npm-cli.js /usr/local/n/versions/node/9.0.0/lib/node_modules/npm/bin/npm-cli.js /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/lib64/node_modules/npm/bin/npm-cli.js gentoo / # /usr/lib64/node_modules/npm/bin/npm-cli.js -v 10.2.4
公式リポジトリ上のnpmは/usr/lib64/node_modules/npm/bin/npm-cli.jsにあるようです。
ということは、公式リポジトリからリンクされているnpm自体も、/usr/local/binではない場所にありそうです。
gentoo / # find / -name npm /etc/npm /var/tmp/portage/net-libs/nodejs-20.8.1/work/node-v20.8.1/deps/corepack/shims/npm /var/tmp/portage/net-libs/nodejs-20.8.1/work/node-v20.8.1/deps/corepack/shims/nodewin/npm /var/tmp/portage/net-libs/nodejs-20.8.1/work/node-v20.8.1/deps/npm /var/tmp/portage/net-libs/nodejs-20.8.1/work/node-v20.8.1/deps/npm/bin/npm /var/tmp/portage/net-libs/nodejs-20.8.1/work/node-v20.8.1/tools/msvs/npm /var/tmp/portage/net-libs/nodejs-20.8.1/work/node-v20.8.1/tools/macos-installer/pkgbuild/npm /var/tmp/portage/net-libs/nodejs-20.9.0/work/node-v20.9.0/deps/corepack/shims/npm /var/tmp/portage/net-libs/nodejs-20.9.0/work/node-v20.9.0/deps/corepack/shims/nodewin/npm /var/tmp/portage/net-libs/nodejs-20.9.0/work/node-v20.9.0/deps/npm /var/tmp/portage/net-libs/nodejs-20.9.0/work/node-v20.9.0/deps/npm/bin/npm /var/tmp/portage/net-libs/nodejs-20.9.0/work/node-v20.9.0/tools/msvs/npm /var/tmp/portage/net-libs/nodejs-20.9.0/work/node-v20.9.0/tools/macos-installer/pkgbuild/npm /usr/local/n/versions/node/8.9.1/bin/npm /usr/local/n/versions/node/8.9.1/lib/node_modules/npm /usr/local/n/versions/node/8.9.1/lib/node_modules/npm/bin/npm /usr/local/n/versions/node/9.0.0/bin/npm /usr/local/n/versions/node/9.0.0/lib/node_modules/npm /usr/local/n/versions/node/9.0.0/lib/node_modules/npm/bin/npm /usr/local/bin/npm /usr/local/lib/node_modules/npm /usr/local/lib/node_modules/npm/bin/npm /usr/lib64/node_modules/npm /usr/lib64/node_modules/npm/bin/npm /usr/bin/npm /usr/share/bash-completion/completions/npm /root/.npm/registry.npmjs.org/npm /root/.npm/npm gentoo / # ls -al /usr/bin/npm lrwxrwxrwx 1 root root 40 2月 25 03:27 /usr/bin/npm -> ../lib64/node_modules/npm/bin/npm-cli.js gentoo / # /usr/bin/npm -v 10.2.4
何のことはない、/usr/local/bin/npmを削除して、今後は/usr/bin/npmを使えば良いだけのことでした。
これでhomebridgeを起動してもエラーが起きます。
[2024/2/27 22:53:10] TypeError: Invalid initialization vector at Cipheriv.createCipherBase (node:internal/crypto/cipher:121:19) at Cipheriv.createCipherWithIV (node:internal/crypto/cipher:140:3) at new Cipheriv (node:internal/crypto/cipher:243:3) at Object.createCipheriv (node:crypto:146:10) at Object.chacha20_poly1305_encryptAndSeal (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/src/lib/util/hapCrypto.ts:90:25) at HAPServer._this._handlePairVerifyStepOne (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/src/lib/HAPServer.ts:553:33) at HAPServer._this._handlePairVerify (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/src/lib/HAPServer.ts:515:12) at IncomingMessage.<anonymous> (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/src/lib/HAPServer.ts:280:24) at IncomingMessage.emit (node:events:518:28) at endReadableNT (node:internal/streams/readable:1696:12) [2024/2/27 22:53:10] Got SIGTERM, shutting down Homebridge...
まずは、関連モジュールをアップデートします。
アップデートにはnpm-check-updates(コマンドは頭文字を取ってncu)を使うと良いそうですので、npmでインストールし、ncu -uでアップデート情報をpackage.jsonに書き込み、npm installでpackage.jsonに書かれた情報から各パッケージをアップデートします。
gentoo / # npm install -g npm-check-updates added 336 packages in 16s 67 packages are looking for funding run `npm fund` for details gentoo / # ncu -u Upgrading /usr/local/lib/node_modules/homebridge/package.json [====================] 20/20 100% @types/debug ^4.1.5 → ^4.1.12 @types/jest ^26.0.13 → ^29.5.12 @types/node 10.17.29 → 20.11.20 @types/semver ^7.3.3 → ^7.5.8 @typescript-eslint/eslint-plugin ^4.0.1 → ^7.1.0 @typescript-eslint/parser ^4.0.1 → ^7.1.0 chalk ^4.1.0 → ^5.3.0 commander 5.1.0 → 12.0.0 eslint ^7.8.1 → ^8.57.0 eslint-plugin-jest ^23.20.0 → ^27.9.0 hap-nodejs ^0.7.10 → ^0.11.1 jest ^26.4.2 → ^29.7.0 node-persist ^0.0.11 → ^4.0.1 rimraf ^3.0.2 → ^5.0.5 semver ^7.3.2 → ^7.6.0 source-map-support ^0.5.19 → ^0.5.21 ts-jest ^26.3.0 → ^29.1.2 ts-node ^9.0.0 → ^10.9.2 typescript ^4.0.2 → ^5.3.3 Run npm install to install new versions. gentoo / # npm install added 546 packages, removed 11 packages, changed 58 packages, and audited 609 packages in 36s 116 packages are looking for funding run `npm fund` for details found 0 vulnerabilities
そして最後に、肝心のhomebridgeそのものもアップデートしましょう。
gentoo / # npm install -g --unsafe-perm homebridge@latest added 91 packages, removed 16 packages, and changed 14 packages in 2s 43 packages are looking for funding run `npm fund` for details
それでもエラーが出ます。
gentoo / # /etc/local.d/homebridge.start Starting homebridge /usr/local/lib/node_modules/homebridge/lib/logger.js:9 const chalk_1 = __importDefault(require("chalk")); ^ Error [ERR_REQUIRE_ESM]: require() of ES Module /usr/local/lib/node_modules/homebridge/node_modules/chalk/source/index.js from /usr/local/lib/node_modules/homebridge/lib/logger.js not supported. Instead change the require of index.js in /usr/local/lib/node_modules/homebridge/lib/logger.js to a dynamic import() which is available in all CommonJS modules. at Object.<anonymous> (/usr/local/lib/node_modules/homebridge/lib/logger.js:9:33)
よく読むと、そもそもhomebridge自体も/usr/local/binにあるもののようです。
最新のhomegridgeはどこなのか?
gentoo / # find / -name homebridge /var/homebridge /usr/local/bin/homebridge /usr/local/lib/node_modules/homebridge-http-switch/test/homebridge /usr/local/lib/node_modules/homebridge /usr/local/lib/node_modules/homebridge/bin/homebridge /usr/lib64/node_modules/homebridge /usr/lib64/node_modules/homebridge/bin/homebridge /usr/bin/homebridge /root/.npm/registry.npmjs.org/homebridge
やはり、/usr/bin/homebridgeがありましたね。
/etc/local.d/homebridge.startの内容を変更します。
#!/bin/sh #dir="/var/homebridge" name="homebridge" pid_file="/var/run/$name.pid" stdout_log="/var/log/$name.log" stderr_log="/var/log/$name.err" echo "Starting $name" #cd "$dir" /usr/bin/homebridge -U /var/homebridge & echo $! > "$pid_file"
あと、node.js自体も、/usr/local/bin/nodeにシンボリックリンクあるので、/usr/local/bin/npmや/usr/local/bin/homebridgeと一緒に消しておきます。
(これらはシンボリックリンクなので、消しても実体は残っています。)
これで無事にhomebridgeが起動・復活しました。