Created
March 10, 2018 09:32
-
-
Save offlinehacker/a7368e33b1e082693e7083811900a89e to your computer and use it in GitHub Desktop.
Libvirt deploy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
VIRSH=virsh | |
LIBVIRT_HOST=root@192.168.122.1 | |
LIBVIRT_URI=qemu+ssh://$LIBVIRT_HOST/system | |
POOL=images | |
PROJECT=$1 | |
SHARE_DIR=/storage/share | |
ROOT_DEV=/dev/vda1 | |
function getIp() { | |
sleepSeconds=10 | |
while ! $VIRSH -c $LIBVIRT_URI domifaddr $1 | grep vnet > /dev/null; do | |
sleep $sleepSeconds | |
done | |
$VIRSH -c $LIBVIRT_URI domifaddr $1 | grep vnet | awk '{print $4}' | cut -d '/' -f1 | |
} | |
function listVolumes() { | |
$VIRSH -c $LIBVIRT_URI vol-list $1 | tail -n +3 | xargs -I{} echo {} | awk '{print $1}' | |
} | |
function listDomains() { | |
$VIRSH -c $LIBVIRT_URI list $1 | xargs -I{} echo {} | awk '{print $2}' | |
} | |
function createBackedVolume() { | |
$VIRSH -c $LIBVIRT_URI vol-create $POOL <(cat <<EOF | |
<volume type='file'> | |
<name>$2</name> | |
<capacity unit='GB'>$3</capacity> | |
<target> | |
<format type='qcow2'/> | |
<features> | |
<lazy_refcounts/> | |
</features> | |
</target> | |
<backingStore> | |
<path>$1</path> | |
<format type='qcow2'/> | |
</backingStore> | |
</volume> | |
EOF | |
) | |
} | |
function volumePath() { | |
$VIRSH -c $LIBVIRT_URI vol-path --pool=$POOL $1 | |
} | |
function waitForSSH() { | |
echo "# waiting for connection to $1" | |
maxConnectionAttempts=10 | |
sleepSeconds=10 | |
index=1 | |
while (( $index <= $maxConnectionAttempts )) | |
do | |
ssh root@$1 "exit 0" | |
case $? in | |
(0) echo "${index}> Success"; break ;; | |
(*) echo "${index} of ${maxConnectionAttempts}> Bastion SSH server not ready yet, waiting ${sleepSeconds} seconds..." ;; | |
esac | |
sleep $sleepSeconds | |
((index+=1)) | |
done | |
} | |
function createDomain() { | |
$VIRSH -c $LIBVIRT_URI define <(cat <<EOF | |
<domain type='kvm'> | |
<name>$1</name> | |
<memory unit='GB'>$2</memory> | |
<vcpu placement='static'>4</vcpu> | |
<resource> | |
<partition>/machine</partition> | |
</resource> | |
<os> | |
<type arch='x86_64' machine='pc-i440fx-2.8'>hvm</type> | |
<boot dev='hd'/> | |
</os> | |
<features> | |
<acpi/> | |
<apic/> | |
<vmport state='off'/> | |
</features> | |
<cpu mode='custom' match='exact'> | |
<model fallback='forbid'>Broadwell-noTSX</model> | |
<vendor>Intel</vendor> | |
</cpu> | |
<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> | |
<disk type='file' device='disk'> | |
<driver name='qemu' type='qcow2'/> | |
<source file='$(volumePath "$1.qcow2")'/> | |
<backingStore type='file' index='1'> | |
<format type='raw'/> | |
<source file='$(volumePath "nixos-17.03.qcow2")'/> | |
<backingStore/> | |
</backingStore> | |
<target dev='vda' bus='virtio'/> | |
<alias name='virtio-disk0'/> | |
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> | |
</disk> | |
<controller type='usb' index='0' model='ich9-ehci1'> | |
<alias name='usb'/> | |
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x7'/> | |
</controller> | |
<controller type='usb' index='0' model='ich9-uhci1'> | |
<alias name='usb'/> | |
<master startport='0'/> | |
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' multifunction='on'/> | |
</controller> | |
<controller type='usb' index='0' model='ich9-uhci2'> | |
<alias name='usb'/> | |
<master startport='2'/> | |
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x1'/> | |
</controller> | |
<controller type='usb' index='0' model='ich9-uhci3'> | |
<alias name='usb'/> | |
<master startport='4'/> | |
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x2'/> | |
</controller> | |
<controller type='virtio-serial' index='0'> | |
<alias name='virtio-serial0'/> | |
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> | |
</controller> | |
<controller type='pci' index='0' model='pci-root'> | |
<alias name='pci.0'/> | |
</controller> | |
<controller type='ide' index='0'> | |
<alias name='ide'/> | |
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> | |
</controller> | |
<filesystem type='mount' accessmode='mapped'> | |
<source dir='$SHARE_DIR'/> | |
<target dir='share'/> | |
<alias name='fs0'/> | |
<address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> | |
</filesystem> | |
<interface type='network'> | |
<source network='default' bridge='virbr0'/> | |
<target dev='vnet0'/> | |
<model type='virtio'/> | |
<alias name='net0'/> | |
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> | |
</interface> | |
<serial type='pty'> | |
<source path='/dev/pts/3'/> | |
<target port='0'/> | |
<alias name='serial0'/> | |
</serial> | |
<console type='pty' tty='/dev/pts/3'> | |
<source path='/dev/pts/3'/> | |
<target type='serial' port='0'/> | |
<alias name='serial0'/> | |
</console> | |
<channel type='spicevmc'> | |
<target type='virtio' name='com.redhat.spice.0' state='connected'/> | |
<alias name='channel0'/> | |
<address type='virtio-serial' controller='0' bus='0' port='1'/> | |
</channel> | |
<channel type='unix'> | |
<source mode='bind'/> | |
<target type='virtio' name='org.qemu.guest_agent.0' state='disconnected'/> | |
<alias name='channel1'/> | |
<address type='virtio-serial' controller='0' bus='0' port='2'/> | |
</channel> | |
<input type='mouse' bus='ps2'> | |
<alias name='input0'/> | |
</input> | |
<input type='keyboard' bus='ps2'> | |
<alias name='input1'/> | |
</input> | |
<graphics type='spice' port='5900' autoport='yes' listen='127.0.0.1'> | |
<listen type='address' address='127.0.0.1'/> | |
<image compression='off'/> | |
</graphics> | |
<sound model='ich6'> | |
<alias name='sound0'/> | |
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> | |
</sound> | |
<video> | |
<model type='virtio' heads='1' primary='yes'> | |
<acceleration accel3d='no'/> | |
</model> | |
<alias name='video0'/> | |
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> | |
</video> | |
<redirdev bus='usb' type='spicevmc'> | |
<alias name='redir0'/> | |
<address type='usb' bus='0' port='1'/> | |
</redirdev> | |
<redirdev bus='usb' type='spicevmc'> | |
<alias name='redir1'/> | |
<address type='usb' bus='0' port='2'/> | |
</redirdev> | |
<memballoon model='virtio'> | |
<alias name='balloon0'/> | |
<address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/> | |
</memballoon> | |
</devices> | |
<seclabel type='none' model='none'/> | |
<seclabel type='dynamic' model='dac' relabel='yes'> | |
<label>+0:+0</label> | |
<imagelabel>+0:+0</imagelabel> | |
</seclabel> | |
</domain> | |
EOF | |
) | |
} | |
function startDomain() { | |
$VIRSH -c $LIBVIRT_URI start $1 | |
} | |
if ! listDomains "--all" | grep $PROJECT >/dev/null; then | |
if ! listVolumes $POOL | grep "nixos-17.03.qcow2" >/dev/null; then | |
echo "--> uploading base volume: nixos-17.03.qcow2" | |
image=$(nix-build --no-out-link -E "import <nixpkgs/nixos> { configuration = <xtruder/nix-profiles/images/qemu-img.nix>; }" -A config.system.build.qemu -j 4) | |
size=$(stat -Lc%s nixos) | |
$VIRSH -c $LIBVIRT_URI vol-create-as $POOL nixos-17.03.qcow2 --format qcow2 | |
$VIRSH vol-upload --pool $POOL nixos-17.03.qcow2 nixos-17.03.qcow2 | |
echo "# volume uploaded" | |
fi | |
echo "--> Creating root volume" | |
createBackedVolume nixos-17.03.qcow2 $PROJECT.qcow2 42 | |
echo "--> Creating domain" | |
createDomain "$PROJECT" 4 | |
fi | |
if ! listDomains | grep $PROJECT; then | |
echo "--> Starting domain" | |
startDomain "$PROJECT" | |
fi | |
echo "--> Getting IP" | |
ip=$(getIp "$PROJECT") | |
echo "#Ip: ${ip}" | |
echo "--> Waiting for ssh" | |
waitForSSH ${ip} | |
echo "--> Resizing root filesystem" | |
ssh -o ProxyJump="$LIBVIRT_HOST" root@${ip} resize2fs $ROOT_DEV | |
echo "--> Building system" | |
export NIXOS_CONFIG=$PWD/environments/$PROJECT.nix | |
system=$(nix-build -E 'import <nixpkgs/nixos> {}' -A system -j 4) | |
echo "# system: ${system}" | |
echo "--> Copy closure" | |
NIX_SSHOPTS="-o ProxyJump='$LIBVIRT_HOST'" nix-copy-closure --to root@${ip} $system | |
echo "--> Switching config" | |
ssh -o ProxyJump="$LIBVIRT_HOST" root@${ip} ${system}/bin/switch-to-configuration switch |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment