以下のような場合、FreeBSD をアップグレードすることは簡単ではないはずです。
- Raspberry Pi のように freebsd-update でサポートされない Tier 2 プラットフォーム
- なおかつ、リモート環境など、 OS がインストールされている micro SD カードなどを物理的に扱うことができない環境
- buildworld しようにもメモリもディスクも容量が足りない環境
このような場合、最近では別環境でビルドしたベースパッケージを使ってアップグレードをするという方法があります。
前提
amd64, Raspberry Piの各モデル向けに各OSトレインのベースパッケージを作成する。
ビルドマシン
- AMD64
- 8vCPU
- 8GB程度のメモリ
- 200GB以上の高速なディスク
- FreeBSD 12.2-RELEASE
所要時間の目安として、一つのOSトレイン一つのアーキテクチャ向けベースパッケージを作成すると当方の環境では30分弱程度かかりました。
ソースツリーのアップデート
/usr/local/bin/update-src.sh(subversion)
#!/bin/sh
if [ -x /usr/bin/svnlite ]; then
SVN=svnlite
else
SVN=svn
fi
#$SVN checkout https://svn.FreeBSD.org/base/releng/12.2 /usr/src-releng
#$SVN checkout https://svn.FreeBSD.org/base/stable/12 /usr/src-stable
#$SVN checkout https://svn.FreeBSD.org/base/head /usr/src-current
$SVN update /usr/src-releng
$SVN update /usr/src-stable
$SVN update /usr/src-current
/usr/local/bin/update-src.sh(git)
#!/bin/sh #git clone -o upstream -b main https://git.freebsd.org/src.git #git clone https://git.freebsd.org/src.git ssh://anongit@git.freebsd.org/src.git #git clone https://git.freebsd.org/src.git /usr/src #git clone -b releng/13.0 --depth 1 https://git.freebsd.org/src.git /usr/src-releng #git clone -b stable/13 --depth 1 https://git.freebsd.org/src.git /usr/src-stable cd /usr/src-stable git config pull.ff only git branch -v git pull cd /usr/src-releng git config pull.ff only git branch -v git pull cd /root #git remote -v
アーキテクチャごとのビルド
/usr/local/bin/makeworld.sh
#!/bin/sh
if [ $# -lt 1 ]; then
echo "$0 [current|stable|releng] [amd64|armv6|armv7|aarch64]"
exit 255
fi
TRAIN="$1"
ARCH="amd64"
if [ $# -gt 1 ]; then
ARCH="$2"
fi
MAKE="make -j 8"
WORLDLOG="buildworld-${ARCH}.log"
KERNELLOG="buildkernel-${ARCH}.log"
PACKAGESLOG="packages-${ARCH}.log"
MADEPACKAGES="packages"
case "${TRAIN}" in
"current"|"stable"|"releng")
cd /usr/src-${TRAIN}
case "${ARCH}" in
"armv6"|"rpi")
${MAKE} buildworld TARGET=arm TARGET_ARCH=armv6 UBLDR_LOADADDR=0x2000000 > ${WORLDLOG} 2>&1 && \
${MAKE} buildkernel TARGET=arm TARGET_ARCH=armv6 KERNCONF=RPI-B > ${KERNELLOG} 2>&1 && \
${MAKE} ${MADEPACKAGES} TARGET=arm TARGET_ARCH=armv6 KERNCONF=RPI-B > ${PACKAGESLOG} 2>&1
;;
"armv7"|"rpi2")
if [ -f sys/arm/conf/RPI2 ]; then
${MAKE} buildworld TARGET=arm TARGET_ARCH=armv7 UBLDR_LOADADDR=0x2000000 > ${WORLDLOG} 2>&1 && \
${MAKE} buildkernel TARGET=arm TARGET_ARCH=armv7 KERNCONF=RPI2 > ${KERNELLOG} 2>&1 && \
${MAKE} ${MADEPACKAGES} TARGET=arm TARGET_ARCH=armv7 KERNCONF=RPI2 > ${PACKAGESLOG} 2>&1
else
${MAKE} buildworld TARGET=arm TARGET_ARCH=armv7 UBLDR_LOADADDR=0x2000000 > ${WORLDLOG} 2>&1 && \
${MAKE} buildkernel TARGET=arm TARGET_ARCH=armv7 > ${KERNELLOG} 2>&1 && \
${MAKE} ${MADEPACKAGES} TARGET=arm TARGET_ARCH=armv7 > ${PACKAGESLOG} 2>&1
fi
;;
"aarch64"|"armv8"|"rpi3")
${MAKE} buildworld TARGET=arm64 TARGET_ARCH=aarch64 > ${WORLDLOG} 2>&1 && \
${MAKE} buildkernel TARGET=arm64 TARGET_ARCH=aarch64 > ${KERNELLOG} 2>&1 && \
${MAKE} ${MADEPACKAGES} TARGET=arm64 TARGET_ARCH=aarch64 > ${PACKAGESLOG} 2>&1
;;
*)
${MAKE} buildworld > ${WORLDLOG} 2>&1 && \
${MAKE} buildkernel > ${KERNELLOG} 2>&1 && \
${MAKE} ${MADEPACKAGES} > ${PACKAGESLOG} 2>&1
;;
esac
;;
*)
;;
esac
すべてのアーキテクチャのビルド
/usr/local/bin/makeworld-all.sh
#!/bin/sh
ARCHITECTURE="amd64 armv6 armv7 aarch64"
RELS="releng stable current"
for rel in ${RELS}
do
chflags -R noschg /usr/obj/usr/src-$rel
rm -rf /usr/obj/usr/src-$rel
for arch in ${ARCHITECTURE}
do
/usr/local/bin/makeworld.sh $rel $arch
done
done
アップグレード
ローカルアップグレード設定
/usr/local/etc/pkg/repos/FreeBSD-base.conf
FreeBSD-base: {
file: "/usr/obj/usr/src-stable/repo/${ABI}/latest",
mirror_type: "none",
enabled: yes
}
リモートアップグレード設定
ビルドしたベースパッケージを HTTP サーバーでアクセスできるようにしておき、そのパッケージサーバーからパッケージを取得します。
/usr/local/etc/apache24/Includes/freebsd-base.conf
Alias /repo "/usr/obj/usr/src-stable/repo"
<Directory "/usr/obj/usr/src-stable/repo">
Options Indexes FollowSymLinks
AllowOverride None
Require local
Require ip 192.168.0.0/16
</Directory>
/usr/local/etc/pkg/repos/FreeBSD-base.conf
FreeBSD-base: {
url: "http://pkg.example.com/repo/${ABI}/latest",
enabled: yes
}
ベースパッケージの初期化
rsync -av /etc/ /etc.old/ pkg update -r FreeBSD-base pkg install -y -r FreeBSD-base -g 'FreeBSD-*' rm -rf /etc rsync -av /etc.old/ /etc/
アップグレード
マイナーアップグレードの実行
既存パッケージのアップグレードと、追加パッケージのインストールを行います。
mergemaster -p pkg update -r FreeBSD-base pkg upgrade -y -r FreeBSD-base pkg install -y -r FreeBSD-base -g 'FreeBSD-*' reboot mergemaster
メジャーアップグレードの実行
FreeBSD 11 から 12 のようにメジャーバージョンをアップグレードするときは明示的に ABI を指定します。また、ライブラリ関係の問題を避けるためにpkg-staticを使います。また、不要になった古いパッケージを削除します。
mergemaster -p rsync -av /etc/ /etc.old/ env ABI=FreeBSD:12:amd64 IGNORE_OSVERSION=yes pkg upgrade -y -r FreeBSD-base env ABI=FreeBSD:12:amd64 IGNORE_OSVERSION=yes pkg-static install -y -r FreeBSD-base -g 'FreeBSD-*' pkg remove -y 'FreeBSD-*-11*' rm -rf /etc mv /etc.old /etc reboot mergemaster pkg-static upgrade -y -r FreeBSD pkg pkg update -r FreeBSD pkg upgrade -y -r FreeBSD
保存されたファイルを削除します。
find / -name "*.pkgsave" -print | xargs rm -f find / -name "*.pkgnew" -print | xargs rm -f
CURRENTのアップグレード
CURRENTからCURRENTへアップグレードするときはライブラリ関係の問題を避けるためにpkg-staticを使います。また、不要になった古いパッケージを削除します。
また、open-vm-toolsを動かしている場合は、カーネルモジュールが動作しなくなる可能性があるので一時的に削除して、アップグレードが終わったら再度インストールするようにします。
mergemaster -p rsync -av /etc/ /etc.old/ pkg-static install -y -r FreeBSD-base -g 'FreeBSD-*' pkg-static remove -y 'FreeBSD-*-14.snap2021*' pkg remove -y open-vm-tools rm -rf /etc mv /etc.old /etc reboot mergemaster pkg update -r FreeBSD pkg upgrade -y -r FreeBSD pkg install -y -r FreeBSD open-vm-tools