LoginSignup
4
3

More than 5 years have passed since last update.

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