当前位置: 代码迷 >> 综合 >> Using debootstrap to build qcow2 virtio image (by quqi99)
  详细解决方案

Using debootstrap to build qcow2 virtio image (by quqi99)

热度:69   发布时间:2023-12-13 09:14:29.0

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

https://raw.githubusercontent.com/zhhuabj/mytools/master/qemu/build_qemu_image.sh

#!/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=4G
BASE_MAC="52:54:74:b7:10:"
NETWORK="192.168.123."partition(){image=$1
fdisk ${DISK_DEV} << EOF
n
p
1+3G
n
p
2w
EOF
}format_image(){mkfs.ext4 -LROOT -m 1 ${ROOT_DEV}mkswap -LSWAP -f ${SWAP_DEV}
}enter_root(){image=$1mkdir -p ${MOUNTPOINT}/{dev,sys,proc,dev}mkdir -p ${MOUNTPOINT}/dev/ptssleep 3mount ${ROOT_DEV} ${MOUNTPOINT}mount -o bind /dev ${MOUNTPOINT}/devmount -o bind /sys ${MOUNTPOINT}/sysmount -o bind /proc ${MOUNTPOINT}/procmount -o bind /dev/pts ${MOUNTPOINT}/dev/pts
}exit_root(){#umount bindumount ${MOUNTPOINT}/dev/ptsumount ${MOUNTPOINT}/devumount ${MOUNTPOINT}/sysumount ${MOUNTPOINT}/proc#umount filesystemsleep 1fuser -k ${MOUNTPOINT}umount ${MOUNTPOINT} -f
}if [[ "$(id -u)" != "0" ]]
thenecho "Error: must be run as root"exit 1
fi# Install some packages
tee "/etc/apt/sources.list" << EOF
deb http://archive.ubuntu.com/ubuntu/ ${RELEASE} main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ ${RELEASE}-updates main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu ${RELEASE}-security main restricted universe multiverse
EOF
apt update && apt -y install qemu-utils debootstrap build-essential# Reset the env
exit_root > /dev/null 2>&1
rm -rf $MOUNTPOINT > /dev/null 2>&1# Create the base imageqemu-img create -f qcow2 'base.qcow2' ${IMG_DISK_SIZE}
partition 'base.qcow2'
format_image
fdisk -l ${DISK_DEV} |grep dev
#Use 'sudo kpartx -a vm.raw' for raw format, then find the partions /dev/mapper/loop0p[N]
modprobe nbd max_part=16
sleep 10
qemu-nbd -c ${DISK_DEV} base.qcow2
# Sometimes above throws 'Failed to set NBD socket', so try again
sleep 15
qemu-nbd -d ${DISK_DEV} > /dev/null 2>&1
qemu-nbd -c ${DISK_DEV} base.qcow2
ls /dev/nbd0 /dev/nbd0p1 /dev/nbd0p2
if [ ! -f "$ROOT_DEV" ]; thenecho "Error: nbd devices no found!"exit 1
fiapt install -y apt-cacher-ng
echo 'Acquire::http::Proxy "http://127.0.0.1:3142";' | sudo tee /etc/apt/apt.conf.d/01acng
# without mount command below chroot will not be able to run apt 'bash: apt: command not found' after enter_root
mkdir -p $MOUNTPOINT && mount ${ROOT_DEV} ${MOUNTPOINT}
debootstrap --include=apt,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/archive.ubuntu.com/ubuntu/
ls ${MOUNTPOINT}/usr/bin/apt
umount ${MOUNTPOINT}enter_root 'base.qcow2'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
EOFtee "${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://archive.ubuntu.com/ubuntu/ ${RELEASE} main restricted universe multiverse
deb http://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-generic-lts-trusty'# Add one user non-interactively
chroot "${MOUNTPOINT}" userdel -r -f hua > /dev/null 2>&1
#chroot "${MOUNTPOINT}" useradd -g users -G root -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 '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"
result=$(cat "${MOUNTPOINT}/boot/grub/grub.cfg" |grep boot |grep root)
if [ -z "$result" ]; thenecho "ERROR when apt install linux-image (apt-get dist-upgrade)"exit 1
fi# Cleanup
exit_root
qemu-nbd -d ${DISK_DEV}# Test the base image
# qemu-system-x86_64 base.qcow2 #It's sda, and also need to change device.map
# qemu-system-x86_64 -drive file=base.qcow2,if=virtio #It's vda, and it requires device.map
BASE_MAC="52:54:74:b7:10:"
# qemu-system-x86_64 -drive file=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 guest.qcow2
qemu-img create -f qcow2 -b base.qcow2 guest.qcow2
#enter_root '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 ]; thenbrctl addbr demobr0brctl stp demobr0 offip link set demobr0 upif [ -n "$PHY_IF" ]; thenifconfig $PHY_IF 0.0.0.0 upbrctl addif demobr0 $PHY_IFfisleep 1ifconfig demobr0 ${NETWORK}1/24echo 'create bridge demobr0 success'echo 1 > /proc/sys/net/ipv4/ip_forwardiptables -t nat -A POSTROUTING -s ${NETWORK}0/24 -d ${NETWORK}0/24 -j ACCEPTiptables -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" ]; thenkill -9 $PID
fi
dnsmasq -C /tmp/dnsmasq.conf --dhcp-hostsfile=/tmp/dhcphosts --pid-file=/tmp/demobr0-dnsmasq.pidtee "/tmp/qemu-ifup" <<EOF
#!/bin/sh
switch=demobr0
if [ -n "\$1" ];thensudo tunctl -u \`whoami\` -t \$1sudo ip link set \$1 up 2>/dev/nullsleep 1sudo brctl addif \$switch \$1exit 0
elseecho "Error: no interface specified"exit 1
fi
EOF
tee "/tmp/qemu-ifdown" <<EOF
#!/bin/sh
switch=demobr0
if [ -n "\$1" ];thensudo ip link set \$1 downsudo brctl delif \$switch \$1 2>/dev/nullsudo tunctl -d \$1exit 0
elseecho "Error: no interface specified"exit 1
fi
EOF
chmod 777 /tmp/qemu-ifup && chmod 777 /tmp/qemu-ifdown
apt-get install -y uml-utilitiesQEMU_PID=$(ps -eo pid,cmd |grep qemu-system-x86_64 |grep '/tmp/qemu-ifup' |awk '{print $1}')
if [ -n "$QEMU_PID" ]; thenkill -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=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:4444cat /tmp/dhcphosts
echo " - SSH: hua@${NETWORK}250 (password: ${PASSWORD})"
echo " OR: minicom -D unix\#/tmp/guest.monitor"
  相关解决方案