Python3 dd-tool for Raspberry Pi 3(Orange Pi 3)

現在の当サイトのメイン環境はRaspberryPi3そしてファイルサーバーにOrangePi3を使って運用しています。それぞれOSのカード以外にSSDやHDDを接続しています。
各OSのイメージ作成にはddコマンドを使ってカードを作成しています。
ddコマンドはOSイメージ作成以外にもいろいろな使い方ができる強力なツールなのですが、使い方を誤ると悲惨な結果を招くことがあります。
間違いを犯す要因として接続ポートによってデバイス名が変わってしまうことが挙げられます。また注意していてもhistoryを多用しているとうっかり過去に使ったデバイス名で実行してしまうということもありえます。

他OSでは便利なツールもあるようですがOSカード作成専用にddコマンドを利用してほぼ間違えようのないツールを作成してみたいと思います。
Raspbian,Armbian(debian buster)用のツールです。

このツールを試すときはdf,lsblkなどのコマンドで充分確認の上実行するようにします。(無責任、無保証です)

概要

ddコマンドの基本書式は次のとおり

# dd if=os.img of=/dev/sdX bs=1M status=progress


ListBOXには接続してあるデバイスのuuidを表示します。
Img File欄には目的のイメージファイルをフルパスで入力します。

使い方は簡単でListBOXから書き込みをするSDカードを選択してSELECTボタンを押すとTerget Device欄に/dev/sdXを表示します。
Terget Deviceは/dev/sdXとして認識できるデバイスを対象にしています。
Img File欄にos imgの場所をコピー貼付けしてFLASHボタンを押すとddを実行します。

画像ではいろいろuuidが表示されていますがこのツールの肝はusbポートに接続してあるssd(hdd)やデータ用のSDカードなど取り外しデバイスのuuidを登録することによってListBOXには載らないようにしています。
uuidは一意(ユニーク)な値になっているので再フォーマットなどパーティション変更に伴う変更をしない限り重複、変化することはありません。
dd,uuidの最低限の基本を理解、設定してあれば極めて安全に且つ簡単にOSイメージのカードを作成することができます。
システム関連の設定は一切変更を加えていなのでコマンドラインその他の操作は一切変わりません。

除外デバイス

プログラム(dd-tool.py)の最初の方に除外デバイスを記述しています。

# device(除外デバイス)
command = ("ls -l /dev/disk/by-uuid | grep -v mmc | awk '{print $9}' | \
grep -v a12e7061-82ca-425e-a377-bbc9f46430e6 | \
grep -v b4f5e826-c78f-4b69-90d0-3753e6b69091 | \
grep -v cb6158bb-02fb-4b75-8736-4ca2bc6a8e5f | \
grep -v 633D-1EF9")

上記は当サイトのRPI3(SSD)の例です。4個のパーティション(うち1個はdosパーティション)があります。

接続したデバイスは/dev/disk/by-uuidに挙がってきます。内蔵スロットのカードはmmcblk0として認識しますがやはりgrep -v mmcでListに載らないようにしています。内蔵スロットからusbポートに差替えた場合はListに挙がってきます。Listに載せたくない場合はやはり除外デバイスとしてリストに記載します。

デフォルト(内蔵スロットカード)はListに何も表示されません。


除外デバイスを設定してraspbianを書き込んだカードを挿してプログラムを起動、またはRELOADボタン(再起動)を押すとリストに現れます。
どちらかを選択(同じ)してSELECTするとメッセージボックスが出現します。
messageboxはlsblk | grep /dev/sdXとsudo blkid | grep /dev/sdXしています。
ターミナルから確認するといいでしょう。

フォーマット

ddはイメージそのまま書き込んでいくのでフォーマットなしでもいいはずなのですが過去の経緯からフォーマットしたほうが安心感があります。初期の頃はOSのせいか安物のカードリーダーのせいかフォーマットしたほうが成功する率が高かったように思います。

パーティションエディタはpartedを実行しています。
実行はやはりデバイスを選択してFORMATボタンをクリックします。
messageboxが出るのでOKで開始
マウントしてあれば自動でアンマウントして実行
パーティションはforで廻してrm
mklabel msdos
mkpart primary fat32 1MiB 100%
FAT32専用フォーマット
xterm -e sudo mkfs.vfat -v -F 32 /dev/sdX1
完了メッセージが出るのでOKでプログラム再起動
uuidが変わります。

書き込み

テストとしてraspbian busterを焼いてみます。ダウンロードして展開しておきます。
Img File欄にフルパスでimgファイルの場所を指定します。Tkinterは右クリック貼り付けできないのでフルパスをフォーカスできるファイラーかpcmanfmでは右クリック-パスをコピーするでテキストエディタに貼り付けてそこからコピーするのがいいでしょう。

Img Fileとdeviceを選択してFLASHボタンをクリックするとxtermに渡すddコマンドの書式が出来上がります。
dd-tool.pyはこの書式を作成しているだけなのでImg File欄に/dev/sdXを記載するとディスクコピーになります。


Yesをクリックするとxtermが起動してddコマンドを実行します。
status=progressで進捗を表示します。


書き込み終了
xtermは終了します。
ターミナルやエディタは使いやすいものに変更するといいでしょう。


プログラム再起動してuuidが変わります。
pcmanfmに古い情報が残っていたらカードを抜き差しで更新

参考 dd-tool.py
# indentに誤りがあったので差替えました。

87             format_exe() (正)
87                 format_exe() (誤)

Orange Pi 3

OrangePi3もRaspberryPiと基本同じですがOrangePi3のオートマウントにはudiskieをインストールしています。フォーマットの際loop中オートマウントが有効になってしまうのでkillallしています。
書き込み後はカードリーダーごと抜き差しで更新します。

def format_exe():
    global dev
    subprocess.run("killall udiskie", shell=True)
    ---
    ---
    subprocess.run("udiskie -F -N &", shell=True)
    messagebox.showinfo('dd tool', "フォーマット完了 FAT32 " + dev)


RaspberryPiはポートを変更しない限りあまりデバイス名は変わらないのですがOrangePi3は再起動やカードの有無でかなり変わってきます。
ダウンロードしたイメージはファイルサーバーのOrangePi3に保存、作成もOrangePi3で実行することが多くなります。
このツールはかなり重宝しています。