Using debootstrap to build qcow2 virtio image (by quqi99)

594人阅读 评论(0) 收藏 举报
分类:

**作者:张华 发表于:2016-11-04
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明
( http://blog.csdn.net/quqi99 )**

Download from github

#!/bin/bash

#PHY_IF='eno1'
PHY_IF=''
RELEASE='trusty'
MOUNTPOINT="/tmp/nbd0"
DISK_DEV=/dev/nbd0
ROOT_DEV=/dev/nbd0p1
SWAP_DEV=/dev/nbd0p2
PASSWORD='password'
IMG_DISK_SIZE=3G
BASE_MAC="52:54:74:b7:10:"
NETWORK="192.168.123."

partition(){
  image=$1
  modprobe nbd max_part=16
  #Use 'sudo kpartx -a vm.raw' for raw format, then find the partions /dev/mapper/loop0p[N]
  qemu-nbd -c ${DISK_DEV} ${image}
fdisk ${DISK_DEV} << EOF
n
p
1

+2G
n
p
2


w
EOF
  fdisk -l ${DISK_DEV} |grep dev
}

format_image(){
  mkfs.ext4 -LROOT -m 1 ${ROOT_DEV}
  mkswap -LSWAP -f ${SWAP_DEV}
}

enter_root(){
  image=$1
  modprobe nbd max_part=16
  qemu-nbd -c ${DISK_DEV} ${image}
  sleep 1
  mkdir -p ${MOUNTPOINT}/{dev,sys,proc,dev}
  mkdir -p ${MOUNTPOINT}/dev/pts
  sleep 1
  mount ${ROOT_DEV} ${MOUNTPOINT}
  mount -o bind /dev ${MOUNTPOINT}/dev
  mount -o bind /sys ${MOUNTPOINT}/sys
  mount -o bind /proc ${MOUNTPOINT}/proc
  mount -o bind /dev/pts ${MOUNTPOINT}/dev/pts
}

exit_root(){
  #umount bind
  umount ${MOUNTPOINT}/dev/pts
  umount ${MOUNTPOINT}/dev
  umount ${MOUNTPOINT}/sys
  umount ${MOUNTPOINT}/proc
  #umount filesystem
  sleep 1
  fuser -k ${MOUNTPOINT}
  umount ${MOUNTPOINT} -f
  qemu-nbd -d ${DISK_DEV}
}

# Reset the env
exit_root

# Create the base image
if [ ! -f "/images/base.qcow2" ]; then
  qemu-img create -f qcow2 '/images/base.qcow2' ${IMG_DISK_SIZE}
  partition '/images/base.qcow2'
  format_image
fi
enter_root '/images/base.qcow2'

apt install -y apt-cacher-ng
echo 'Acquire::http::Proxy "http://127.0.0.1:3142";' | sudo tee /etc/apt/apt.conf.d/01acng
debootstrap --include=less,vim,sudo,openssh-server,bash-completion,wget,rsync,git,gdb,crash,grub-pc,screen,open-iscsi,build-essential $RELEASE ${MOUNTPOINT} http://127.0.0.1:3142/cn.archive.ubuntu.com/ubuntu/

tee "${MOUNTPOINT}/etc/fstab" <<EOF
#UUID can be found via blkid command
#LABEL=boot /boot ext2 sync 0 2
#UUID=735b3be3-779c-4d21-a944-b033225f3ab4 none   swap    sw      0       0
LABEL=SWAP none swap sw 0 0
LABEL=root / ext4 errors=remount-ro 0 1
EOF

tee "${MOUNTPOINT}/etc/network/interfaces" <<EOF
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
EOF

# Configure apt
tee "${MOUNTPOINT}/etc/apt/sources.list" <<EOF
deb http://cn.archive.ubuntu.com/ubuntu/ ${RELEASE} main restricted universe multiverse
deb http://cn.archive.ubuntu.com/ubuntu/ ${RELEASE}-updates main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu ${RELEASE}-security main restricted universe multiverse
EOF
tee "${MOUNTPOINT}/etc/apt/apt.conf" <<EOF
# Acquire::http::Proxy "http://127.0.0.1:3142/";
APT::Install-Recommends "true";
APT::Install-Suggests "false";
APT::Get::Assume-Yes "true";
APT::Get::Show-Upgraded "true";
APT::Quiet "true";
DPkg::Options {"--force-confdef";"--force-confmiss";"--force-confold"};
Debug::pkgProblemResolver "true";
Acquire::Languages "none";
EOF

# Install the locales and kernel
LANG=C DEBIAN_FRONTEND=noninteractive chroot "${MOUNTPOINT}" bash -c 'apt-get update'
#LANG=C DEBIAN_FRONTEND=noninteractive chroot "${MOUNTPOINT}" bash -c 'apt-get dist-upgrade -y'
LANG=C DEBIAN_FRONTEND=noninteractive chroot "${MOUNTPOINT}" bash -c 'apt-get -y install gdbserver'
chroot "${MOUNTPOINT}" bash -c 'apt-get -f install'
LANG=C DEBIAN_FRONTEND=noninteractive chroot "${MOUNTPOINT}" bash -c 'apt-get install -y linux-image-generic linux-headers-generic'

# Add one user non-interactively
chroot "${MOUNTPOINT}" userdel -r -f hua
#chroot "${MOUNTPOINT}" useradd -g users -G admin -s /bin/bash -d /home/hua -m hua
chroot "${MOUNTPOINT}" adduser --disabled-password --gecos "" hua
echo "hua:${PASSWORD}" | chpasswd -R "${MOUNTPOINT}"
echo 'hua ALL=(ALL) NOPASSWD: ALL' >> ${MOUNTPOINT}/etc/sudoers
mkdir -p "${MOUNTPOINT}/home/hua/.ssh"
cat /home/${SUDO_USER}/.ssh/{id_*.pub,authorized_keys} 2>/dev/null | sort -u > "${MOUNTPOINT}/home/hua/.ssh/authorized_keys"
# root user
echo "root:${PASSWORD}" | chpasswd -R "${MOUNTPOINT}"
mkdir -p "${MOUNTPOINT}/root/.ssh"
cat /home/${SUDO_USER}/.ssh/{id_*.pub,authorized_keys} 2>/dev/null | sort -u > "${MOUNTPOINT}/root/.ssh/authorized_keys"

# IMPORTANT: Install grub
exit_root
enter_root '/images/base.qcow2'
# without /boot partition: grub-install --boot-directory=${MOUNTPOINT}/boot/boot ${DISK_DEV}
# with /boot partition:    grub-install --boot-directory=${MOUNTPOINT}/boot ${DISK_DEV}
# But seems '--boot-directory' will cause grub can't find the modules of hard disk
chroot "${MOUNTPOINT}" grub-install --modules="biosdisk part_msdos" --no-floppy ${DISK_DEV}
# Used for serial console
tee "${MOUNTPOINT}/etc/default/grub" <<EOF
GRUB_DEFAULT=0
#GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=2
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
#IMPORTANT: it's vda for virtio, it's sda for ide
GRUB_CMDLINE_LINUX_DEFAULT="root=/dev/vda1 console=tty0 console=ttyS0,38400n8 apparmor=0 crashkernel=384M-:256M"
GRUB_CMDLINE_LINUX=""
GRUB_TERMINAL=serial
GRUB_SERIAL_COMMAND="serial --speed=38400 --unit=0 --word=8 --parity=no --stop=1"
#GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"
#GRUB_TERMINAL=console
#GRUB_GFXMODE=640x480
#GRUB_DISABLE_LINUX_UUID=true
#GRUB_DISABLE_RECOVERY="true"
#GRUB_INIT_TUNE="480 440 1"
EOF
tee "${MOUNTPOINT}/boot/grub/device.map" <<EOF
# It's vda for virtio, it's sda for ide
(hd0) /dev/vda
EOF
chroot "${MOUNTPOINT}" update-grub
#IMPORTANT: it's vda for virtio, it's sda for ide
sed -i -e "s|${SWAP_DEV}|/dev/vda2|g;s|${ROOT_DEV}|/dev/vda1|g;s|${DISK_DEV}|/dev/vda|g" "${MOUNTPOINT}/boot/grub/grub.cfg"
cat "${MOUNTPOINT}/boot/grub/grub.cfg" |grep boot |grep root

# Test the base image
exit_root
# qemu-system-x86_64 /images/base.qcow2   #It's sda, and also need to change device.map
qemu-system-x86_64 -drive file=/images/base.qcow2,if=virtio  #It's vda, and it requires device.map
# qemu-system-x86_64 -drive file=/images/base.qcow2,if=virtio -device virtio-net-pci,netdev=net1,mac=${BASE_MAC}fd -netdev tap,id=net1,script=/tmp/qemu-ifup,downscript=/tmp/qemu-ifdown

# Burning to disk
#dd if=/dev/nbd0 of=/dev/sdb bs=4M; sync

# Create a Guest
rm -f /images/guest.qcow2
qemu-img create -f qcow2 -b /images/base.qcow2 /images/guest.qcow2
#enter_root '/images/guest.qcow2'
# Do something
#exit_root

# Boot one VM
apt-get install -y qemu-kvm bridge-utils dnsmasq
declare -i result=$(brctl show | grep demobr0 | wc -l)
if [ $result == 0 ]; then
   brctl addbr demobr0
   brctl stp demobr0 off
   ip link set demobr0 up
   if [ -n "$PHY_IF" ]; then
     ifconfig $PHY_IF 0.0.0.0 up
     brctl addif demobr0 $PHY_IF
   fi
   sleep 1
   ifconfig demobr0 ${NETWORK}1/24
   echo 'create bridge demobr0 success'
   echo 1 > /proc/sys/net/ipv4/ip_forward
   iptables -t nat -A POSTROUTING -s ${NETWORK}0/24 -d ${NETWORK}0/24 -j ACCEPT
   iptables -t nat -A POSTROUTING -s ${NETWORK}0/24 -j MASQUERADE
fi
brctl show

# dnsmasq
service dnsmasq stop
echo "${BASE_MAC}fd,${NETWORK}249,guest" > /tmp/dhcphosts
echo "${BASE_MAC}fe,${NETWORK}250,guest" >> /tmp/dhcphosts
tee "/tmp/dnsmasq.conf" <<EOF
interface=demobr0
except-interface=lo
bind-interfaces
dhcp-range=${NETWORK}1,${NETWORK}250,12h
EOF
PID=$(ps -eo pid,cmd |grep -E '([0-9]+)\s+[^0-9]+dnsmasq' |grep demobr0 |awk '{print $1}')
if [ -n "$PID" ]; then
  kill -9 $PID
fi
dnsmasq -C /tmp/dnsmasq.conf --dhcp-hostsfile=/tmp/dhcphosts --pid-file=/tmp/demobr0-dnsmasq.pid

tee "/tmp/qemu-ifup" <<EOF
#!/bin/sh
switch=demobr0
if [ -n "\$1" ];then
        sudo tunctl -u \`whoami\` -t \$1
        sudo ip link set \$1 up 2>/dev/null
        sleep 1
        sudo brctl addif \$switch \$1
        exit 0
else
        echo "Error: no interface specified"
        exit 1
fi
EOF
tee "/tmp/qemu-ifdown" <<EOF
#!/bin/sh
switch=demobr0
if [ -n "\$1" ];then
        sudo ip link set \$1 down
        sudo brctl delif \$switch \$1 2>/dev/null
        sudo tunctl -d \$1
        exit 0
else
        echo "Error: no interface specified"
        exit 1
fi
EOF
chmod 777 /tmp/qemu-ifup && chmod 777 /tmp/qemu-ifdown
apt-get install -y uml-utilities

QEMU_PID=$(ps -eo pid,cmd |grep qemu-system-x86_64 |grep '/tmp/qemu-ifup' |awk '{print $1}')
if [ -n "$QEMU_PID" ]; then
  kill -9 $QEMU_PID
fi
BASE_MAC="52:54:74:b7:10:"
sudo qemu-system-x86_64 -enable-kvm -machine q35 -smp 8 -m 4096 \
-name guest=guest,debug-threads=on \
-device virtio-net-pci,netdev=net0,mac=${BASE_MAC}fe \
-netdev tap,id=net0,script=/tmp/qemu-ifup,downscript=/tmp/qemu-ifdown \
-device virtio-net-pci,netdev=net1,mac=${BASE_MAC}fd \
-netdev tap,id=net1,script=/tmp/qemu-ifup,downscript=/tmp/qemu-ifdown \
-drive file=/images/guest.qcow2,if=virtio \
-numa node,nodeid=0,cpus=0-3 \
-numa node,nodeid=1,cpus=4-7 \
-chardev socket,id=monitor,path=/tmp/guest.monitor,server,nowait \
-monitor chardev:monitor \
-chardev socket,id=serial,path=/tmp/guest.serial,server,nowait \
-serial chardev:serial \
-curses
#-S \
#-incoming tcp:0:4444

cat /tmp/dhcphosts
echo " - SSH: hua@${NETWORK}250 (password: ${PASSWORD})"
echo " OR: minicom -D unix\#/tmp/guest.monitor"
1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1407465次
    • 积分:16298
    • 等级:
    • 排名:第659名
    • 原创:300篇
    • 转载:10篇
    • 译文:0篇
    • 评论:299条