4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

FreeBSDAdvent Calendar 2016

Day 13

BHyVeお手軽スクリプト

Last updated at Posted at 2016-12-13

BHyVeを安直に動かしたいという目的で作った、「BHyVeお手軽スクリプト」を公開します。

基本ZFS用ですが、ufsでも使えます。事前にvmm.koをロードする必要があります。

このファイルを適当な名前(例えば bhyve-util等)で保存して、システム名-コマンド名でシンボリックリンクを貼ります。

$ ln -s bhyve-util freebsd0-boot
$ ln -s bhyve-util freebsd0-boottty
$ ln -s bhyve-util freebsd0-clean
$ ln -s bhyve-util freebsd0-console
$ ln -s bhyve-util freebsd0-install
$ ln -s bhyve-util freebsd0-resources
$ ln -s bhyve-util freebsd0-shutdown

内部の __config_system 関数内の設定を必要に応じて修正します。1回目はfreebsd0-installを実行し、インストール後に freebsd0-boot を実行すれば動きます。

とりあえず、FreeBSD アドベントカレンダーを埋めてる目的で、今日はここまで(かなりヒドイ)。

2018-12-20 追記
更新版を公開しました。「続 BHyVe お手軽スクリプト 」を見てください。

#!/bin/sh
#
#  BHyVe での Grubを使うOSのインストール/起動スクリプト
#  プログラム名
#   システム名-install		bhyveへのインストール
#   システム名-boot		インストール済みシステムの起動
#   システム名-boottty		consoleをttyで起動 (*-boot -t でも同じ)
#   システム名-console		null-modem経由でコンソールへ接続
#   システム名-resources	リソースの表示
#   システム名-shutodnw		VMMのシャットダウン
#   システム名-clean		VMMのクリア
#

export PATH=/usr/local/bin:/usr/local/sbin:/bin:/usr/bin:/sbin:/usr/sbin

cpu=1			# VMのデフォルトのCPU数
mem=256M		# VMのデフォルトのメモリサイズ
bridge=bridge0		# デフォルトのbridge if
zvol_pre=zroot/vm	# VM用ZFS Volumeのprefix
iso_prefix=/home/archives/ISO	# ISO image のあるPathのprefix
zvol_opt='-o volmode=dev -o volblocksize=4k'	# ZFS Volumeのプロパティ

do_daemon=daemon		# daemon コマンド

#  VMのリソース割り当て
#
#   新たなVMを増やす場合
#     case文のエントリーを増やす
#     _id に新規の番号を割り当てる
#     適当なISOイメージを割り当てる
#
#  con: consoleが接続されるヌルモデムのデバイス名 ex. /dev/nmdm0A
#  tap:  tap IFの名前   ex tap0
#        tapX と /dev/nmdmXA の Xの番号は一致し、_id に設定した値を使う
#  zvol: VM用 zfs volume
#	 システム名とZFSのvolume名は同じ名前であることを前提としている
#  hd0:  システムディスク 通常 /dev/zvol/${zvol_pre}/${system}
#  cd0:  インストール用のISOイメージ
#  freebsd:  ターゲットOSがfreebsdならばYES
#  grub_inst_cmd: (optional) grub-bhyveでinstallに必要なコマンド列
#  grub_boot_cmd: (optional) grub-bhyveでbootに必要なコマンド列
#
__config_system () {
	local _id _iso _ver _kern _ramfs _root

	case ${system} in

	ubuntu0)
		_id=0
		_iso=Ubuntu/ubuntu-16.04-server-amd64.iso
		;;
	debian0)
		_id=1
		_iso=Debian/debian-8.4.0-amd64-netinst.iso
		;;
	centos0)
		_id=2
		_iso=CentOS/CentOS-7-x86_64-Minimal-1511.iso
		_ver="3.10.0-327"	# install時のCentOS 7のオリジナル
		_ver="3.10.0-327.18.2"	# update によって適宜更新する
		_ver="3.10.0-327.22.2"	# update によって適宜更新する
		_ver="3.10.0-327.28.2"	# update によって適宜更新する
		_ver="3.10.0-327.28.3"	# update によって適宜更新する
		_root=/dev/mapper/centos-root
		_kern="(hd0,msdos1)/vmlinuz-${_ver}.el7.x86_64"
		_ramfs="(hd0,msdos1)/initramfs-${_ver}.el7.x86_64.img"
		grub_inst_cmd="linux (cd0)/isolinux/vmlinuz; initrd (cd0)/isolinux/initrd.img"
		grub_boot_cmd="linux ${_kern} root=${_root}; initrd ${_ramfs}"
		;;
	openbsd0)
		_id=3
		_iso=OpenBSD/install59.iso
		_ver=5.9
		grub_inst_cmd="kopenbsd -h com0 (cd0)/${_ver}/amd64/bsd.rd"
		grub_boot_cmd="kopenbsd -h com0 -r sd0a (hd0,openbsd1)/bsd"
		;;
	netbsd0)
		_id=4
		_iso=NetBSD/NetBSD-7.0.1-amd64.iso
		grub_inst_cmd="knetbsd -h -r cd0a (cd0)/netbsd"
		grub_boot_cmd="knetbsd -h -r /dev/rld0a (hd0,netbsd1)/netbsd"
		;;
	freebsd0)
		_id=5
		_iso=FreeBSD/FreeBSD-10.3-RELEASE-amd64-disc1.iso
		freebsd=YES
		;;
	fbsdzfs0)
		_id=6
		_iso=FreeBSD/FreeBSD-10.3-RELEASE-amd64-disc1.iso
		freebsd=YES
		mem=512M
		;;
	ubuntubsd0)
		_id=7
		_iso=ubuntuBSD/ubuntuBSD-15.10~BETA5-amd64.iso
		;;
	*)
		echo "*** ${0##*/} is bad name" 1>&2 ; exit 1
		;;
	esac

	tap=tap${_id}
	con=/dev/nmdm${_id}A
	zvol=${zvol:-${zvol_pre}/${system}}
	hd0=${hd0:-/dev/zvol/${zvol}}
	cd0=${cd0:-${iso_prefix}/${_iso}}
}

