#------------------------------------------------------------------------------
usage(){
echo "USAGE: sudo ./virctl create [ vlan / pool ] "
echo " sudo ./virctl drop [ vlan / pool ] "
echo " sudo ./virctl host [ define / start / shutdown / undefine ] "
echo " sudo ./virctl list "
echo " sudo ./virctl attach "
echo " sudo ./virctl interface [ host ] "
echo ""
echo " sudo virsh dumpxml hostname > file "
echo " sudo virsh edit hostname "
echo " sudo virsh vcpuinfo hostname "
}
#------------------------------------------------------------------------------
DIR_IMAGES="/disk/virt/images"
POOL_NAME="stage"
POOL_DIR="/virt_images"
POOL_STORAGE="${POOL_DIR}/${POOL_NAME}"
VLAN_LISTS=" nat|public_nat_1a|virbr_nat_1a|domain_nat_1a|10.0.10.1|255.255.255.0 \
nat|public_nat_1c|virbr_nat_1c|domain_nat_1c|10.0.20.1|255.255.255.0 \
bridge|private_api_1a|virbr_api_1a|domain_api_1a|10.0.11.1|255.255.255.0 \
bridge|private_api_1c|virbr_api_1c|domain_api_1c|10.0.21.1|255.255.255.0 \
bridge|private_web_1a|virbr_web_1a|domain_web_1a|10.0.12.1|255.255.255.0 \
bridge|private_web_1c|virbr_web_1c|domain_web_1c|10.0.22.1|255.255.255.0 \
bridge|private_utl_1a|virbr_utl_1a|domain_utl_1a|10.0.13.1|255.255.255.0 \
bridge|private_utl_1c|virbr_utl_1c|domain_utl_1c|10.0.23.1|255.255.255.0 \
bridge|private_ofc_1a|virbr_ofc_1a|domain_ofc_1a|10.0.14.1|255.255.255.0 \
bridge|private_ofc_1c|virbr_ofc_1c|domain_ofc_1c|10.0.24.1|255.255.255.0 \
bridge|private_db_1a|virbr_db_1a|domain_db_1a|10.0.18.1|255.255.255.0 \
bridge|private_db_1c|virbr_db_1c|domain_db_1c|10.0.28.1|255.255.255.0 \
bridge|private_mng_1a|virbr_mng_1a|domain_mng_1a|10.0.19.1|255.255.255.0 \
bridge|private_mng_1c|virbr_mng_1c|domain_mng_1c|10.0.29.1|255.255.255.0 \
"
OPTION_DISK_FOR_POSTGRES15=$(cat <( cat <<__EOF__
<disk type="file" device="disk">
<driver name="qemu" type="qcow2"/>
<source file="${POOL_STORAGE}/pg_tablespace.qcow2"/>
<target dev="vdb" bus="virtio"/>
<address type="pci" domain="0x0000" bus="0x08" slot="0x00" function="0x0"/>
</disk>
__EOF__
))
OPTION_NETWORK_FOR_SECURITY_GROUP=$(cat <( cat <<__EOF__
<interface type="network">
<source network="private_api_1a"/>
<model type="virtio"/>
</interface>
<interface type="network">
<source network="private_api_1c"/>
<model type="virtio"/>
</interface>
<interface type="network">
<source network="private_web_1a"/>
<model type="virtio"/>
</interface>
<interface type="network">
<source network="private_web_1c"/>
<model type="virtio"/>
</interface>
<interface type="network">
<source network="private_db_1a"/>
<model type="virtio"/>
</interface>
<interface type="network">
<source network="private_db_1c"/>
<model type="virtio"/>
</interface>
<interface type="network">
<source network="private_utl_1a"/>
<model type="virtio"/>
</interface>
<interface type="network">
<source network="private_utl_1c"/>
<model type="virtio"/>
</interface>
<interface type="network">
<source network="private_ofc_1a"/>
<model type="virtio"/>
</interface>
<interface type="network">
<source network="private_ofc_1c"/>
<model type="virtio"/>
</interface>
<interface type="network">
<source network="private_mng_1a"/>
<model type="virtio"/>
</interface>
<interface type="network">
<source network="private_mng_1c"/>
<model type="virtio"/>
</interface>
<interface type="network">
<source network="public_nat_1a"/>
<model type="virtio"/>
</interface>
<interface type="network">
<source network="public_nat_1c"/>
<model type="virtio"/>
</interface>
__EOF__
))
# HOST NETWORK CPU MEMOEY qcow2イメージ OPTION
HOST_LISTS=" nassv|private_db_1a|2|8388608|${POOL_STORAGE}/nassv.qcow2 \
security_group|public_nat_1a|2|4194304|${POOL_STORAGE}/security_group.qcow2|OPTION_NETWORK_FOR_SECURITY_GROUP \
igw|public_nat_1a|2|4194304|${POOL_STORAGE}/igw.qcow2 \
ngw|public_nat_1a|2|4194304|${POOL_STORAGE}/ngw.qcow2 \
elb_api|public_nat_1a|2|4194304|${POOL_STORAGE}/elb_api.qcow2 \
elb_web|public_nat_1a|2|4194304|${POOL_STORAGE}/elb_web.qcow2 \
apisv1n|private_api_1a|2|4194304|${POOL_STORAGE}/apisv1n.qcow2 \
apisv2n|private_api_2a|2|4194304|${POOL_STORAGE}/apisv2n.qcow2 \
websv1n|private_web_1a|2|4194304|${POOL_STORAGE}/websv1n.qcow2 \
websv2n|private_web_1c|2|4194304|${POOL_STORAGE}/websv2n.qcow2 \
utlsv1n|private_utl_1a|2|4194304|${POOL_STORAGE}/utlsv1n.qcow2 \
officesv1n|private_ofc_1a|2|4194304|${POOL_STORAGE}/officesv1n.qcow2 \
postgres15|private_db_1a|4|8388608|${POOL_STORAGE}/postgres15.qcow2|OPTION_DISK_FOR_POSTGRES15 \
postgres15-2|private_db_1a|4|8388608|${POOL_STORAGE}/postgres15-2.qcow2 \
buildsv|private_mng_1a|2|8388608|${POOL_STORAGE}/buildsv.qcow2 \
ora2pg|private_mng_1a|2|8388608|${POOL_STORAGE}/ora2pg.qcow2 \
ami_postgres15|private_mng_1a|2|4194304|${POOL_STORAGE}/ami_postgres15.qcow2 \
zabbix5.4|private_mng_1a|4|8388608|${POOL_STORAGE}/zabbix5.4.qcow2 \
"
#echo $OPTION_DISK
#exit
# pg_tablespace|private_db_1a|2|8388608|${POOL_STORAGE}/pg_tablespace.qcow2 \
#------------------------------------------------------------------------------
# MAIN ROUTIN
#------------------------------------------------------------------------------
main(){
case "$1" in
"create" )
case "$2" in
"vlan" )
create_vlan
;;
"pool" )
create_pool
;;
*)
usage
;;
esac
;;
"drop" )
case "$2" in
"vlan" )
drop_vlan
;;
"pool" )
drop_pool
;;
*)
usage
;;
esac
;;
"host" )
case "$2" in
"define" )
regist_hosts $3
;;
"start" )
virsh start $3
;;
"shutdown" )
virsh shutdown $3
sleep 1
;;
"undefine" )
undefine_hosts $3
#virsh undefine $3
;;
*)
usage
;;
esac
virsh list --all
;;
"attach" )
#virsh attach-interface --domain postgres15-2 --type bridge --source virbr_db_1a --model virtio
virsh attach-interface --domain postgres15-2 --type network --source private_db_1a --model virtio
;;
"list" )
virsh pool-list --all
virsh list --all
if [ "$2" != "" ]; then
virsh domiflist $2
fi
;;
"interface" )
virsh domiflist $2
virsh domifaddr $2
;;
"dumpxml" )
virsh dumpxml $2
;;
"edit" )
virsh edit $2
;;
*)
usage
;;
esac
}
#------------------------------------------------------------------------------
# VLAN 作成
#------------------------------------------------------------------------------
create_vlan(){
for ROW in $VLAN_LISTS; do
TYPE=`echo $ROW | cut -d "|" -f 1`
NETWORK_NAME=`echo $ROW | cut -d "|" -f 2`
IF_NAME=`echo $ROW | cut -d "|" -f 3`
DOMAIN_NAME=`echo $ROW | cut -d "|" -f 4`
IP_ADDRESS=`echo $ROW | cut -d "|" -f 5 `
MASK=`echo $ROW | cut -d "|" -f 6 `
echo $NETWORK_NAME / $IF_NAME / $DOMAIN_NAME / $IP_ADDRESS $MASK
case $TYPE in
"bridge" )
echo CREATE BRIDGE
create_bridge $NETWORK_NAME $IF_NAME $DOMAIN_NAME $IP_ADDRESS $MASK
;;
"nat" )
echo CREATE NAT
create_nat $NETWORK_NAME $IF_NAME $DOMAIN_NAME $IP_ADDRESS $MASK
;;
esac
done
nmcli c
}
drop_vlan(){
for ROW in $VLAN_LISTS; do
IF_NAME=`echo $ROW | cut -d "|" -f 2`
virsh net-destroy $IF_NAME
done
nmcli c
}
create_bridge(){
NETWORK_NAME=$1
IF_NAME=$2
DOMAIN_NAME=$3
IP_ADDRESS=$4
MASK=$5
virsh net-create <( cat <<__EOF__
<network connections="2">
<name>${NETWORK_NAME}</name>
<bridge name="${IF_NAME}" stp="on" delay="0"/>
<domain name="${DOMAIN_NAME}"/>
<ip address="${IP_ADDRESS}" netmask="${MASK}">
</ip>
</network>
__EOF__
)
}
create_nat(){
NETWORK_NAME=$1
IF_NAME=$2
DOMAIN_NAME=$3
IP_ADDRESS=$4
MASK=$5
virsh net-create <( cat <<__EOF__
<network connections="2">
<name>${NETWORK_NAME}</name>
<forward mode="nat">
<nat>
<port start="1024" end="65535"/>
</nat>
</forward>
<bridge name="${IF_NAME}" stp="on" delay="0"/>
<domain name="${DOMAIN_NAME}"/>
<ip address="${IP_ADDRESS}" netmask="${MASK}">
</ip>
</network>
__EOF__
)
}
#------------------------------------------------------------------------------
# POOL 作成
#------------------------------------------------------------------------------
create_pool(){
if [ -d ${POOL_STORAGE} ]; then
if [ -L ${POOL_STORAGE} ]; then
echo ${POOL_STORAGE}はシンボリンクリンクです。
else
echo ${POOL_STORAGE}はディレクトリです。
fi
else
mkdir -p ${POOL_DIR}
ln -s ${DIR_IMAGES}/${POOL_NAME} ${POOL_DIR}/${POOL_NAME}
chmod -R 755 ${POOL_DIR}
chown -R qemu:qemu ${POOL_DIR}
echo ${POOL_STORAGE}を作成しました。
fi
virsh pool-define <( cat <<__EOF__
<pool type='dir'>
<name>${POOL_NAME}</name>
<source>
</source>
<target>
<path>${POOL_STORAGE}</path>
<permissions>
<mode>0755</mode>
<owner>-1</owner>
<group>-1</group>
</permissions>
</target>
</pool>
__EOF__
)
virsh pool-start ${POOL_NAME}
virsh pool-list --all
}
# <label>system_u:object_r:virt_image_t:s0</label>
drop_pool(){
virsh pool-list --all
virsh pool-destroy ${POOL_NAME}
virsh pool-undefine ${POOL_NAME}
#if [ $? == 0 ]; then
# rm -rf ${POOL_DIR}
#fi
virsh pool-list --all
}
#------------------------------------------------------------------------------
# HOST 登録解除
#------------------------------------------------------------------------------
undefine_hosts(){
for ROW in ${HOST_LISTS}; do
SERVER_NAME=`echo $ROW | cut -d "|" -f 1`
if [ "$1" == "" ] || [ "$1" == "${SERVER_NAME}" ]; then
echo "${SERVER_NAME} を削除します。(実態ファイルは削除しません。)"
yes_no
if [ $? -eq 0 ]; then
virsh undefine ${SERVER_NAME}
if [ $? == 0 ]; then
echo "${SERVER_NAME} を定義削除しました。"
else
echo "[ERROR] ${SERVER_NAME} の削除に失敗しました。"
fi
else
echo "${SERVER_NAME} はスキップします。"
fi
fi
done
}
#------------------------------------------------------------------------------
# HOST 登録
#------------------------------------------------------------------------------
regist_hosts(){
for ROW in ${HOST_LISTS}; do
SERVER_NAME=`echo $ROW | cut -d "|" -f 1`
NETWORK_NAME=`echo $ROW | cut -d "|" -f 2`
NUMBER_OF_CPU=`echo $ROW | cut -d "|" -f 3`
SIZE_OF_MEMORY=`echo $ROW | cut -d "|" -f 4`
GUEST_HOST_SOURCE=`echo $ROW | cut -d "|" -f 5`
OPTIONS=`echo $ROW | cut -d "|" -f 6`
if [ "$1" == "" ] || [ "$1" == "${SERVER_NAME}" ]; then
host_define $SERVER_NAME $NETWORK_NAME $NUMBER_OF_CPU $SIZE_OF_MEMORY $GUEST_HOST_SOURCE $OPTIONS
if [ $? == 0 ]; then
echo "${SERVER_NAME} を定義しました"
else
echo "[ERROR] ${SERVER_NAME} を定義に失敗しました。"
fi
fi
done
}
host_define(){
#SERVER_NAME=postgres15-2
#NETWORK_NAME=private_db_1a
#NUMBER_OF_CPU=2
#SIZE_OF_MEMORY=8388608
#GUEST_HOST_SOURCE=/virt_images/stage_cxdnext/postgres15-2.qcow2
SERVER_NAME=$1
NETWORK_NAME=$2
NUMBER_OF_CPU=$3
SIZE_OF_MEMORY=$4
GUEST_HOST_SOURCE=$5
OPTIONS=${!6}
echo OPTIONS=$6
virsh define <( cat <<__EOF__
<domain type="kvm">
<name>${SERVER_NAME}</name>
<!--
<uuid>83e081df-ec65-49a8-ad45-a4066e06d7ab</uuid>
-->
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://rockylinux.org/rocky/9"/>
</libosinfo:libosinfo>
</metadata>
<memory unit="KiB">${SIZE_OF_MEMORY}</memory>
<currentMemory unit="KiB">${SIZE_OF_MEMORY}</currentMemory>
<vcpu placement="static">${NUMBER_OF_CPU}</vcpu>
<os>
<type arch="x86_64" machine="pc-q35-rhel9.2.0">hvm</type>
<boot dev="hd"/>
</os>
<features>
<acpi/>
<apic/>
</features>
<cpu mode="host-passthrough" check="none" migratable="on"/>
<clock offset="utc">
<timer name="rtc" tickpolicy="catchup"/>
<timer name="pit" tickpolicy="delay"/>
<timer name="hpet" present="no"/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<pm>
<suspend-to-mem enabled="no"/>
<suspend-to-disk enabled="no"/>
</pm>
<devices>
<emulator>/usr/libexec/qemu-kvm</emulator>
<disk type="file" device="disk">
<driver name="qemu" type="qcow2"/>
<source file="${GUEST_HOST_SOURCE}"/>
<target dev="vda" bus="virtio"/>
<address type="pci" domain="0x0000" bus="0x04" slot="0x00" function="0x0"/>
</disk>
${OPTIONS}
<controller type="usb" index="0" model="qemu-xhci" ports="15">
<address type="pci" domain="0x0000" bus="0x02" slot="0x00" function="0x0"/>
</controller>
<controller type="pci" index="0" model="pcie-root"/>
<controller type="pci" index="1" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="1" port="0x10"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x0" multifunction="on"/>
</controller>
<controller type="pci" index="2" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="2" port="0x11"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x1"/>
</controller>
<controller type="pci" index="3" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="3" port="0x12"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x2"/>
</controller>
<controller type="pci" index="4" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="4" port="0x13"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x3"/>
</controller>
<controller type="pci" index="5" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="5" port="0x14"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x4"/>
</controller>
<controller type="pci" index="6" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="6" port="0x15"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x5"/>
</controller>
<controller type="pci" index="7" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="7" port="0x16"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x6"/>
</controller>
<controller type="pci" index="8" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="8" port="0x17"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x7"/>
</controller>
<controller type="pci" index="9" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="9" port="0x18"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x0" multifunction="on"/>
</controller>
<controller type="pci" index="10" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="10" port="0x19"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x1"/>
</controller>
<controller type="pci" index="11" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="11" port="0x1a"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x2"/>
</controller>
<controller type="pci" index="12" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="12" port="0x1b"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x3"/>
</controller>
<controller type="pci" index="13" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="13" port="0x1c"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x4"/>
</controller>
<controller type="pci" index="14" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="14" port="0x1d"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x5"/>
</controller>
<controller type="sata" index="0">
<address type="pci" domain="0x0000" bus="0x00" slot="0x1f" function="0x2"/>
</controller>
<controller type="virtio-serial" index="0">
<address type="pci" domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
</controller>
<interface type="network">
<!--
<mac address="52:54:00:f5:18:f2"/>
-->
<source network="${NETWORK_NAME}"/>
<model type="virtio"/>
<address type="pci" domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
</interface>
<serial type="pty">
<target type="isa-serial" port="0">
<model name="isa-serial"/>
</target>
</serial>
<console type="pty">
<target type="serial" port="0"/>
</console>
<channel type="unix">
<target type="virtio" name="org.qemu.guest_agent.0"/>
<address type="virtio-serial" controller="0" bus="0" port="1"/>
</channel>
<input type="tablet" bus="usb">
<address type="usb" bus="0" port="1"/>
</input>
<input type="mouse" bus="ps2"/>
<input type="keyboard" bus="ps2"/>
<graphics type="vnc" port="-1" autoport="yes">
<listen type="address"/>
</graphics>
<audio id="1" type="none"/>
<video>
<model type="virtio" heads="1" primary="yes"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x0"/>
</video>
<watchdog model="itco" action="reset"/>
<memballoon model="virtio">
<address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
</memballoon>
<rng model="virtio">
<backend model="random">/dev/urandom</backend>
<address type="pci" domain="0x0000" bus="0x06" slot="0x00" function="0x0"/>
</rng>
</devices>
</domain>
__EOF__
)
}
#----------------------------------------
# 汎用関数
#----------------------------------------
yes_no(){
echo -n "よろしいですか? [y/N]:"
if tty -s; then
read ANS
else
echo TTY端末からの起動で無いため、強制的に「y」を入力します。
ANS=Yes
fi
case $ANS in
[Yy]* )
#echo "Yes"
return 0
;;
* )
#echo "No"
return 1
;;
esac
}
main $@