setup(000-099)¶
000_write_env_files.sh¶
このスクリプトは、デバイスごとの識別子・ボード種別・GitHub/AWS の資格情報を引数で受け取り、/etc/signage 配下に環境ファイルを生成します。
生成されるのは次の2つです。
/etc/signage/signage.env…… 一般設定(権限 644)/etc/signage/secret.env…… 機密情報(権限 600)
これにより、以後のセットアップスクリプトや systemd サービスが一貫した場所から設定・秘密情報を読み込めるようになります。
また、6番目の任意引数 ASSUME_ROLE_ARN に対応し、指定がなければ自動解決します(詳細は後述)。
実行方法¶
# ルート権限での実行を推奨
sudo bash scripts/setup/000_write_env_files.sh \
<DEVICE_ID> <BOARD_TYPE> <GH_TOKEN> <AWS_ACCESS_KEY_ID> <AWS_SECRET_ACCESS_KEY> [ASSUME_ROLE_ARN]
# 例
sudo bash scripts/setup/000_write_env_files.sh \
XIG-JON-000 jetsonorinnano ghp_xxxxxxxxxxxxxxxxxxxxx \
AKIAxxxxxxxxxxxxxxxx wJalrXUtnFEMI/K7MDENG/bPxRfiCYxxxxxxxx
# 例(ASSUME_ROLE_ARN を明示)
sudo bash scripts/setup/000_write_env_files.sh \
XIG-JON-000 jetsonorinnano ghp_xxxxxxxxxxxxxxxxxxxxx \
AKIAxxxxxxxxxxxxxxxx wJalrXUtnFEMI/K7MDENG/bPxRfiCYxxxxxxxx \
arn:aws:iam::123456789012:role/iot-provisioner-role
/etc/signage/signage.env(権限: 0644) 一般設定を格納します。SIGNAGE_CORE_DIRは実行時の環境変数がそのまま書き込まれます。 また、ASSUME_ROLE_ARNは 引数 > 環境変数 >signage.env.sample> 既定値 の優先度で解決され、出力されます。
# Example environment variables for signage
SIGNAGE_CORE_DIR=<SIGNAGE_CORE_DIR>
DEVICE_ID=<DEVICE_ID>
BOARD_TYPE=<BOARD_TYPE>
NODE_ENV=production
ASSUME_ROLE_ARN=<RESOLVED_ASSUME_ROLE_ARN>
- /etc/signage/secret.env(権限: 0600)
機密情報を格納します。GitHub/AWS 資格情報と、既定リージョン ap-northeast-1 が書き込まれます。
# Secret environment variables for signage
GH_TOKEN=<GH_TOKEN>
AWS_ACCESS_KEY_ID=<AWS_ACCESS_KEY_ID>
AWS_SECRET_ACCESS_KEY=<AWS_SECRET_ACCESS_KEY>
AWS_DEFAULT_REGION=ap-northeast-1
ASSUME_ROLE_ARN の解決ロジック
スクリプト内部では次の順序で ASSUME_ROLE_ARN を決定します(最初に見つかった値を採用):
- コマンド引数(第6引数)
ASSUME_ROLE_ARN - シェル環境変数
ASSUME_ROLE_ARN $ROOT_DIR/signage.env.sampleのASSUME_ROLE_ARN=行- 既定値
arn:aws:iam::<ACCOUNT_ID>:role/iot-provisioner-role
引数の説明¶
| 引数 | 必須 | 例 | 説明 |
|---|---|---|---|
DEVICE_ID |
✅ | XIG-JON-000 |
デバイスの一意な識別子。運用・監視・ログ関連で参照。 |
BOARD_TYPE |
✅ | jetsonorinnano |
ハードウェア種別。後続のセットアップ分岐や最適化に利用。 |
GH_TOKEN |
✅ | ghp_xxx... |
GitHub の PAT(機密)。プライベート取得等に使用。 |
AWS_ACCESS_KEY_ID |
✅ | AKIA... |
AWS アクセスキー ID。 |
AWS_SECRET_ACCESS_KEY |
✅ | wJalrXUtnF... |
AWS シークレットアクセスキー(機密)。 |
ASSUME_ROLE_ARN |
任意 | arn:aws:iam::123456789012:role/iot-provisioner-role |
任意引数。未指定時は上記ロジックで自動解決し、signage.env に書き込み。 |
050_fix_hosts.sh¶
このスクリプトは、現在のホスト名(/etc/hostname)が /etc/hosts に自己解決可能なエントリとして登録されているかを確認し、未登録なら 127.0.1.1 <hostname> を追記します。
Ubuntu/Debian 系で一般的な慣習(127.0.1.1 にホスト名を割り当て)に従い、sudo の遅延や一部ツールの名前解決不良を防止します。
この対応の主目的(よくある症状)
sudo: unable to resolve host <hostname>: Name or service not known
/etc/hostname と /etc/hosts の不整合、または DNS 不達時に発生しやすいエラーを、DNS に依存しない自己解決で回避します。
055_include_usercfg_pi.sh¶
このスクリプトは Raspberry Pi 系ボードでのみ有効になり、起動設定を調整します。
BOARD_TYPEにraspまたはpiを含まない場合は 何もせず終了(安全にスキップ)/boot/firmware/config.txtにinclude usercfg.txtを追記(未設定時)- 同ファイルに
dtoverlay=disable-btを追記(未設定時)
→ 内蔵 Bluetooth を無効化(UART の占有回避や干渉低減などの目的)
なぜ config.txt に書くのか
本実装は 確実性と単純化 を優先して dtoverlay=disable-bt を config.txt へ直接 設定します。
usercfg.txt はユーザー上書き用として include されますが、環境やベンダーイメージによっては読み込み順・優先度が異なる場合があります。
そのため、本リポジトリでは overlay は config.txt に固定し、usercfg.txt は 他のユーザー設定用の拡張ポイント として確保します。
060_enable_uart_pi.sh¶
このスクリプトは Raspberry Pi 系ボードでのみ実行され、UART を確実に使えるようにブート設定を行います(BOARD_TYPE に rasp または pi を含まない場合は安全にスキップ)。
- 対象ファイル:
/boot/firmware/usercfg.txt(無ければ作成) - 次の行を 重複チェックのうえ追記(冪等)
enable_uart=1… 物理 UART を有効化(/dev/serial0を有効に)dtoverlay=disable-bt… 内蔵 Bluetooth を無効化し、PL011 UART を専有させる
Bluetooth を無効化します
dtoverlay=disable-bt により内蔵 Bluetooth は使えなくなります。BT が必要な場合は本行を入れず、代替として dtoverlay=miniuart-bt(BT を mini UART に退避)などを検討してください。
070_install_rtl8188eus.sh¶
このスクリプトは Raspberry Pi 系ボード(BOARD_TYPE に rasp または pi を含む場合)のみ実行され、Realtek RTL8188EUS(USB Wi-Fi)向けの DKMS ドライバ(8188eu) をインストールします。
主な処理は以下のとおりです。
- 非 Pi 環境は安全にスキップ
- 既に
8188euモジュールが存在する場合は 即終了 - ビルド依存関係の導入:
linux-headers-$(uname -r),build-essential,dkms,git - Aircrack-NG の
rtl8188eusリポジトリを取得/更新して /usr/src に配置 dkms add→dkms installで カーネルに適合したモジュールをビルド/導入- 競合回避のため、カーネル同梱の
r8188euを blacklist(/etc/modprobe.d/realtek-blacklist.conf) depmod実行でモジュール依存関係を再生成
Note
DKMS を使うため、カーネル更新後も自動的に再ビルドされます。
既存の r8188eu(in-kernel)と競合するため、ブラックリスト化しています。ロードされるのは 8188eu(DKMS) です。
ヘッダーパッケージについて
本スクリプトは linux-headers-$(uname -r) を前提にしています(Ubuntu for Raspberry Pi 想定)。
環境によっては raspberrypi-kernel-headers が必要な場合があります。
ヘッダ不一致でビルドに失敗する際は、カーネルとヘッダのバージョン整合を確認してください。
071_fix_wifi_names.sh¶
このスクリプトは、起動順やUSBの差し替えで無線IF名がwlan0/wlan1 など変動しないよう、Wi-Fiインタフェースを安定名に固定します。
これにより、ネットワーク設定やサービスで安定参照できるようにします。
内蔵Wi-Fiを wlanINT、USBドングルを wlanUSB にリネームします(systemd .link による MACアドレス固定)。
主な動作:
wl*インタフェースを走査し、/sys/class/net/<if>/device/subsystemから USB接続か否か を判定- ボード種別で要件分岐(例: Raspberry Pi は INT+USB を要求、Jetson は USB 任意)
- 必要IFが揃っていない場合は 安全にスキップ
/etc/systemd/network/00-wifi-int.link,01-wifi-usb.linkを 冪等に生成/更新
内蔵Wi-Fi →
wlanINT
-
検出した内蔵IFのMACに一致した場合、インタフェース名を
wlanINTに固定 -
生成/更新するファイル:
/etc/systemd/network/00-wifi-int.link
USB Wi-Fi →
wlanINT
- 検出したUSB接続IFのMACに一致した場合、インタフェース名を
wlanUSBに固定 - Raspberry Pi: INT+USB の両方が揃っていないとスキップ(要件未充足)
-
Jetson/その他: USBは任意。存在すれば
wlanUSBを設定、無ければ INT のみ設定 -
生成/更新するファイル:
/etc/systemd/network/01-wifi-usb.link
072_wifi_metrics.sh¶
このスクリプトは、USB ドングル(wlanUSB)を主回線、内蔵 Wi-Fi(wlanINT)をバックアップ回線として扱うため、systemd-networkd の .network を生成し 経路メトリック(IPv4RouteMetric)で優先度を固定します。
既定値は METRIC_PRIMARY=50(USB優先), METRIC_BACKUP=100(内蔵バックアップ)ですが、環境変数で上書き可能です。生成後、systemd-networkd を有効化/起動して設定を反映します。
wlanUSB(USBドングル/主回線)
- 生成ファイル:
/etc/systemd/network/wlanUSB.network - 目的: 低いメトリックでデフォルト経路を優先(主回線)
wlanINT(内蔵 Wi-Fi/バックアップ回線)
- 生成ファイル:
/etc/systemd/network/wlanINT.network - 目的: 高いメトリックで待機(主回線ダウン時のみ昇格)
073_setup_journal.sh¶
このスクリプトは、systemd-journald のログを 再起動後も保持(persistent) しつつ、総使用量を 200 MB に制限する設定を適用します。
必要なディレクトリの作成・権限整備、ドロップイン設定の配置、デーモン再起動までを自動化します。
設定内容
1) 永続保存ディレクトリを用意
- 生成:
/var/log/journal - 権限整備:
systemd-tmpfiles --create --prefix /var/log/journal
2) journald ドロップインを配置
- 生成:
/etc/systemd/journald.conf.d/99-persistent-200M.conf -
内容:
[Journal] Storage=persistent SystemMaxUse=200M -
効果:
Storage=persistent… ログを/var/log/journalに永続化SystemMaxUse=200M… 旧ログの自動削除で 総容量を 200 MB 以下に維持
074_lock_snapd.sh¶
このスクリプトは Raspberry Pi 以外のボードで、snapd を 特定バージョン(2.68.5 / rev 24724)に固定し、以降の自動更新を 一時停止(hold) します。
これにより、上位バージョンでの互換性問題を回避します。
BOARD_TYPE に pi / rasp を含む場合は 安全にスキップします。
主な処理:
- 現在の
snapdバージョンを確認し、2.68.5 でなければダウングレード - 指定リビジョン(rev 24724)の
.snap/.assertを ローカルに確保し、snap ack→snap installで ローカルインストール - その後
snap refresh --hold snapdを実行して 自動更新を停止 - スクリプトはカレントディレクトリに
snapd_24724.snap/snapd_24724.assertを生成し(未存在時)、再実行時はそれらを再利用します。
固定されるバージョン/ファイル
- TARGET_VER:
2.68.5 - REVISION:
24724 - 生成物:
snapd_24724.snapsnapd_24724.assert
075_install_awscli.sh¶
このスクリプトは、/etc/signage/secret.env の資格情報を読み込み、AWS CLI をインストール(未導入時)し、aws configure set で 既定プロファイル(default)を設定します。最後に aws sts get-caller-identity で動作確認を行います。
参照する環境変数(/etc/signage/secret.env)
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=wJalrXUtnF...
AWS_DEFAULT_REGION=ap-northeast-1 # 未設定なら ap-northeast-1 を採用
設定内容
- 資格情報の読み込み
set -a; source /etc/signage/secret.env; set +a(環境変数としてエクスポート) - AWS CLI の導入
- 既定プロファイル(default)の設定
設定先は実行ユーザのホーム配下:~/.aws/credentials,~/.aws/config(sudoで実行した場合は/root/.aws/…に書かれます。)
メモ
- プロファイル: 本スクリプトは
defaultを設定します。別名にしたい場合は--profile <name>で再設定してください。 - 権限: サービスから利用する場合、そのサービスが実行されるユーザのホームに資格情報があることを確認してください(例:systemd の
User=)。 - 秘匿性:
~/.aws/credentialsは平文です。ファイル権限(0600 相当)の適切な管理を推奨します。
076_install_fluentbit.sh¶
このスクリプトは Fluent Bit v4 を未導入時にインストールし、systemd-journal・CPU/MEM を収集して S3 と CloudWatch Logs に送信する最小構成を生成・起動します。
あわせて AWS 資格情報を systemd 経由で読み込む override を設定し、バッファ用ディレクトリの権限も整えます。既に導入済みの場合は安全にスキップします。
主要処理
- Fluent Bit の導入(未導入時)
GPG キー配置:/usr/share/keyrings/fluentbit-keyring.gpgAPT リポジトリ追加:/etc/apt/sources.list.d/fluentbit.list(lsb_release -csを二箇所に使用) 旧td-agent-bitの停止・削除(存在時) パッケージfluent-bitをインストール 実行ファイルへのシンボリックリンク:/usr/local/bin/fluent-bit -> /opt/fluent-bit/bin/fluent-bit - 設定ファイル生成
/etc/fluent-bit/fluent-bit.confを上書き生成(ソースコード参照) - systemd override(AWS 認証情報の注入)
/etc/systemd/system/fluent-bit.service.d/override.confに
EnvironmentFile=/etc/signage/secret.envを追加 - バッファ領域の用意
ディレクトリ作成:/var/tmp/fluent-bit/bufferパーミッション:/var/tmp/fluent-bit所有 root:root、bufferをchmod 700
生成/変更されるファイル
- APT 関連
/usr/share/keyrings/fluentbit-keyring.gpg/etc/apt/sources.list.d/fluentbit.list - Fluent Bit 設定
/etc/fluent-bit/fluent-bit.conf -
systemd override
/etc/systemd/system/fluent-bit.service.d/override.conf
内容:[Service] EnvironmentFile=/etc/signage/secret.env -
バッファ
/var/tmp/fluent-bit/buffer(700) - (存在時に削除)
パッケージtd-agent-bit
注意
- AWS 資格情報の前提:
/etc/signage/secret.envにAWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY(任意でAWS_DEFAULT_REGION)が定義されていること。Fluent Bit は systemd の override(EnvironmentFile=/etc/signage/secret.env)で読み込みます。 - S3 バケット/権限:
xignage-logsが存在し、PutObject できる IAM 権限があること。 - CloudWatch Logs 権限: ロググループ
/xignage/fluentbitを作成・書き込み可能な権限があること(auto_create_group On)。 - 環境依存文字列:
s3_key_formatの${HOSTNAME}/$(hostname)の展開は環境に依存します。必要に応じて固定値や$TAGなどへの置換を検討してください。 - リージョン: 本設定は
ap-northeast-1に固定。変更する場合は設定ファイルと資格情報のリージョン整合を確認してください。 - 旧エージェントとの競合:
td-agent-bitは削除します。共存不可のため、既存設定があればバックアップしてから実行してください。
080_initial_setup.sh¶
このスクリプトは、ベース OS の初期設定を一括で行います。主な内容は パッケージ更新と依存導入、Python/pip 依存の導入、タイムゾーンとロケール設定、時刻同期サービスの有効化、不要サービスの無効化、Wi-Fi supplicant 設定ファイルの用意、DNS リゾルバの固定化(immutable)、疎通確認 です。
Raspberry Pi の場合は追加で deps/pip-raspi.txt を導入します。
処理の流れ
1) APT 更新と依存パッケージの導入
- Raspberry Pi のときは、追加で pip-raspi.txt に記載のものも。
2) タイムゾーン & ロケール設定
- Asia/Tokyo
- ja_JP.UTF-8
3) 時刻同期サービス
- chrony.service が有効なら timesyncd はスキップ
- 無ければ systemd-timesyncd を enable --now(存在しない場合は警告)
- timedatectl set-ntp true → timedatectl timesync-status(可能なら)
- 併せて chrony を enable/start(失敗は無視して継続)
4) 不要サービスの無効化
- systemd-resolved
- systemd-networkd-wait-online
- resolvconf.service
5) Wi-Fi supplicant 設定ファイルの用意
- 各 IFACE(例:wlanINT, wlanUSB)について
- /etc/wpa_supplicant/wpa_supplicant-<IFACE>.conf を 存在しなければ作成
- 所有者:$USERNAME:$USERNAME、権限:664
6) DNS リゾルバの固定化(ハードニング)
- ${RESOLV_FILE} を削除後に ${TARGET_NS} を追記
- chattr +i ${RESOLV_FILE} で immutable 化(再生成・上書きを防止)
7) 疎通確認
- ping -c 3 google.com
注意・運用上のポイント
- アップグレード:
apt-get upgrade -yはカーネルや重要コンポーネントも更新する可能性があります。運用環境ではメンテナンスウィンドウでの実行を推奨します。 - DNS 固定化:
${RESOLV_FILE}を immutable にするため、NetworkManager / systemd-resolved / resolvconf などが後から上書きできなくなります。変更が必要なときは一時的にchattr -i ${RESOLV_FILE}を実行してください。 - 時刻同期の重複:
chronyとsystemd-timesyncdは 併用しないのが原則です。本スクリプトはchronyを優先し、無い場合のみ timesyncd を使用します。 - wpa_supplicant の実動作: 本スクリプトは 空の conf ファイルを用意するだけです。実際の接続設定(SSID/PASSPHRASE)とサービス起動(例:
wpa_supplicant@<IFACE>.service)は別途行います。
081_install_jetson_deps.sh¶
Jetson 専用の依存導入スクリプトです。/etc/nv_tegra_release の存在で Jetson を判定し、非 Jetson では安全にスキップします。
Jetson 向けの APT / PIP 依存を入れるための骨組みで、現状はインストール処理のログ出力のみ。pip-jetson.txt を使う行は コメントアウトされています(必要に応じて有効化)。
Note
現在はコメントアウトされているので、pip-jetson.txt の使用を有効化する場合はスクリプト内のコメントを外してください。
085_enable_led_gpio18.sh¶
このスクリプトは Raspberry Pi 系ボードのみ実行され、ブート時に GPIO18(BCM18, 物理ピン12)を出力・High に初期化します。
これにより、電源投入直後から 電源ボタンのLEDを 即時点灯(High) させます。
/boot/firmware/usercfg.txt に次の行を 重複チェックのうえ追記(冪等)します。
op: output(出力)dh: drive-high(High で駆動)
補足
- 本スクリプトは Ubuntu for Raspberry Pi のパス構成(/boot/firmware/)前提です。Raspberry Pi OS では /boot/ の場合があります。
- Low 始動にしたい場合は gpio=18=op,dl(drive-low)に変更してください。
086_install_gpio_button_shutdown_service.sh¶
Raspberry Pi 系のみで有効化される、長押しシャットダウン用のボタンハンドラをセットアップします。
Python スクリプトを所定パスへ配置(リンク/コピー)し、systemd ユニット gpio-button-shutdown.service を作成・有効化します。
BOARD_TYPE に rasp / pi を含まない場合は 安全にスキップします。
- GPIO ピン番号は固定ではありません。既定は BCM 3(物理ピン 5)ですが、
/etc/signage/io.envの環境変数で上書き可能です。
生成/変更されるファイル
- /usr/local/bin/gpio_button_shutdown.py
- ソースファイル:
scripts/power/gpio_button_shutdown.py - 配置方法:
install_or_linkにより シンボリックリンク or コピー(冪等) - /etc/systemd/system/gpio-button-shutdown.service(systemd ユニット)
環境変数(/etc/signage/io.env)¶
# 例:既定(BCM3)から変更したい場合に上書き
SHUT_BTN_BCM=3 # 使用するボタンの BCM 番号(整数)
SHUT_BTN_HOLD_MS=2000 # 長押し判定ミリ秒(例)
補足
- I²C との競合(既定が BCM 3 の場合): BCM3 は I²C1 の SDA ピンです。I²C を使用する構成では、本機能と競合する可能性があります。
SHUT_BTN_BCMを別ピンに変更するか、I²C の利用有無を再確認してください。 - 電源オフからの起動(wake): これは 稼働中の安全なシャットダウンを扱う仕組みです。電源断状態からの起動トリガーはカーネルの
gpio-shutdownオーバーレイ等、別機構の設定が必要です。
087_enable_gpio_shutdown_overlay.sh¶
このスクリプトは Raspberry Pi 系ボードのみ実行され、電源ボタン用のデバイスツリー・オーバーレイを config.txt に設定して、GPIO ピンでの安全なシャットダウン/起動(wake)を有効化します。
既存の gpio-shutdown 設定行は一旦削除し、下記の 統一行 を追記します(冪等)。
ピン/論理について
上記は BCM 23(物理ピン 16) を対象に、active-low(押下で GND に落ちる想定)かつ 内部プルダウンを有効にする設定です。配線やスイッチの極性に応じて active_low / gpio_pull の値は調整してください。
例)通常のプッシュスイッチで 3.3V に「離すと High / 押下で GND」なら active_low=1,gpio_pull=up が一般的です。
090_symlink_initial.sh¶
このスクリプトは、$SIGNAGE_JETSON_DIR 配下の current シンボリックリンクを、常に releases/initial を指すように更新します。
ln -sfn を用いて 既存リンクを強制置換(冪等・安全)します。サービスやスクリプトが current を固定パスとして参照する前提のディレクトリ構成で利用します。
フラグの意味
-s:シンボリックリンクを作成-f:既存のファイル/リンクを強制置換-n:リンクがディレクトリを指していても追従せずリンク自体を置換