__check_running () {
	pgrep -qf "bhyve: ${system}"
	return $?
}

# Bhyve 用ZFS volumeの作成 (HOGE-ressouces 時)
__make_zvol () {
	if [ -e "${hd0}" ]; then
		echo "*** ${hd0} already exist" 1>&2
	else
		sudo zfs create ${s_flag} -V ${V_size} ${zvol_opt} ${zvol} || exit
	fi
}

# Bhyve 用tap ifの作成
__make_tap () {

	if ifconfig "${tap}" >/dev/null 2>&1; then
		echo "*** ${tap} already exist" 1>&2
	else
		sudo ifconfig ${tap} create
		sudo ifconfig ${bridge} addm ${tap}
	fi
}

# ディスクイメージがあるかどうかの確認
__check_resouces() {
	local _badconfig

	if [ ! -e "${hd0}" ]; then
		echo "*** ${hd0} not found." 1>&2
		_badconfig=YES
	fi

	if [ x"${install}" = xYES -a ! -e "${cd0}" ]; then
		echo "*** ${cd0} not found." 1>&2
		_badconfig=YES
	fi

	if [ x"${_badconfig}" = x"YES" ]; then
		exit 1		# 問題があれば終了
	fi
}

__connect_console() {	# nmdmデバイス経由でコンソールへ接続する
	local nmdm 

	nmdm=`echo ${con} | tr 'A' 'B'`
	exec sudo cu -l ${nmdm}
}

__print_resources () {
	if [ "x${V_size}" != x ]; then
		__make_zvol
	fi
	echo tap=${tap}
	echo con=${con}
	echo zvol=${zvol}
	echo hd0=${hd0}
	echo cd0=${cd0}
}

__grub_install () {
	local _st

	cat <<- EOT > ${map}
	(hd0) ${hd0}
	(cd0) ${cd0}
	EOT

	if [ x${grub_inst_cmd} = x ]; then
		sudo grub-bhyve -m ${map} -r cd0 -M ${mem} ${system}
	else
		sudo grub-bhyve -m ${map} -r cd0 -M ${mem} ${system} <<- EOT
		${grub_inst_cmd}
		boot
		EOT
	fi
	_st=$?
	rm -f ${map}

	# インストーラの起動
	[ ${_st} -eq 0 ] && exec sudo bhyve -A -H -P \
		-c ${cpu} \
		-m ${mem} \
		-l com1,stdio \
		-s 0:0,hostbridge \
		-s 1:0,lpc \
		-s 2:0,virtio-net,${tap} \
		-s 3:0,virtio-blk,${hd0} \
		-s 4:0,ahci-cd,${cd0} \
		${system}
}

__clean_vm () {
	if pgrep -fq "bhyve: ${system}"
	then
		echo "*** ${system} is running" 1>&2
		exit 2
	fi

	if [ -e /dev/vmm/${system} ] ;
	then
		sudo bhyvectl --destroy --vm=${system} # VMのクリア
	fi

	if ifconfig ${tap} >/dev/null 2>&1
	then
		sudo ifconfig ${bridge} deletem ${tap}
		sudo ifconfig ${tap} destroy
	fi
}

