build.func 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. variables() {
  2. NSAPP=$(echo ${APP,,} | tr -d ' ')
  3. var_install="${NSAPP}-install"
  4. INTEGER='^[0-9]+([.][0-9]+)?$'
  5. }
  6. color() {
  7. YW=$(echo "\033[33m")
  8. BL=$(echo "\033[36m")
  9. RD=$(echo "\033[01;31m")
  10. BGN=$(echo "\033[4;92m")
  11. GN=$(echo "\033[1;92m")
  12. DGN=$(echo "\033[32m")
  13. CL=$(echo "\033[m")
  14. CM="${GN}✓${CL}"
  15. CROSS="${RD}✗${CL}"
  16. BFR="\\r\\033[K"
  17. HOLD="-"
  18. }
  19. catch_errors() {
  20. set -Eeuo pipefail
  21. trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
  22. }
  23. error_handler() {
  24. local exit_code="$?"
  25. local line_number="$1"
  26. local command="$2"
  27. local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
  28. echo -e "\n$error_message\n"
  29. }
  30. msg_info() {
  31. local msg="$1"
  32. echo -ne " ${HOLD} ${YW}${msg}..."
  33. }
  34. msg_ok() {
  35. local msg="$1"
  36. echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
  37. }
  38. msg_error() {
  39. local msg="$1"
  40. echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
  41. }
  42. pve_check() {
  43. if [ $(pveversion | grep -c "pve-manager/7\.[0-9]") -eq 0 ]; then
  44. echo -e "${CROSS} This version of Proxmox Virtual Environment is not supported"
  45. echo -e "Requires PVE Version 7.0 or higher"
  46. echo -e "Exiting..."
  47. sleep 2
  48. exit
  49. fi
  50. }
  51. arch_check() {
  52. if [ "$(dpkg --print-architecture)" != "amd64" ]; then
  53. echo -e "\n ${CROSS} This script will not work with PiMox! \n"
  54. echo -e "Exiting..."
  55. sleep 2
  56. exit
  57. fi
  58. }
  59. ssh_check() {
  60. if command -v pveversion >/dev/null 2>&1; then
  61. if [ -n "${SSH_CLIENT:+x}" ]; then
  62. if whiptail --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then
  63. echo "you've been warned"
  64. else
  65. clear
  66. exit
  67. fi
  68. fi
  69. fi
  70. }
  71. echo_default() {
  72. echo -e "${DGN}Using Distribution: ${BGN}$var_os${CL}"
  73. echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}"
  74. echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}"
  75. echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}"
  76. echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}"
  77. echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}"
  78. echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}"
  79. echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}"
  80. echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}"
  81. echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}"
  82. echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}"
  83. echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}"
  84. echo -e "${DGN}Disable IPv6: ${BGN}No${CL}"
  85. echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}"
  86. echo -e "${DGN}Using DNS Search Domain: ${BGN}Host${CL}"
  87. echo -e "${DGN}Using DNS Server Address: ${BGN}Host${CL}"
  88. echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}"
  89. echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}"
  90. echo -e "${DGN}Enable Root SSH Access: ${BGN}No${CL}"
  91. if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then
  92. echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}No${CL}"
  93. fi
  94. echo -e "${DGN}Enable Verbose Mode: ${BGN}No${CL}"
  95. echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}"
  96. }
  97. exit-script() {
  98. clear
  99. echo -e "⚠ User exited script \n"
  100. exit
  101. }
  102. advanced_settings() {
  103. whiptail --msgbox --title "Default distribution for $APP" "${var_os} \n${var_version} \n" 8 58
  104. if [ "$var_os" != "alpine" ]; then
  105. var_os=""
  106. while [ -z "$var_os" ]; do
  107. if var_os=$(whiptail --title "DISTRIBUTION" --radiolist "Choose Distribution:" 10 58 2 \
  108. "debian" "" OFF \
  109. "ubuntu" "" OFF \
  110. 3>&1 1>&2 2>&3); then
  111. if [ -n "$var_os" ]; then
  112. echo -e "${DGN}Using Distribution: ${BGN}$var_os${CL}"
  113. fi
  114. else
  115. exit-script
  116. fi
  117. done
  118. fi
  119. if [ "$var_os" == "debian" ]; then
  120. var_version="11"
  121. echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}"
  122. fi
  123. if [ "$var_os" == "ubuntu" ]; then
  124. var_version=""
  125. while [ -z "$var_version" ]; do
  126. if var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \
  127. "20.04" "Focal" OFF \
  128. "22.04" "Jammy" OFF \
  129. "22.10" "Kinetic" OFF \
  130. 3>&1 1>&2 2>&3); then
  131. if [ -n "$var_version" ]; then
  132. echo -e "${DGN}Using $var_os Version: ${BGN}$var_version${CL}"
  133. fi
  134. else
  135. exit-script
  136. fi
  137. done
  138. fi
  139. CT_TYPE=""
  140. while [ -z "$CT_TYPE" ]; do
  141. if CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist "Choose Type" 10 58 2 \
  142. "1" "Unprivileged" OFF \
  143. "0" "Privileged" OFF \
  144. 3>&1 1>&2 2>&3); then
  145. if [ -n "$CT_TYPE" ]; then
  146. echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}"
  147. fi
  148. else
  149. exit-script
  150. fi
  151. done
  152. if PW1=$(whiptail --inputbox "\nSet Root Password (needed for root ssh access)" 9 58 --title "PASSWORD(leave blank for automatic login)" 3>&1 1>&2 2>&3); then
  153. if [ -z $PW1 ]; then
  154. PW1="Automatic Login"
  155. PW=" "
  156. else
  157. PW="-password $PW1"
  158. fi
  159. echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}"
  160. else
  161. exit-script
  162. fi
  163. if CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" 3>&1 1>&2 2>&3); then
  164. if [ -z "$CT_ID" ]; then
  165. CT_ID="$NEXTID"
  166. echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"
  167. else
  168. echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"
  169. fi
  170. else
  171. exit
  172. fi
  173. if CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" 3>&1 1>&2 2>&3); then
  174. if [ -z "$CT_NAME" ]; then
  175. HN="$NSAPP"
  176. else
  177. HN=$(echo ${CT_NAME,,} | tr -d ' ')
  178. fi
  179. echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"
  180. else
  181. exit-script
  182. fi
  183. if DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" 3>&1 1>&2 2>&3); then
  184. if [ -z "$DISK_SIZE" ]; then
  185. DISK_SIZE="$var_disk"
  186. echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"
  187. else
  188. if ! [[ $DISK_SIZE =~ $INTEGER ]]; then
  189. echo -e "${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}"
  190. advanced_settings
  191. fi
  192. echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"
  193. fi
  194. else
  195. exit-script
  196. fi
  197. if CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" 3>&1 1>&2 2>&3); then
  198. if [ -z "$CORE_COUNT" ]; then
  199. CORE_COUNT="$var_cpu"
  200. echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"
  201. else
  202. echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"
  203. fi
  204. else
  205. exit-script
  206. fi
  207. if RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" 3>&1 1>&2 2>&3); then
  208. if [ -z "$RAM_SIZE" ]; then
  209. RAM_SIZE="$var_ram"
  210. echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"
  211. else
  212. echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"
  213. fi
  214. else
  215. exit-script
  216. fi
  217. if BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" 3>&1 1>&2 2>&3); then
  218. if [ -z "$BRG" ]; then
  219. BRG="vmbr0"
  220. echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"
  221. else
  222. echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"
  223. fi
  224. else
  225. exit-script
  226. fi
  227. while true; do
  228. NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address (/24)" 8 58 dhcp --title "IP ADDRESS" 3>&1 1>&2 2>&3)
  229. exit_status=$?
  230. if [ $exit_status -eq 0 ]; then
  231. if [ "$NET" = "dhcp" ]; then
  232. echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"
  233. break
  234. else
  235. if [[ "$NET" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then
  236. echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"
  237. break
  238. else
  239. whiptail --msgbox "$NET is an invalid IPv4 CIDR address. Please enter a valid IPv4 CIDR address or 'dhcp'" 8 58
  240. fi
  241. fi
  242. else
  243. exit-script
  244. fi
  245. done
  246. while true; do
  247. GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" 3>&1 1>&2 2>&3)
  248. exit_status=$?
  249. if [ $exit_status -eq 0 ]; then
  250. if [ -z "$GATE1" ]; then
  251. if [ "$NET" = "dhcp" ]; then
  252. GATE1="Default"
  253. GATE=""
  254. echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}"
  255. break
  256. else
  257. whiptail --msgbox "Since a static IP was used, a gateway IP address is mandatory." 8 58
  258. fi
  259. else
  260. if [[ "$GATE1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
  261. GATE=",gw=$GATE1"
  262. echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}"
  263. break
  264. else
  265. whiptail --msgbox "Invalid IP address. Please enter a valid IP address." 8 58
  266. fi
  267. fi
  268. else
  269. exit-script
  270. fi
  271. done
  272. if (whiptail --defaultno --title "IPv6" --yesno "Disable IPv6?" 10 58); then
  273. DISABLEIP6="yes"
  274. else
  275. DISABLEIP6="no"
  276. fi
  277. echo -e "${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}"
  278. if MTU1=$(whiptail --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" 3>&1 1>&2 2>&3); then
  279. if [ -z $MTU1 ]; then
  280. MTU1="Default"
  281. MTU=""
  282. else
  283. MTU=",mtu=$MTU1"
  284. fi
  285. echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}"
  286. else
  287. exit-script
  288. fi
  289. if SD=$(whiptail --inputbox "Set a DNS Search Domain (leave blank for HOST)" 8 58 --title "DNS Search Domain" 3>&1 1>&2 2>&3); then
  290. if [ -z $SD ]; then
  291. SX=Host
  292. SD=""
  293. else
  294. SX=$SD
  295. SD="-searchdomain=$SD"
  296. fi
  297. echo -e "${DGN}Using DNS Search Domain: ${BGN}$SX${CL}"
  298. else
  299. exit-script
  300. fi
  301. if NX=$(whiptail --inputbox "Set a DNS Server IP (leave blank for HOST)" 8 58 --title "DNS SERVER IP" 3>&1 1>&2 2>&3); then
  302. if [ -z $NX ]; then
  303. NX=Host
  304. NS=""
  305. else
  306. NS="-nameserver=$NX"
  307. fi
  308. echo -e "${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}"
  309. else
  310. exit-script
  311. fi
  312. if MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" 3>&1 1>&2 2>&3); then
  313. if [ -z $MAC1 ]; then
  314. MAC1="Default"
  315. MAC=""
  316. else
  317. MAC=",hwaddr=$MAC1"
  318. echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}"
  319. fi
  320. else
  321. exit-script
  322. fi
  323. if VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" 3>&1 1>&2 2>&3); then
  324. if [ -z $VLAN1 ]; then
  325. VLAN1="Default"
  326. VLAN=""
  327. else
  328. VLAN=",tag=$VLAN1"
  329. fi
  330. echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}"
  331. else
  332. exit-script
  333. fi
  334. if (whiptail --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then
  335. SSH="yes"
  336. else
  337. SSH="no"
  338. fi
  339. echo -e "${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}"
  340. if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then
  341. if (whiptail --defaultno --title "FUSE OVERLAYFS" --yesno "(ZFS) Enable Fuse Overlayfs?" 10 58); then
  342. FUSE="yes"
  343. else
  344. FUSE="no"
  345. fi
  346. echo -e "${DGN}Enable Fuse Overlayfs (ZFS): ${BGN}$FUSE${CL}"
  347. fi
  348. if (whiptail --defaultno --title "VERBOSE MODE" --yesno "Enable Verbose Mode?" 10 58); then
  349. VERB="yes"
  350. else
  351. VERB="no"
  352. fi
  353. echo -e "${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}"
  354. if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" 10 58); then
  355. echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}"
  356. else
  357. clear
  358. header_info
  359. echo -e "${RD}Using Advanced Settings${CL}"
  360. advanced_settings
  361. fi
  362. }
  363. install_script() {
  364. ssh_check
  365. arch_check
  366. pve_check
  367. if systemctl is-active -q ping-instances.service; then
  368. systemctl stop ping-instances.service
  369. fi
  370. NEXTID=$(pvesh get /cluster/nextid)
  371. timezone=$(cat /etc/timezone)
  372. header_info
  373. if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then
  374. header_info
  375. echo -e "${BL}Using Default Settings${CL}"
  376. default_settings
  377. else
  378. header_info
  379. echo -e "${RD}Using Advanced Settings${CL}"
  380. advanced_settings
  381. fi
  382. }
  383. start() {
  384. if command -v pveversion >/dev/null 2>&1; then
  385. if ! (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then
  386. clear
  387. echo -e "⚠ User exited script \n"
  388. exit
  389. fi
  390. install_script
  391. fi
  392. if ! command -v pveversion >/dev/null 2>&1; then
  393. if ! (whiptail --title "${APP} LXC UPDATE" --yesno "This will update ${APP} LXC. Proceed?" 10 58); then
  394. clear
  395. echo -e "⚠ User exited script \n"
  396. exit
  397. fi
  398. update_script
  399. fi
  400. }
  401. build_container() {
  402. if [ "$VERB" == "yes" ]; then set -x; fi
  403. if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then
  404. if [ "$FUSE" == "yes" ]; then
  405. FEATURES="fuse=1,keyctl=1,nesting=1"
  406. else
  407. FEATURES="keyctl=1,nesting=1"
  408. fi
  409. fi
  410. if [[ "$APP" != "Docker" && "$APP" != "Umbrel" && "$APP" != "CasaOS" && "$APP" != "Home Assistant" ]]; then
  411. if [ "$CT_TYPE" == "1" ]; then
  412. FEATURES="keyctl=1,nesting=1"
  413. else
  414. FEATURES="nesting=1"
  415. fi
  416. fi
  417. TEMP_DIR=$(mktemp -d)
  418. pushd $TEMP_DIR >/dev/null
  419. if [ "$var_os" == "alpine" ]; then
  420. export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine-install.func)"
  421. else
  422. export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)"
  423. fi
  424. export tz="$timezone"
  425. if [[ "$APP" == "Docker" || "$APP" == "Umbrel" || "$APP" == "CasaOS" || "$APP" == "Home Assistant" ]]; then
  426. export ST="$FUSE"
  427. fi
  428. export DISABLEIPV6="$DISABLEIP6"
  429. export APPLICATION="$APP"
  430. export VERBOSE="$VERB"
  431. export SSH_ROOT="${SSH}"
  432. export CTID="$CT_ID"
  433. export PCT_OSTYPE="$var_os"
  434. export PCT_OSVERSION="$var_version"
  435. export PCT_DISK_SIZE="$DISK_SIZE"
  436. export PCT_OPTIONS="
  437. -features $FEATURES
  438. -hostname $HN
  439. $SD
  440. $NS
  441. -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU
  442. -onboot 1
  443. -cores $CORE_COUNT
  444. -memory $RAM_SIZE
  445. -unprivileged $CT_TYPE
  446. $PW
  447. "
  448. bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit
  449. LXC_CONFIG=/etc/pve/lxc/${CTID}.conf
  450. if [ "$CT_TYPE" == "0" ]; then
  451. if [[ "$APP" != "Emby" && "$APP" != "Jellyfin" && "$APP" != "Plex" ]]; then
  452. cat <<EOF >>$LXC_CONFIG
  453. lxc.cgroup2.devices.allow: a
  454. lxc.cap.drop:
  455. lxc.cgroup2.devices.allow: c 188:* rwm
  456. lxc.cgroup2.devices.allow: c 189:* rwm
  457. lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir
  458. lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file
  459. lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file
  460. lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file
  461. lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file
  462. EOF
  463. fi
  464. fi
  465. if [ "$CT_TYPE" == "0" ]; then
  466. if [[ "$APP" == "Emby" || "$APP" == "Jellyfin" || "$APP" == "Plex" ]]; then
  467. cat <<EOF >>$LXC_CONFIG
  468. lxc.cgroup2.devices.allow: a
  469. lxc.cap.drop:
  470. lxc.cgroup2.devices.allow: c 226:0 rwm
  471. lxc.cgroup2.devices.allow: c 226:128 rwm
  472. lxc.cgroup2.devices.allow: c 29:0 rwm
  473. lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file
  474. lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir
  475. lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file
  476. EOF
  477. fi
  478. fi
  479. msg_info "Starting LXC Container"
  480. pct start "$CTID"
  481. msg_ok "Started LXC Container"
  482. if [ "$var_os" == "alpine" ]; then
  483. sleep 2
  484. pct exec "$CTID" -- ash -c "apk add bash >/dev/null"
  485. fi
  486. lxc-attach -n "$CTID" -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)" || exit
  487. }
  488. description() {
  489. IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1)
  490. pct set "$CTID" -description "# ${APP} LXC
  491. ### https://tteck.github.io/Proxmox/
  492. <a href='https://ko-fi.com/D1D7EP4GF'><img src='https://img.shields.io/badge/☕-Buy me a coffee-red' /></a>"
  493. if [[ -f /etc/systemd/system/ping-instances.service ]]; then
  494. systemctl start ping-instances.service
  495. fi
  496. }