Raspberry Pi + Yocto + RAUC + hawkbitでOTAアップデートの実装
作りたいもの
こちらのポータブルエッジサーバをOTAアップデートする仕組みを実装します。最新に近いバージョンの情報が少なかったので、実装課程を共有します。具体的には以下のものを実装します。
なお、今回は実運用では無くローカルネットワーク上の実験のため、クラウドコストをかけずにアップデート配信サーバにもRasPiを使用しましたが、コンテナ化しているのでクラウド環境にも載せやすいと思います。
ポータブルエッジサーバ側:
- Yocto: 5.0 (scarthgap)
- LTSバージョンであることと、meta-rauc-communityにあるブランチがscarthgapまでだったため
- RAUC(meta-rauc): scarthgapブランチのHEAD
- rauc本体(アップデートバンドルを予備パーティションに書き込み、ブートパーティションをを切り替え)
- rauc-hawkbit-updater(hawkbit-update-serverからアップデートバンドルをダウンロードしてrauc本体を起動する常駐サービス)
- アップデートバンドルを作る仕組み
- など
- Raspberry Pi BSPへのパッチ(meta-rauc-community/meta-rauc-raspberrypi): scarthgapブランチのHEAD
- ブートローダをu-bootにしてA/B(現用・予備)パーティション起動
- パーティションテーブル
- など
アップデート配信サーバ側:
- RasPi OS(Yoctoではないです)
- docker compose(実験なのでdocker composeでコンテナ群を実行します)
- bithawk-update-server: 0.8.0
- 最新の0.9.0ではエラーでtargetの作成ができなかったため(バグ?)
- bithawk-simple-ui: 0.8.0
- bithawk 0.5.0からWeb UIが削除され、独立したコンポーネントとなりました。Experimentalだそうです。
- など
- bithawk-update-server: 0.8.0
- docker compose(実験なのでdocker composeでコンテナ群を実行します)
※hawkbitは構成をモノリシック・マイクロサービスから選べるようです。マイクロサービスの構成の場合、はDDI (Direct Device Integration)、DMF(Device Management Federation)、Managementの機能をマイクロサービス化します。今回はモノリシックな構成を使いましたが、スケーリングするにはDDIのインスタンスを増やした方が良いのでしょうね。この記事によるとDDIはhawkbitが直接デバイスと通信してアップデートを配信する方式、DMFは既存のdevice management機能(OMA-DMとか)と統合してDM経由でアップデートを配信する方式だそうです。なお、下図のManagement UIは0.5.0以降削除されています。
動作する全ソースコードをGitHubで公開しています。
[scarthgap向け変更のみ]実装
ポータブルエッジサーバ側
ベースのYocto
こちらを参照してください。ブランチはscarthgap(pokyはscarthgap-5.0)に変更します。meta-sample*ではwalnascar向けからscarthgap向けに、主に2点変更しています。
- .bbファイルのUNPACKDIRはscarthgapでは使用できないので
S=${WORKDIR}
に変更。
S = "${WORKDIR}/sources"
UNPACKDIR = "${S}"
S = "${WORKDIR}"
- 不足するPythonパッケージ(starlette, tzdata)を追加
git clone -b scarthgap-5.0 git://git.yoctoproject.org/poky
git clone -b scarthgap git://git.yoctoproject.org/meta-raspberrypi
git clone -b scarthgap git://git.openembedded.org/meta-openembedded
git clone -b scarthgap git://git.yoctoproject.org/meta-virtualization
git clone -b scarthgap git@github.com:takumique/build-sample.git
git clone -b scarthgap git@github.com:takumique/meta-sample-ui.git
git clone -b scarthgap git@github.com:takumique/meta-sample-connectivity.git
git clone -b scarthgap git@github.com:takumique/meta-sample.git
また、IMAGE_ROOTFS_EXTRA_SPACE
による空き容量の確保は10GBに変更します。(パーティションを2つ作るので容量が変わるため)
# add 10GiB of extra space (fits for 64GB SD card)
IMAGE_ROOTFS_EXTRA_SPACE = "1048576"
meta-rauc/meta-rauc-communityのインテグレーション
必要となるレイヤをダウンロードします。
git clone -b scarthgap https://github.com/rauc/meta-rauc.git
git clone -b scarthgap https://github.com/rauc/meta-rauc-community.git
bblayers.confに以下のレイヤを追加します。
${TOPDIR}/../meta-openembedded/meta-filesystems \
${TOPDIR}/../meta-rauc \
${TOPDIR}/../meta-rauc-community/meta-rauc-raspberrypi \
GitHubのREADMEに従ってlocal.confに以下を追加していきます。
# enable u-boot
RPI_USE_U_BOOT = "1"
DISTRO_FEATURES:append = " rauc"
IMAGE_FSTYPES:append = " ext4"
CORE_IMAGE_EXTRA_INSTALL:append = " rauc"
CORE_IMAGE_EXTRA_INSTALL:append = " rauc-hawkbit-updater"
WKS_FILE = "sdimage-dual-raspberrypi.wks.in"
このバージョンの組み合わせでは、meta-rauc-community/meta-rauc-raspberrypiのu-bootのパッチがあたらずエラーとなってしまいました。仕方が無いのでmeta-rauc-community/meta-rauc-raspberrypi/recipes-bsp/u-boot/files/rpi_arm64_defconfig.patchを以下のように手動で変更しました。
Upstream-Status: Inappropriate [manually created]
--- git.orig/configs/rpi_arm64_defconfig
+++ git/configs/rpi_arm64_defconfig
@@ -57,3 +57,6 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_BCM2835=y
CONFIG_CONSOLE_SCROLL_LINES=10
CONFIG_PHYS_TO_BUS=y
+# squashfs support
+CONFIG_FS_SQUASHFS=y
+CONFIG_CMD_SQUASHFS=y
デバイス固有値のハンドリング
こちらの記事でNVRAM(EEPROMデバイスを使ったKey-Valueストア)を実装しました。これを使用してデバイス固有の情報(デバイスIDや、デバイスごとに異なる認証情報など)をハンドリングします。
今回はrauc_hawkbit_updaterのコンフィグをNVRAMの情報を使用してoverrideします。
- hawkbit_server
- target_name
- auth_token
具体的にはType=oneshot
、Before=rauc-hawkbit-updater.service
のsystemd-serviceを作成し、シェルスクリプトを実行します。このシェルスクリプトからnvram-read
でNVRAMからデバイス固有値を取得して/etc/rauc-hawkbit-updater/config.conf
を更新することで、NVRAMの内容を動作に反映させます。
なお、nvram-readはI2Cを使用するのでI2Cをenableします。ボーレートは100KHzにしました。
この部分の動作する全ソースコードをGitHubで公開しています。Yoctoに組み込むための設定は以下の通りです。
git clone -b scarthgap git@github.com:takumique/meta-sample-bsp.git
${TOPDIR}/../meta-sample-bsp \
# enable interfaces
ENABLE_UART = "1"
ENABLE_I2C = "1"
KERNEL_MODULE_AUTOLOAD:rpi += "i2c-dev"
...
RPI_EXTRA_CONFIG:append = "dtparam=i2c_arm_baudrate=100000"
...
CORE_IMAGE_EXTRA_INSTALL:append = " libnvram"
CORE_IMAGE_EXTRA_INSTALL:append = " nvram-read"
CORE_IMAGE_EXTRA_INSTALL:append = " rauc-hawkbit-updater-config"
ビルド
通常通りビルドします。この際、raucをインテグレーションする前のビルド生成物が存在するとエラーとなるので、手動で削除してからビルドします。
cd <build>
rm -fr cache
rm -fr conf/downloads
rm -fr conf/sstate-cache
rm -fr conf/tmp
rm -f bitbake-cookerdaemon.log
bitbake core-image-base
こちらにあるようにSDカードにフラッシュします。
アップデート配信サーバ側
まずは普通にRasPi OSをSDカードに焼きます。
その後、RasPi上で普通にdockerをインストールします。
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo gpasswd -a $USER docker
hawkbitはdockerhub上にイメージがあるのですが、x86用のみなのでRasPi上では動きません。そこでGitHubにあるDockerfileをベースにしてイメージをビルドします。(ベースイメージのeclipse-temurinがARM対応なのでいけます)今回はmetadataの保存にmysqlを使います。
hawkbit-update-server
このDockerfile、jarファイルをmavenのリポジトリからダウンロードして配置しているだけなのですが、MariaDBのJDBCドライバがインストールされないためmysqlと通信できません。Dockerfileを修正します。また、今回はdockerfileでvolumeをマウントしたいので、簡単のためhawkbitをrootで実行させています。
# set Java
ARG JAVA_VERSION=21.0.8_9
# extracts spring layers from the app jar (to optimize boot)
FROM eclipse-temurin:${JAVA_VERSION}-jre-alpine as build
ARG HAWKBIT_APP=hawkbit-update-server
ARG HAWKBIT_VERSION=pass_as_buils_arg
ENV BUILD_DIR=/opt/hawkbit_build
RUN mkdir -p ${BUILD_DIR}
WORKDIR ${BUILD_DIR}
ENV APP=${HAWKBIT_APP}
ENV VERSION=${HAWKBIT_VERSION}
COPY KEY /
RUN set -x && \
apk add --no-cache --virtual build-dependencies gnupg unzip libressl wget && \
gpg --import /KEY && \
wget -O /${APP}.jar --no-verbose https://repo1.maven.org/maven2/org/eclipse/hawkbit/${APP}/${VERSION}/${APP}-${VERSION}.jar && \
wget -O /${APP}.jar.asc --no-verbose https://repo1.maven.org/maven2/org/eclipse/hawkbit/${APP}/${VERSION}/${APP}-${VERSION}.jar.asc && \
gpg --batch --verify /${APP}.jar.asc /${APP}.jar && \
java -Djarmode=tools -jar /${APP}.jar extract --layers --launcher --destination . && \
rm /KEY /${APP}.jar /${APP}.jar.asc
RUN wget -O ./dependencies/BOOT-INF/lib/mariadb-java-client-3.4.2.jar --no-verbose https://repo1.maven.org/maven2/org/mariadb/jdbc/mariadb-java-client/3.4.2/mariadb-java-client-3.4.2.jar
FROM eclipse-temurin:${JAVA_VERSION}-jre-alpine
# RUN addgroup -S hawkbit_group && adduser -D hawkbit -G hawkbit_group
# RUN mkdir -p /artifactrepo && chown -R hawkbit /artifactrepo
# USER hawkbit
ENV BUILD_DIR=/opt/hawkbit_build
COPY --from=build ${BUILD_DIR}/dependencies/ /
COPY --from=build ${BUILD_DIR}/spring-boot-loader/ /
COPY --from=build ${BUILD_DIR}/snapshot-dependencies/ /
COPY --from=build ${BUILD_DIR}/application/ /
# VOLUME "/artifactrepo"
ARG CONTAINER_PORT=8080
EXPOSE ${CONTAINER_PORT}
ARG PROFILES=h2
ENV PROFILES=${PROFILES}
ARG X_MS=768m
ENV X_MS=${X_MS}
ARG X_MX=768m
ENV X_MX=${X_MX}
ARG XX_MAX_METASPACE_SIZE=250m
ENV XX_MAX_METASPACE_SIZE=${XX_MAX_METASPACE_SIZE}
ARG XX_METASPACE_SIZE=250m
ENV XX_METASPACE_SIZE=${XX_METASPACE_SIZE}
ARG XSS=300K
ENV XSS=${XSS}
ARG GC=G1
ENV GC=${GC}
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -Dspring.profiles.active=${PROFILES} -Xms${X_MS} -Xmx${X_MX} -XX:MaxMetaspaceSize=${XX_MAX_METASPACE_SIZE} -XX:MetaspaceSize=${XX_METASPACE_SIZE} -Xss${XSS} -XX:+Use${GC}GC -XX:+UseStringDeduplication -XX:+UseCompressedOops -XX:+HeapDumpOnOutOfMemoryError org.springframework.boot.loader.launch.JarLauncher ${@}"]
hawkbit-simple-ui
こちらはお手本のDockerfileがないので自前で作る必要があります。幸い、これもhawkbit-update-serverと同じくSpring Bootベースなので上記Dockerfileをベースにします。なお、JDBCドライバは不要です。
# set Java
ARG JAVA_VERSION=21.0.8_9
# extracts spring layers from the app jar (to optimize boot)
FROM eclipse-temurin:${JAVA_VERSION}-jre-alpine AS build
ARG HAWKBIT_APP=hawkbit-simple-ui
ARG HAWKBIT_VERSION=pass_as_buils_arg
ENV BUILD_DIR=/opt/hawkbit_build
RUN mkdir -p ${BUILD_DIR}
WORKDIR ${BUILD_DIR}
ENV APP=${HAWKBIT_APP}
ENV VERSION=${HAWKBIT_VERSION}
COPY KEY /
RUN set -x && \
apk add --no-cache --virtual build-dependencies gnupg unzip libressl wget && \
gpg --import /KEY && \
wget -O /${APP}.jar --no-verbose https://repo1.maven.org/maven2/org/eclipse/hawkbit/${APP}/${VERSION}/${APP}-${VERSION}.jar && \
wget -O /${APP}.jar.asc --no-verbose https://repo1.maven.org/maven2/org/eclipse/hawkbit/${APP}/${VERSION}/${APP}-${VERSION}.jar.asc && \
gpg --batch --verify /${APP}.jar.asc /${APP}.jar && \
java -Djarmode=tools -jar /${APP}.jar extract --layers --launcher --destination . && \
rm /KEY /${APP}.jar /${APP}.jar.asc
FROM eclipse-temurin:${JAVA_VERSION}-jre-alpine
RUN addgroup -S hawkbit_group && adduser -D hawkbit -G hawkbit_group
RUN mkdir -p /artifactrepo && chown -R hawkbit /artifactrepo
USER hawkbit
ENV BUILD_DIR=/opt/hawkbit_build
COPY --from=build ${BUILD_DIR}/dependencies/ /
COPY --from=build ${BUILD_DIR}/spring-boot-loader/ /
COPY --from=build ${BUILD_DIR}/snapshot-dependencies/ /
COPY --from=build ${BUILD_DIR}/application/ /
ARG CONTAINER_PORT=8088
EXPOSE ${CONTAINER_PORT}
ARG X_MS=768m
ENV X_MS=${X_MS}
ARG X_MX=768m
ENV X_MX=${X_MX}
ARG XX_MAX_METASPACE_SIZE=250m
ENV XX_MAX_METASPACE_SIZE=${XX_MAX_METASPACE_SIZE}
ARG XX_METASPACE_SIZE=250m
ENV XX_METASPACE_SIZE=${XX_METASPACE_SIZE}
ARG XSS=300K
ENV XSS=${XSS}
ARG GC=G1
ENV GC=${GC}
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -Xms${X_MS} -Xmx${X_MX} -XX:MaxMetaspaceSize=${XX_MAX_METASPACE_SIZE} -XX:MetaspaceSize=${XX_METASPACE_SIZE} -Xss${XSS} -XX:+Use${GC}GC -XX:+UseStringDeduplication -XX:+UseCompressedOops -XX:+HeapDumpOnOutOfMemoryError org.springframework.boot.loader.launch.JarLauncher ${@}"]
compose.yaml
上記をビルド・起動するためのcompose.yamlです。SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE
はアップロードするアップデートバンドルファイルの最大サイズです。とりあえず1024MBにしておきました。
services:
hawkbit-update-server:
build:
context: ./hawkbit-update-server
dockerfile: Dockerfile
args:
HAWKBIT_VERSION: 0.8.0
# image: hawkbit/hawkbit-update-server:0.8.0
environment:
- 'PROFILES=mysql'
- 'SPRING_DATASOURCE_URL=jdbc:mariadb://mysql:3306/hawkbit?allowPublicKeyRetrieval=true'
- 'SPRING_DATASOURCE_USERNAME=root'
- 'SPRING_DATASOURCE_PASSWORD=password'
- 'SPRING_RABBITMQ_HOST=rabbitmq'
- 'SPRING_RABBITMQ_PORT=5672'
- 'SPRING_RABBITMQ_VIRTUALHOST=/'
- 'SPRING_RABBITMQ_USERNAME=guest'
- 'SPRING_RABBITMQ_PASSWORD=guest'
ports:
- 8080:8080
volumes:
- ./hawkbit-artifactrepo:/artifactrepo
depends_on:
mysql:
condition: service_healthy
rabbitmq:
condition: service_started
restart: unless-stopped
hawkbit-simple-ui:
build:
context: ./hawkbit-simple-ui
dockerfile: Dockerfile
args:
HAWKBIT_VERSION: 0.8.0
# image: hawkbit/hawkbit-simple-ui:0.8.0
environment:
- 'SPRING_APPLICATION_JSON={"hawkbit.server.mgmtUrl": "http://hawkbit-update-server:8080"}'
- 'SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE=1024MB'
- 'SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE=1024MB'
ports:
- 8088:8088
depends_on:
hawkbit-update-server:
condition: service_started
restart: unless-stopped
mysql:
image: mysql:9.4
environment:
- 'MYSQL_ROOT_HOST=%'
- 'MYSQL_ROOT_PASSWORD=password'
- 'MYSQL_DATABASE=hawkbit'
- 'MYSQL_USER=hawkbit'
- 'MYSQL_PASSWORD=password'
- 'MYSQL_TCP_PORT=3306'
ports:
- 3306:3306
volumes:
- ./mysql-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "--user=root", "--password=password"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
restart: unless-stopped
rabbitmq:
image: rabbitmq:4-management-alpine
environment:
- 'RABBITMQ_DEFAULT_VHOST=/'
- 'RABBITMQ_DEFAULT_USER=guest'
- 'RABBITMQ_DEFAULT_PASS=guest'
ports:
- 15672:15672
- 5672:5672
restart: unless-stopped
これをdocker compose up --build
すればサーバが起動します。(データベースのスキーマのマイグレーションがあり時間がかかります。ログに下記のように出るまで待ちます。)
hawkbit-update-server-1 | 2025-08-07T04:08:11.796Z INFO 1 --- [update-server] [:] [ main] org.eclipse.hawkbit.app.Start : Started Start in 88.196 seconds (process running for 91.506)
操作
※hawkbit-simple-uiの画面はExperimentalだからか、あまり洗練されていません。
1: アップデート配信サーバ側の初期設定とターゲットデバイス登録
ログインと設定
ブラウザでhttp://<アップデート配信サーバのIP>:8088/
を開いて、hawkbit-simple-uiのログイン画面を表示します。ディフォルトのユーザ/パスはadmin/adminです。
後述のSecurity Tokenで認証を行うため、この認証フローをenableにする設定をします。左のメニューからConfigを選択、authentication.targettoken.enabledをチェックし、下の方にある[Save]ボタンを押します。
Targetの作成
左のメニューからTargetsを選択、右下の[+]ボタンを押します。Register Targetポップアップが表示されるのでController IDにデバイス毎にユニークなIDを入力します。ここではtest-targetです。
登録できました。リストのアイテムをクリックすると詳細が表示されます。
このController IDおよびSecurity Tokenがデバイス固有値となります。これをデバイスに設定する必要があります。(後述のStep 2)
Filterの作成
Filterは登録された全デバイスのサブセットとなるデバイス群を定義します。このデバイス群ごとにアップデートを配信するので、機種・仕向け等ごとなどでデバイス群を作ります。
後ほどRolloutの登録に必要なので設定しておきます。Raw Filterの入力にパターンを入力して右のセーブボタンを押すと保存されます。
パターンの書式はここに書いてあります。私はシンプルにname==test-target
で登録しました。
2: ポータブルエッジサーバ側にターゲットデバイスの登録内容を反映
起動させる
通常通り起動するだけです。rauc status
コマンドでA/Bどちらのパーティションから起動しているかわかります。
=== System Info ===
Compatible: raspberrypi3-64
Variant:
Booted from: rootfs.0 (A)
=== Bootloader ===
Activated: rootfs.1 (B)
=== Slot States ===
x [rootfs.1] (/dev/mmcblk0p3, ext4, inactive)
bootname: B
boot status: good
o [rootfs.0] (/dev/mmcblk0p2, ext4, booted)
bootname: A
mounted: /
boot status: good
デバイス固有値の設定
こちらの記事でNVRAM(EEPROMデバイスを使ったKey-Valueストア)を実装しました。nvram-writeを使用してデバイス固有の情報(デバイスIDや、デバイスごとに異なる認証情報など)をEEPROMデバイスに書き込みます。
まずは書き込みたいKey-Valueを格納したjsonファイルを作成します。hawkbit_server
に<アップデート配信サーバのIP>:8088を設定、target_name
およびauth_token
に前述のController IDおよびSecurity Tokenをコピペします。
{
"hawkbit_server": "192.168.1.201:8080",
"target_name": "test-target",
"auth_token": "hoge"
}
このjsonファイルを使ってEEPROMに書き込むのにnvram-write
コマンドを使用します。
nvram-write -v -c test.json
ログを表示しておく
アップデートの様子を確認するため、rauc-hawkbit-updaterのログを表示します。
journalctl -u rauc-hawkbit-updater -f
3: アップデートバンドルの準備
Yoctoのビルドホストでの作業となります。何かソフトを変更して、以下のコマンドで作成できます。(ソフトは変更しなくてもOKです。アップデート後のソフトは何も変わりませんが。)
bitbake update-bundle
アップデートバンドル(squashfsイメージ)が出来上がるので、分かりやすいところにコピーしておきます。差分では無いのでそれなりに大きいです。
cp ./tmp/deploy/images/raspberrypi3-64/update-bundle-raspberrypi3-64.raucb ~
4: アップデート配信サーバ側でアップデートバンドルの配信を登録
Software Moduleの作成
左のメニューからSoftware Modulesを選択、右下の[+]ボタンを押します。Create Software Moduleポップアップが表示されるのでType, Name, Versionを入力します。ここではOS, test-software-module, 1です。
[Create]ボタンを押すと、続いて対象のファイルをアップロードします。
アップロードが完了したら[Finish]ボタンを押します。リストに登録されました。
Distribution Setの作成
一度に配信したい複数のSoftware Modulesを束ねたものがDistribution Setです。これを作ります。
左のメニューからDistribution Setsを選択、右下の[+]ボタンを押します。Create Distribution Setポップアップが表示されるのでType, Name, Versionを入力します。ここではOS only, test-distribution-set, 1です。
[Create]ボタンを押すと、続いて対象のSoftware Moduleを選択します。[+]ボタンを押します。
先ほど作成したtest-software-moduleを追加します。
最後に[Finish]ボタンを押します。リストに登録されました。
Rolloutの作成
最後に配信イベントであるRolloutを登録します。
左のメニューからRolloutsを選択、右下の[+]ボタンを押します。Create Rolloutポップアップが表示されるので名前、Distribution Set、1で作成したFilterを入力し、[Create]ボタンを押します。(なおStart TypeはManualにしておきます)リストに登録されました。
直後のStatusはcreating
で、これがready
になると配信できるのですが、自動では表示が更新されません。ちょっと待ってからブラウザのページの再読込をするとready
になり、配信開始ボタンが表示されると思います。(Start TypeをManualにしたのでこのボタンでスタート)
配信開始ボタンを押すとStatusがrunning
になり、配信が開始されます。
5: ポータブルエッジサーバ側のアップデートを確認
配信のチェックはディフォルトで10分間核で行われます。2のログがこのようになります。
Aug 07 01:48:51 raspberrypi3-64 rauc-hawkbit-updater[356]: Checking for new software...
Aug 07 01:48:51 raspberrypi3-64 rauc-hawkbit-updater[356]: No new software.
Aug 07 01:53:52 raspberrypi3-64 rauc-hawkbit-updater[356]: Checking for new software...
Aug 07 01:53:52 raspberrypi3-64 rauc-hawkbit-updater[356]: New software ready for download (Name: test-target, Version: 1, Size: 58115952 bytes, URL: http://192.168.1.4:8080/DEFAULT/controller/v1/test-target/softwaremodules/1/artifacts/update-bundle-raspberrypi3-64.raucb)
Aug 07 01:53:52 raspberrypi3-64 rauc-hawkbit-updater[356]: Start downloading: http://192.168.1.4:8080/DEFAULT/controller/v1/test-target/softwaremodules/1/artifacts/update-bundle-raspberrypi3-64.raucb
Aug 07 01:53:55 raspberrypi3-64 rauc-hawkbit-updater[356]: Download complete. 35.46 MB/s
Aug 07 01:53:55 raspberrypi3-64 rauc-hawkbit-updater[356]: File checksum OK.
Aug 07 01:53:55 raspberrypi3-64 rauc-hawkbit-updater[356]: Installing: /tmp/bundle.raucb : installing
Aug 07 01:53:55 raspberrypi3-64 rauc-hawkbit-updater[356]: installing
Aug 07 01:53:55 raspberrypi3-64 rauc-hawkbit-updater[356]: Installing: /tmp/bundle.raucb : 0% Installing
Aug 07 01:53:55 raspberrypi3-64 rauc-hawkbit-updater[356]: 0% Installing
Aug 07 01:53:55 raspberrypi3-64 rauc-hawkbit-updater[356]: Installing: /tmp/bundle.raucb : 0% Determining slot states
Aug 07 01:53:55 raspberrypi3-64 rauc-hawkbit-updater[356]: 0% Determining slot states
Aug 07 01:53:55 raspberrypi3-64 rauc-hawkbit-updater[356]: Installing: /tmp/bundle.raucb : 10% Determining slot states done.
Aug 07 01:53:55 raspberrypi3-64 rauc-hawkbit-updater[356]: 10% Determining slot states done.
Aug 07 01:53:55 raspberrypi3-64 rauc-hawkbit-updater[356]: Installing: /tmp/bundle.raucb : 10% Checking bundle
Aug 07 01:53:55 raspberrypi3-64 rauc-hawkbit-updater[356]: 10% Checking bundle
Aug 07 01:53:55 raspberrypi3-64 rauc-hawkbit-updater[356]: Installing: /tmp/bundle.raucb : 10% Verifying signature
Aug 07 01:53:55 raspberrypi3-64 rauc-hawkbit-updater[356]: 10% Verifying signature
...
Aug 07 01:54:03 raspberrypi3-64 rauc-hawkbit-updater[356]: Installing: /tmp/bundle.raucb : 99% Copying image to rootfs.1
Aug 07 01:54:03 raspberrypi3-64 rauc-hawkbit-updater[356]: 99% Copying image to rootfs.1
Aug 07 01:54:16 raspberrypi3-64 rauc-hawkbit-updater[356]: Installing: /tmp/bundle.raucb : 99% Copying image to rootfs.1 done.
Aug 07 01:54:16 raspberrypi3-64 rauc-hawkbit-updater[356]: 99% Copying image to rootfs.1 done.
Aug 07 01:54:16 raspberrypi3-64 rauc-hawkbit-updater[356]: Installing: /tmp/bundle.raucb : 99% Updating slots done.
Aug 07 01:54:16 raspberrypi3-64 rauc-hawkbit-updater[356]: 99% Updating slots done.
Aug 07 01:54:16 raspberrypi3-64 rauc-hawkbit-updater[356]: Installing: /tmp/bundle.raucb : 100% Installing done.
Aug 07 01:54:16 raspberrypi3-64 rauc-hawkbit-updater[356]: 100% Installing done.
Aug 07 01:54:16 raspberrypi3-64 rauc-hawkbit-updater[356]: Installing: /tmp/bundle.raucb : idle
Aug 07 01:54:16 raspberrypi3-64 rauc-hawkbit-updater[356]: idle
Aug 07 01:54:16 raspberrypi3-64 rauc-hawkbit-updater[356]: Software bundle installed successfully.
rauc status
はこのようになりました。
=== System Info ===
Compatible: raspberrypi3-64
Variant:
Booted from: rootfs.1 (B)
=== Bootloader ===
Activated: rootfs.1 (B)
=== Slot States ===
x [rootfs.1] (/dev/mmcblk0p3, ext4, booted)
bootname: B
mounted: /
boot status: good
o [rootfs.0] (/dev/mmcblk0p2, ext4, inactive)
bootname: A
boot status: good
再起動します。するとBパーティションから起動し、rauc status
はこのようになります。
=== System Info ===
Compatible: raspberrypi3-64
Variant:
Booted from: rootfs.1 (B)
=== Bootloader ===
Activated: rootfs.1 (B)
=== Slot States ===
x [rootfs.1] (/dev/mmcblk0p3, ext4, booted)
bootname: B
mounted: /
boot status: good
o [rootfs.0] (/dev/mmcblk0p2, ext4, inactive)
bootname: A
boot status: good
これでOTAアップデートが完了しました。
Discussion