Collection of scripts for interfacing with proxmox containers
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.

239 lines
8.8 KiB

  1. #!/usr/bin/env bash
  2. ##########################
  3. # Deploy script used for initilizing an Arch based container on Proxmox
  4. # You should have cowsay installed because it's awesome!
  5. ##########################
  6. # This will not work currently because of a bug somewhere along apparmour,
  7. # lxd, lcx, or systemd. Seems most of the blame is on apparmour who refuse
  8. # to do anything about it. Until that is fixed, this script will not work,
  9. # so say so instead of realizing the issue, forgetting about it after a few
  10. # weeks, then spending another few hours wondering what the hell is going
  11. # on, and then finding my original post on launchpad.
  12. #
  13. # If this is bypassed, you will get a container which when booting will
  14. # not have any network interface.
  15. echo " !!!!! THIS DOES NOT WORK WITH NEW PROXMOX !!!!!"
  16. echo " Check out hak8or post on https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/1811248"
  17. exit
  18. # Header for this script
  19. TITLE="Deployment_Script"
  20. DEPTH=0
  21. if [[ $DEPTH == 0 ]]; then
  22. TAGSTR="-->"
  23. elif [[ $DEPTH == 1 ]]; then
  24. TAGSTR="--->"
  25. elif [[ $DEPTH == 2 ]]; then
  26. TAGSTR="----->"
  27. elif [[ $DEPTH == 3 ]]; then
  28. TAGSTR="------>"
  29. fi
  30. echo "====== $TITLE ======"
  31. # IP address of the Proxmox host
  32. PROXMOX_IP_ADDR=10.10.10.200
  33. PROXMOX_PORT=2221
  34. if [[ -z $PROXMOX_IP_ADDR ]]; then
  35. echo "$TAGSTR PROXMOX_IP_ADDR was not set!"
  36. exit
  37. fi
  38. # Verify we can talk to the proxmox host.
  39. REPLYFROMSERVER=$(ssh root@$PROXMOX_IP_ADDR -p $PROXMOX_PORT $"echo "Hello World"")
  40. if [[ $REPLYFROMSERVER != "Hello World" ]]; then
  41. echo "$TAGSTR Failed to verify SSH connectivty with proxmox host."
  42. exit
  43. fi
  44. # Retrieve the IP address of a container as IPv4,IPv6. Arg1 is the container ID.
  45. FN_get_IPaddr (){
  46. # IPv6 address fetch. We can't use the -4 or -6 flags because escaping turns into a nightmare.
  47. IPv6ADDR=$(ssh root@$PROXMOX_IP_ADDR -p $PROXMOX_PORT "pct exec $1 ip addr show dev eth0 | grep \"inet6 fe80\"")
  48. IPv6ADDR=$(echo $IPv6ADDR | awk '{a=$2; split(a, b, "/"); print b[1]}')
  49. # IPv4 address fetch
  50. IPv4ADDR=$(ssh root@$PROXMOX_IP_ADDR -p $PROXMOX_PORT "pct exec $1 ip addr show dev eth0 | grep \"inet 10\"")
  51. IPv4ADDR=$(echo $IPv4ADDR | awk '{a=$2; split(a, b, "/"); print b[1]}')
  52. }
  53. # Run a script on the the proxmox container. Arg 1 is container ID, arg 2 is script file.
  54. #
  55. # This uses the proxmox host as a proxy, meaning it writes the script into the host, and
  56. # then copies from proxmox to the guest, and executes on the guest. Only useful when you
  57. # can't copy to script directly to the guest, like when ssh isn't running yet.
  58. #
  59. # Run script over SSH instead of using this when possible. For example:
  60. # ssh root@$IPv6ADDR 'bash -s' < somescript.sh
  61. FN_exec_script_proxy_container(){
  62. scp -P $PROXMOX_PORT $2 root@$PROXMOX_IP_ADDR:/tmp/$2 > /dev/null
  63. ssh -p $PROXMOX_PORT root@$PROXMOX_IP_ADDR /usr/bin/env bash <<- AcRP030Cclfad6
  64. pct push $1 /tmp/$2 /tmp/$2 > /dev/null
  65. pct exec $1 chmod +x /tmp/$2
  66. pct exec $1 /tmp/$2
  67. AcRP030Cclfad6
  68. }
  69. # Runs a single script or copies the contents of a directory and executes a script that has
  70. # the same name as the directory but with the .sh extension appended.
  71. #
  72. # Arg1 is the file name, Arg2 is the ip address.
  73. FN_copyandorexec(){
  74. # Check if it's just a normal file (not directory).
  75. if [[ -f $1 ]]; then
  76. ssh root@$2 'bash -s' < $1
  77. fi
  78. # If it's a directory, copy the contents.
  79. if [[ -d $1 ]]; then
  80. # This may take a while, so let user know something is happening.
  81. echo "$TAGSTR Copying contents of $1"
  82. # Use Rsync in case it's many files.
  83. # Flag -a: Archive (recursive, copy symbolic links, modification times, etc)
  84. # Flag -z: Compress (use compression when sending)
  85. # Flag -e: specifies remote shell to use (to disable fingerprint verification)
  86. rsync -aze "ssh -q -o StrictHostKeyChecking=no" $1 root@[$2]:/tmp
  87. # Execute the presumed script inside the directory.
  88. ssh root@$2 "cd /tmp/$1; ./$1.sh"
  89. fi
  90. }
  91. # Check if we are referring to a specific container.
  92. if [[ $1 == "-ID" ]]; then
  93. # Make sure we have a container ID
  94. if [[ -z $2 ]]; then
  95. echo "$TAGSTR No container ID was given!"
  96. exit
  97. fi
  98. # Get the machines IPv4 and IPv6 address.
  99. FN_get_IPaddr $2
  100. # Check if this is a snapshot operation
  101. if [[ $3 == "-snapshot" ]]; then
  102. # If no snapshot name given, abort.
  103. if [[ -z $4 ]]; then
  104. echo "$TAGSTR No snapshot name given!"
  105. exit
  106. fi
  107. # Check if the snapshot exists on proxmox for this VMID.
  108. SNAPSHOT_LIST=$(ssh -p $PROXMOX_PORT root@$PROXMOX_IP_ADDR "pct listsnapshot $2")
  109. SNAPSHOT_LIST=$(echo "$SNAPSHOT_LIST" | awk '{print $1}' | grep $4)
  110. if [[ -z $SNAPSHOT_LIST ]]; then
  111. # Create a snapshot with this name.
  112. echo "$TAGSTR Creating a snapshot called $4 for VMID $2!"
  113. ssh -p $PROXMOX_PORT root@$PROXMOX_IP_ADDR "pct snapshot $2 $4"
  114. else
  115. # Restore to the snapshot
  116. echo "$TAGSTR Rollbacking VMID $2 to snapshot $4!"
  117. ssh -p $PROXMOX_PORT root@$PROXMOX_IP_ADDR "pct rollback $2 $4"
  118. echo "$TAGSTR Starting VMID $2!"
  119. ssh -p $PROXMOX_PORT root@$PROXMOX_IP_ADDR "pct start $2"
  120. fi
  121. echo "$TAGSTR $IPv4ADDR, $IPv6ADDR"
  122. exit
  123. fi
  124. # Check if a script/dir was provided.
  125. if [[ -z $3 ]]; then
  126. # No script found, just return the ip address.
  127. echo "$IPv4ADDR, $IPv6ADDR"
  128. exit
  129. else
  130. # A script/dir was found, verify it exists.
  131. if [[ -e $3 ]]; then
  132. FN_copyandorexec $3 $IPv6ADDR
  133. echo "$TAGSTR $IPv4ADDR, $IPv6ADDR"
  134. exit
  135. else
  136. echo "$TAGSTR Directory or file $3 was not found."
  137. exit
  138. fi
  139. fi
  140. fi
  141. # Make sure SSH public key is in proxmox host. This overwrites if it exists.
  142. scp -P $PROXMOX_PORT $HOME/.ssh/id_rsa.pub root@$PROXMOX_IP_ADDR:/tmp/id_rsa.pub > /dev/null
  143. # No specific container was provided, so we create one.
  144. # Can pass small script like this: https://stackoverflow.com/a/3872762/516959
  145. echo "$TAGSTR Creating container"
  146. VMID=$(ssh -p $PROXMOX_PORT root@$PROXMOX_IP_ADDR /usr/bin/env bash <<-'AcRP030CAlfad6'
  147. # use the highest VMID+1 as our new VMID. This returns 1 if no VMID's exist.
  148. VMID=$(pct list | awk 'NR > 1 {print $1}' | sort -nr | head -n1)
  149. VMID=$(($VMID + 1))
  150. # VMID's less than 100 are for internal proxmox use, make sure we are >= 100.
  151. # This also could mean there were no proxmox boxes created.
  152. if [[ $VMID -lt 100 ]]; then
  153. VMID=100
  154. fi
  155. # Get the IP Addresses
  156. CTIP=10.10.10.$(($VMID + 100))/24
  157. CTGW=10.10.10.1
  158. CTIPv6=2001:470:8a74::$(($VMID + 100))/64
  159. CTGWv6=2001:470:8a74::1
  160. # Create a new container with the VMID
  161. # Use Below to create a new container template. Can also right click in proxmox GUI
  162. # but that does not handle clearing pacman cache, etc.
  163. # https://forum.proxmox.com/threads/customize-a-lxc-template.23461/
  164. # https://forum.proxmox.com/threads/lxc-create-template-from-existing-container.24239/
  165. # For Arch linux:
  166. # 1. Login via pct enter instead of ssh
  167. # 2. Remove all contents of ~/.ssh folder
  168. # 3. Clear pacman cache with yay -Scc
  169. # 4. Exit and shutdown the container
  170. # 5. Remove Network interface via proxmox web GUI
  171. # 6. Create a backup (not snapshot!)
  172. # 7. Copy backup from /var/lib/vz/dump to /var/lib/vz/template/cache
  173. # 8. Rename file to better template name.
  174. TEMPLATE=archlinux_custombase_2-16-2019.tar.lzo
  175. #TEMPLATE=archlinux_custombase_4-24-2018.tar.lzo
  176. #TEMPLATE=archlinux-base_20170704-1_amd64.tar.gz
  177. #TEMPLATE=archlinux_bootstrapped_11-14-2017.tar.gz
  178. 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
  179. # Start the container.
  180. pct start $VMID > /dev/null
  181. # And say all went well.
  182. echo "$VMID"
  183. AcRP030CAlfad6
  184. )
  185. # Send and execute our arch init script.
  186. FN_exec_script_proxy_container $VMID arch_setup.sh
  187. # Wait a bit for the vm to initilize fully.
  188. sleep 2
  189. # Get the IPv4 and IPv6 addresses of our noew container.
  190. FN_get_IPaddr $VMID
  191. # Wipe the fingerprint of the host in case it was used earlier.
  192. ssh-keygen -R $IPv6ADDR > /dev/null
  193. ssh-keygen -R $IPv4ADDR > /dev/null
  194. # Run any potential secondary script.
  195. if [[ -n $1 ]]; then
  196. # A script was found, verify it exists.
  197. if [[ -e $1 ]]; then
  198. FN_copyandorexec $1 $IPv6ADDR
  199. else
  200. echo "$TAGSTR Directory or file $1 was not found."
  201. exit
  202. fi
  203. fi
  204. # Lastly, say we are done and what the IP address is to the terminal.
  205. echo "$TAGSTR Completed $TITLE"
  206. cowsay "Arch setup all done! VMID: $VMID, IPv4: $IPv4ADDR, IPv6: $IPv6ADDR"