__shutdown_vm () {
	local _pid _i

	if ! _pid=$(pgrep -f "bhyve: ${system}")
	then
		echo "*** ${system} is not running" 1>&2
		exit 2
	fi

	sudo kill ${_pid}

	test ${q_flag} || echo -n "Waiting for shutdown ${system} " 1>&2
	_i=0
	while pgrep -qf "bhyve: ${system}"
	do
		_i=$((_i + 1))
		if [ ${_i} -ge 150 ]	# shutdownを2分半までは待つ
		then
			echo "**** ${system}: can not shutdown!" 1>&2
			exit 2
		fi
		sleep 1
		test ${q_flag} || echo -n '.' 1>&2
	done
	__clean_vm 
	test ${q_flag} || echo " Done." 1>&2
}

__grub_boot () {
	local _st

	# boot用のmapファイルの作成
	cat <<- EOT > ${map}
	(hd0) ${hd0}
	EOT

	[ ! -z "${hd1}" ] && hd2nd="-s 4:0,virtio-blk,${hd1}"

	# Boot用の Grubの起動
	#
	if [ x"${grub_boot_cmd}" = x -o x"${p_flag}" = xYES ]; then
		sudo grub-bhyve -m ${map} -r hd0,msdos1 -M ${mem} ${system}
	else
		sudo grub-bhyve -m ${map} -r hd0,msdos1 -M ${mem} ${system} <<- EOT
		${grub_boot_cmd}
		boot
		EOT
	fi
	_st=$?

	rm -f ${map} 

	# bhyveの起動
	[ ${_st} -eq 0 ] && exec sudo ${do_daemon} bhyve -A -H -P \
		-c ${cpu} \
		-m ${mem} \
		-l com1,${con} \
		-s 0:0,hostbridge \
		-s 1:0,lpc \
		-s 2:0,virtio-net,${tap} \
		-s 3:0,virtio-blk,${hd0} ${hd2nd} \
		${system}
}

__freebsd_install () {
	sudo bhyveload -c stdio -m ${mem} -d ${cd0} ${system} &&
	sudo bhyve -H -A -P  \
		-c ${cpu} \
		-m ${mem} \
		-l com1,stdio \
		-s 0:0,hostbridge \
		-s 1:0,lpc \
		-s 2:0,virtio-net,${tap} \
		-s 3:0,virtio-blk,${hd0} ${hd2nd} \
		-s 31:0,ahci-cd,${cd0} \
		${system}
}

__freebsd_boot () {

	[ ! -z "${hd1}" ] && hd2nd="-s 4:0,virtio-blk,${hd1}"

	sudo bhyveload -c stdio -m ${mem} -d ${hd0} ${system} &&
	exec sudo ${do_daemon} bhyve -H -A -P  \
		-c ${cpu} \
		-m ${mem} \
		-l com1,${con} \
		-s 0:0,hostbridge \
		-s 1:0,lpc \
		-s 2:0,virtio-net,${tap} \
		-s 3:0,virtio-blk,${hd0} ${hd2nd} \
		${system}
}

# ----- ここからメイン -----

prog=${0##*/}
system=${prog%-*}	# "XXX-hogehoge"の"XXX"をシステム名
cmd=${prog##*-}		#  "hogehoge"をコマンド名

__config_system

# -t オプションがあればサーバーをバックグラウンド処理にしない
# -c cpu数
# -m メモリサイズ
# -V size 指定サイズのvolumeの作成 (*-resources のみ)
# -I tap の作成 (*-resources のみ)
#
while getopts 'qpstc:m:IV:' cmd_arg; do
	case "${cmd_arg}" in
	t)      con=stdio ; unset do_daemon ;;
	c)      cpu=${OPTARG} ;;
	m)	mem=${OPTARG} ;;
	I)	I_flag=YES ;;
	s)	s_flag=-s ;;
	p)	p_flag=YES ;;
	q)	q_flag=YES ;;
	V)	V_size=${OPTARG} ;;
	*)	echo "Usage: ${0##*/} [ -t ]" 1>&2; exit 2;;
	esac
done
shift $((OPTIND - 1))

# コマンドの判断
#
case ${cmd} in
clean)		__clean_vm ; exit ;;
resources)	__print_resources ; exit ;;
boot)		;;
boottty)	con=stdio ; unset do_daemon ;;
install)	install=YES ;;
console)	__connect_console ;;
shutdown)	__shutdown_vm ; exit ;; 
*)		echo "*** ${cmd}: Unknown Commmand" 1>&2 ; exit 2 ;;
esac

__check_resouces
__clean_vm
__make_tap

cd /tmp		# ワーキングディレクトリを /tmp に変更

if [ x${freebsd} = xYES ]; then
	if [ x${install} = xYES ]; then
		__freebsd_install
	else
		__freebsd_boot
	fi
else
	map=`mktemp /tmp/_bhyve-map-${system}-XXXXXX` # grub-bhyve用mapファイル

	if [ x${install} = xYES ]; then
		__grub_install
	else
		__grub_boot
	fi
fi
4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?