外部補助記憶装置

雑多なメモの寄せ集め

AArch64 な環境を x86_64 マシン上に cloud-init で自動で構築する

テスト用に aarch64 な環境が欲しいが手元に aarch64 ネイティブな環境がなかったため、QEMU のエミュレーションを用いた仮想マシンで cloud-init を使って自動で環境を構築したときのメモ

依存パッケージのインストール

virshvirt-installcloud-localds を利用するため必要なパッケージをインストールしておく。

sudo apt install virtinst libvirt-system-daemon qemu-system-aarch64 cloud-image-utils

cloud-init による自動インストール

SSH サーバーの設定と SSH 鍵を事前に登録しておき、パスワードなしでログインできるようにしておく。 ネットワークはブリッジ等の設定が面倒なため、QEMU のユーザースペースネットワーク機能とポートフォワードを利用している。

#!/bin/bash

set -eux

rm -f key key.pub
ssh-keygen -t ed25519 -f $(pwd)/key -N ""
PUB_KEY=$(cat key.pub)

HOSTNAME="aarch64-test"
USER="test"

cat << EOF > user-data.yaml
#cloud-config
hostname: $HOSTNAME
user: $USER
password: $USER
chpasswd: { expire: False }
ssh_pwauth: True
package_upgrade: true
packages:
  - openssh-server

runcmd:
  - mkdir /home/$USER/.ssh
  - echo $PUB_KEY > /home/$USER/.ssh/authorized_keys
  - systemctl enable sshd
  - poweroff

disk_setup:
  /dev/vdb:
    table_type: 'mbr'
    layout:
      - [100,82]
    overwrite: False
EOF

cat << EOF > network.yaml
EOF

cloud-localds user-data.img user-data.yaml --network-config network.yaml

IMAGE_NAME="image.img"
if [ ! -e noble-server-cloudimg-arm64.img ]; then
    wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-arm64.img
fi
cp noble-server-cloudimg-arm64.img $IMAGE_NAME
qemu-img resize $IMAGE_NAME 20G

virt-install \
    --name $HOSTNAME --ram 4096 --arch aarch64 --vcpus 4 \
    --os-variant ubuntu22.04 \
    --disk path=$IMAGE_NAME \
    --disk path=user-data.img \
    --tpm none \
    --network type=user,model=virtio \
    --graphics none --serial pty --console pty \
    --import


virsh start $HOSTNAME
virsh qemu-monitor-command --hmp $HOSTNAME 'hostfwd_add ::10022-:22'

上記スクリプトを実行すると、セットアップと再起動後のポートフォワードの設定が自動で行われる。 セットアップ後に自動で何かを実行する場合は、以下のように再起動を待機するようにしておけばよい。

#!/bin/bash

SSH="ssh -p 10022 -i key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no test@localhost"

$SSH exit
RESULT=$?
until [ $RESULT -eq 0 ]; do
   echo "retrying..."
   $SSH exit
   RESULT=$?
   sleep 1
done