rpi-source が失敗するときの解決方法 (ImportError, tar Error)

# 前提条件
* Raspberry Pi 2 Model B
* Volumio 3.703 (Raspberry Pi OS でも同じだと思います)
* Realtek RTL8811AU （アダプタに搭載されたチップ）
* [rpi-source](https://github.com/RPi-Distro/rpi-source)

`uname` コマンドの実行結果
```:uname -r 実行結果
6.1.77-v7+
```
```:uname -a 実行結果
Linux volumio 6.1.77-v7+ #1730 SMP Thu Feb  8 15:17:51 GMT 2024 armv7l GNU/Linux
```

使用している Raspberry Pi 2B には Wi-Fi モジュールが搭載されていないため、Wi-Fi ドングルを接続し、ドライバをインストールしようとしました。
その過程で `rpi-source` を使って Kernel source を取得しようとしましたが、エラーで進めなくなりました。解決方法を説明します。

# ImportError: No module named request
rpi-source をインストールするため、次のコマンドを実行したところ、エラーが発生しました。
```bash:実行したコマンド
sudo apt install git bc bison flex libssl-dev
sudo wget https://raw.githubusercontent.com/RPi-Distro/rpi-source/master/rpi-source -O /usr/local/bin/rpi-source
sudo chmod +x /usr/local/bin/rpi-source
/usr/local/bin/rpi-source -q --tag-update  # エラー発生
```

次のように urllib がインポートできないというエラーメッセージが表示されました。
```:発生したエラーメッセージ
Traceback (most recent call last):
  File "/usr/local/bin/rpi-source", line 14, in <module>
    import urllib.request, urllib.parse, urllib.error
ImportError: No module named request
```

これは rpi-source が Python3 で実行されることを想定しているのにも関わらず、Python2 で実行されているために発生します。
そこで、rpi-source の先頭行のシバン (Shebang) を直接修正します。

参考: https://forums.raspberrypi.com/viewtopic.php?t=324870 （直接的な問題解決ではないが）

```bash:vi コマンド実行
sudo vi /usr/local/bin/rpi-source
```

```:修正前
#!/usr/bin/env python
```

```:修正後
#!/usr/bin/env python3
```

エラーで実行できなかったコマンドを再度実行する。
```bash:コマンド実行
/usr/local/bin/rpi-source -q --tag-update
```

# tar: Exiting with failure status due to previous errors
Kernel source を取得するため、rpi-source を実行しました。

```bash:コマンド実行
rpi-source  # エラー発生
```

次のようなエラーが発生しました。
```:rpi-source 実行結果
 *** Unpack kernel source
tar: linux-77fc1fbcb5c013329af9583307dd1ff3cd4752aa/arch/arm64/boot/dts/broadcom: Directory renamed before its status could be extracted
tar: linux-77fc1fbcb5c013329af9583307dd1ff3cd4752aa/arch/arm64/boot/dts/arm: Directory renamed before its status could be extracted
tar: linux-77fc1fbcb5c013329af9583307dd1ff3cd4752aa/arch/arm64/boot/dts: Directory renamed before its status could be extracted
tar: linux-77fc1fbcb5c013329af9583307dd1ff3cd4752aa/arch/arm64/boot: Directory renamed before its status could be extracted
tar: linux-77fc1fbcb5c013329af9583307dd1ff3cd4752aa/arch/arm64: Directory renamed before its status could be extracted
tar: Exiting with failure status due to previous errors
Traceback (most recent call last):
  File "/usr/local/bin/rpi-source", line 434, in <module>
    sh("cd %s && tar --checkpoint=100 --checkpoint-action=dot -xzf %s" % (args.dest, linux_tar))
  File "/usr/local/bin/rpi-source", line 96, in sh
    subprocess.check_call(cmd, shell=True)
  File "/usr/lib/python3.7/subprocess.py", line 347, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command 'cd /home/volumio/rpi-source && tar --checkpoint=100 --checkpoint-action=dot -xzf /home/volumio/rpi-source/linux-77fc1fbcb5c013329af9583307dd1ff3cd4752aa.tar.gz' returned non-zero exit status 2.
```

これは `/usr/local/bin/rpi-source` の434行目で tar が実行されており、tar コマンドでエラーが発生しているようです。

```:434行目付近
info("Unpack kernel source")
if args.quiet:
    sh("cd %s && tar -xzf %s" % (args.dest, linux_tar))
else:
    sh("cd %s && tar --checkpoint=100 --checkpoint-action=dot -xzf %s" % (args.dest, linux_tar))
```

エラーの詳細を確認するため、tar コマンドを手動で実行してみます。

```bash:tar コマンド実行
tar -xzf linux-77fc1fbcb5c013329af9583307dd1ff3cd4752aa.tar.gz
```

すると、よくわからないエラーで止まりました。こちらは調べましたがよくわかりませんでした。
```:tar コマンド実行結果
tar: linux-77fc1fbcb5c013329af9583307dd1ff3cd4752aa/arch/arm64/boot/dts/broadcom: Directory renamed before its status could be extracted
tar: linux-77fc1fbcb5c013329af9583307dd1ff3cd4752aa/arch/arm64/boot/dts/arm: Directory renamed before its status could be extracted
tar: linux-77fc1fbcb5c013329af9583307dd1ff3cd4752aa/arch/arm64/boot/dts: Directory renamed before its status could be extracted
tar: linux-77fc1fbcb5c013329af9583307dd1ff3cd4752aa/arch/arm64/boot: Directory renamed before its status could be extracted
tar: linux-77fc1fbcb5c013329af9583307dd1ff3cd4752aa/arch/arm64: Directory renamed before its status could be extracted
tar: Exiting with failure status due to previous errors
```

そこで、tar コマンドの代わりに bsdtar コマンドを使って tar.gz を解凍することにしました。bsdtar コマンドをインストールします。
```bash:apt install コマンド実行
sudo apt install bsdtar
```

`/usr/local/bin/rpi-source` の434行目付近を bsdtar コマンドで実行するように修正します。（オプションはなし）
```:434行目付近 変更後
info("Unpack kernel source")
sh("cd %s && bsdtar -xzf %s" % (args.dest, linux_tar))
```

中途半端に解凍された linux-(hash) フォルダを削除し、rpi-source コマンドを再度実行します。
```bash:コマンド実行
rm -rf linux-(hash)
rpi-source
```

正常に成功しているはずです。