You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
8.8 KiB
238 lines
8.8 KiB
#!/usr/bin/env bash |
|
|
|
########################## |
|
# Deploy script used for initilizing an Arch based container on Proxmox |
|
# You should have cowsay installed because it's awesome! |
|
########################## |
|
|
|
# This will not work currently because of a bug somewhere along apparmour, |
|
# lxd, lcx, or systemd. Seems most of the blame is on apparmour who refuse |
|
# to do anything about it. Until that is fixed, this script will not work, |
|
# so say so instead of realizing the issue, forgetting about it after a few |
|
# weeks, then spending another few hours wondering what the hell is going |
|
# on, and then finding my original post on launchpad. |
|
# |
|
# If this is bypassed, you will get a container which when booting will |
|
# not have any network interface. |
|
echo " !!!!! THIS DOES NOT WORK WITH NEW PROXMOX !!!!!" |
|
echo " Check out hak8or post on https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/1811248" |
|
exit |
|
|
|
# Header for this script |
|
TITLE="Deployment_Script" |
|
DEPTH=0 |
|
if [[ $DEPTH == 0 ]]; then |
|
TAGSTR="-->" |
|
elif [[ $DEPTH == 1 ]]; then |
|
TAGSTR="--->" |
|
elif [[ $DEPTH == 2 ]]; then |
|
TAGSTR="----->" |
|
elif [[ $DEPTH == 3 ]]; then |
|
TAGSTR="------>" |
|
fi |
|
echo "====== $TITLE ======" |
|
|
|
# IP address of the Proxmox host |
|
PROXMOX_IP_ADDR=10.10.10.200 |
|
PROXMOX_PORT=2221 |
|
if [[ -z $PROXMOX_IP_ADDR ]]; then |
|
echo "$TAGSTR PROXMOX_IP_ADDR was not set!" |
|
exit |
|
fi |
|
|
|
# Verify we can talk to the proxmox host. |
|
REPLYFROMSERVER=$(ssh root@$PROXMOX_IP_ADDR -p $PROXMOX_PORT $"echo "Hello World"") |
|
if [[ $REPLYFROMSERVER != "Hello World" ]]; then |
|
echo "$TAGSTR Failed to verify SSH connectivty with proxmox host." |
|
exit |
|
fi |
|
|
|
# Retrieve the IP address of a container as IPv4,IPv6. Arg1 is the container ID. |
|
FN_get_IPaddr (){ |
|
# IPv6 address fetch. We can't use the -4 or -6 flags because escaping turns into a nightmare. |
|
IPv6ADDR=$(ssh root@$PROXMOX_IP_ADDR -p $PROXMOX_PORT "pct exec $1 ip addr show dev eth0 | grep \"inet6 fe80\"") |
|
IPv6ADDR=$(echo $IPv6ADDR | awk '{a=$2; split(a, b, "/"); print b[1]}') |
|
|
|
# IPv4 address fetch |
|
IPv4ADDR=$(ssh root@$PROXMOX_IP_ADDR -p $PROXMOX_PORT "pct exec $1 ip addr show dev eth0 | grep \"inet 10\"") |
|
IPv4ADDR=$(echo $IPv4ADDR | awk '{a=$2; split(a, b, "/"); print b[1]}') |
|
} |
|
|
|
# Run a script on the the proxmox container. Arg 1 is container ID, arg 2 is script file. |
|
# |
|
# This uses the proxmox host as a proxy, meaning it writes the script into the host, and |
|
# then copies from proxmox to the guest, and executes on the guest. Only useful when you |
|
# can't copy to script directly to the guest, like when ssh isn't running yet. |
|
# |
|
# Run script over SSH instead of using this when possible. For example: |
|
# ssh root@$IPv6ADDR 'bash -s' < somescript.sh |
|
FN_exec_script_proxy_container(){ |
|
scp -P $PROXMOX_PORT $2 root@$PROXMOX_IP_ADDR:/tmp/$2 > /dev/null |
|
|
|
ssh -p $PROXMOX_PORT root@$PROXMOX_IP_ADDR /usr/bin/env bash <<- AcRP030Cclfad6 |
|
pct push $1 /tmp/$2 /tmp/$2 > /dev/null |
|
pct exec $1 chmod +x /tmp/$2 |
|
pct exec $1 /tmp/$2 |
|
AcRP030Cclfad6 |
|
} |
|
|
|
# Runs a single script or copies the contents of a directory and executes a script that has |
|
# the same name as the directory but with the .sh extension appended. |
|
# |
|
# Arg1 is the file name, Arg2 is the ip address. |
|
FN_copyandorexec(){ |
|
# Check if it's just a normal file (not directory). |
|
if [[ -f $1 ]]; then |
|
ssh root@$2 'bash -s' < $1 |
|
fi |
|
|
|
# If it's a directory, copy the contents. |
|
if [[ -d $1 ]]; then |
|
# This may take a while, so let user know something is happening. |
|
echo "$TAGSTR Copying contents of $1" |
|
|
|
# Use Rsync in case it's many files. |
|
# Flag -a: Archive (recursive, copy symbolic links, modification times, etc) |
|
# Flag -z: Compress (use compression when sending) |
|
# Flag -e: specifies remote shell to use (to disable fingerprint verification) |
|
rsync -aze "ssh -q -o StrictHostKeyChecking=no" $1 root@[$2]:/tmp |
|
|
|
# Execute the presumed script inside the directory. |
|
ssh root@$2 "cd /tmp/$1; ./$1.sh" |
|
fi |
|
} |
|
|
|
# Check if we are referring to a specific container. |
|
if [[ $1 == "-ID" ]]; then |
|
# Make sure we have a container ID |
|
if [[ -z $2 ]]; then |
|
echo "$TAGSTR No container ID was given!" |
|
exit |
|
fi |
|
|
|
# Get the machines IPv4 and IPv6 address. |
|
FN_get_IPaddr $2 |
|
|
|
# Check if this is a snapshot operation |
|
if [[ $3 == "-snapshot" ]]; then |
|
# If no snapshot name given, abort. |
|
if [[ -z $4 ]]; then |
|
echo "$TAGSTR No snapshot name given!" |
|
exit |
|
fi |
|
|
|
# Check if the snapshot exists on proxmox for this VMID. |
|
SNAPSHOT_LIST=$(ssh -p $PROXMOX_PORT root@$PROXMOX_IP_ADDR "pct listsnapshot $2") |
|
SNAPSHOT_LIST=$(echo "$SNAPSHOT_LIST" | awk '{print $1}' | grep $4) |
|
if [[ -z $SNAPSHOT_LIST ]]; then |
|
# Create a snapshot with this name. |
|
echo "$TAGSTR Creating a snapshot called $4 for VMID $2!" |
|
ssh -p $PROXMOX_PORT root@$PROXMOX_IP_ADDR "pct snapshot $2 $4" |
|
else |
|
# Restore to the snapshot |
|
echo "$TAGSTR Rollbacking VMID $2 to snapshot $4!" |
|
ssh -p $PROXMOX_PORT root@$PROXMOX_IP_ADDR "pct rollback $2 $4" |
|
|
|
echo "$TAGSTR Starting VMID $2!" |
|
ssh -p $PROXMOX_PORT root@$PROXMOX_IP_ADDR "pct start $2" |
|
fi |
|
echo "$TAGSTR $IPv4ADDR, $IPv6ADDR" |
|
exit |
|
fi |
|
|
|
# Check if a script/dir was provided. |
|
if [[ -z $3 ]]; then |
|
# No script found, just return the ip address. |
|
echo "$IPv4ADDR, $IPv6ADDR" |
|
exit |
|
else |
|
# A script/dir was found, verify it exists. |
|
if [[ -e $3 ]]; then |
|
FN_copyandorexec $3 $IPv6ADDR |
|
echo "$TAGSTR $IPv4ADDR, $IPv6ADDR" |
|
exit |
|
else |
|
echo "$TAGSTR Directory or file $3 was not found." |
|
exit |
|
fi |
|
fi |
|
fi |
|
|
|
# Make sure SSH public key is in proxmox host. This overwrites if it exists. |
|
scp -P $PROXMOX_PORT $HOME/.ssh/id_rsa.pub root@$PROXMOX_IP_ADDR:/tmp/id_rsa.pub > /dev/null |
|
|
|
# No specific container was provided, so we create one. |
|
# Can pass small script like this: https://stackoverflow.com/a/3872762/516959 |
|
echo "$TAGSTR Creating container" |
|
VMID=$(ssh -p $PROXMOX_PORT root@$PROXMOX_IP_ADDR /usr/bin/env bash <<-'AcRP030CAlfad6' |
|
# use the highest VMID+1 as our new VMID. This returns 1 if no VMID's exist. |
|
VMID=$(pct list | awk 'NR > 1 {print $1}' | sort -nr | head -n1) |
|
VMID=$(($VMID + 1)) |
|
|
|
# VMID's less than 100 are for internal proxmox use, make sure we are >= 100. |
|
# This also could mean there were no proxmox boxes created. |
|
if [[ $VMID -lt 100 ]]; then |
|
VMID=100 |
|
fi |
|
|
|
# Get the IP Addresses |
|
CTIP=10.10.10.$(($VMID + 100))/24 |
|
CTGW=10.10.10.1 |
|
CTIPv6=2001:470:8a74::$(($VMID + 100))/64 |
|
CTGWv6=2001:470:8a74::1 |
|
|
|
# Create a new container with the VMID |
|
# Use Below to create a new container template. Can also right click in proxmox GUI |
|
# but that does not handle clearing pacman cache, etc. |
|
# https://forum.proxmox.com/threads/customize-a-lxc-template.23461/ |
|
# https://forum.proxmox.com/threads/lxc-create-template-from-existing-container.24239/ |
|
# For Arch linux: |
|
# 1. Login via pct enter instead of ssh |
|
# 2. Remove all contents of ~/.ssh folder |
|
# 3. Clear pacman cache with yay -Scc |
|
# 4. Exit and shutdown the container |
|
# 5. Remove Network interface via proxmox web GUI |
|
# 6. Create a backup (not snapshot!) |
|
# 7. Copy backup from /var/lib/vz/dump to /var/lib/vz/template/cache |
|
# 8. Rename file to better template name. |
|
TEMPLATE=archlinux_custombase_2-16-2019.tar.lzo |
|
#TEMPLATE=archlinux_custombase_4-24-2018.tar.lzo |
|
#TEMPLATE=archlinux-base_20170704-1_amd64.tar.gz |
|
#TEMPLATE=archlinux_bootstrapped_11-14-2017.tar.gz |
|
pct create $VMID /var/lib/vz/template/cache/$TEMPLATE -ssh-public-keys /tmp/id_rsa.pub -storage local-zfs -net0 name=eth0,bridge=vmbr2004,ip=$CTIP,gw=$CTGW,ip6=$CTIPv6,gw6=$CTGWv6, -ostype archlinux > /dev/null |
|
|
|
# Start the container. |
|
pct start $VMID > /dev/null |
|
|
|
# And say all went well. |
|
echo "$VMID" |
|
AcRP030CAlfad6 |
|
) |
|
|
|
# Send and execute our arch init script. |
|
FN_exec_script_proxy_container $VMID arch_setup.sh |
|
|
|
# Wait a bit for the vm to initilize fully. |
|
sleep 2 |
|
|
|
# Get the IPv4 and IPv6 addresses of our noew container. |
|
FN_get_IPaddr $VMID |
|
|
|
# Wipe the fingerprint of the host in case it was used earlier. |
|
ssh-keygen -R $IPv6ADDR > /dev/null |
|
ssh-keygen -R $IPv4ADDR > /dev/null |
|
|
|
# Run any potential secondary script. |
|
if [[ -n $1 ]]; then |
|
# A script was found, verify it exists. |
|
if [[ -e $1 ]]; then |
|
FN_copyandorexec $1 $IPv6ADDR |
|
else |
|
echo "$TAGSTR Directory or file $1 was not found." |
|
exit |
|
fi |
|
fi |
|
|
|
# Lastly, say we are done and what the IP address is to the terminal. |
|
echo "$TAGSTR Completed $TITLE" |
|
cowsay "Arch setup all done! VMID: $VMID, IPv4: $IPv4ADDR, IPv6: $IPv6ADDR"
|
|
|