nm-upgrade-0-17-1-to-0-19-0.sh 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. #!/bin/bash
  2. LATEST="v0.20.4"
  3. INSTALL_PATH="/root"
  4. trap restore_old_netmaker_instructions
  5. # check_version - make sure current version is 0.17.1 before continuing
  6. check_version() {
  7. IMG_TAG=$(yq -r '.services.netmaker.image' docker-compose.yml)
  8. if [[ "$IMG_TAG" == *"v0.17.1"* ]]; then
  9. echo "version is $IMG_TAG"
  10. else
  11. echo "error, current version is $IMG_TAG"
  12. echo "please upgrade to v0.17.1 in order to use the upgrade script"
  13. exit 1
  14. fi
  15. }
  16. backup_v17_files() {
  17. mkdir $INSTALL_PATH/netmaker_0.17.1_backup
  18. cp $INSTALL_PATH/docker-compose.yml $INSTALL_PATH/netmaker_0.17.1_backup/docker-compose.yml
  19. cp $INSTALL_PATH/Caddyfile $INSTALL_PATH/netmaker_0.17.1_backup/Caddyfile
  20. cp $INSTALL_PATH/mosquitto.conf $INSTALL_PATH/netmaker_0.17.1_backup/mosquitto.conf
  21. cp $INSTALL_PATH/wait.sh $INSTALL_PATH/netmaker_0.17.1_backup/wait.sh
  22. }
  23. backup_volumes() {
  24. # TODO backup to /root/nm-backup
  25. cp -r /var/lib/docker/volumes/root_caddy_conf/ /var/lib/docker/volumes/root_caddy_conf-backup/
  26. cp -r /var/lib/docker/volumes/root_caddy_data/ /var/lib/docker/volumes/root_caddy_data-backup/
  27. cp -r /var/lib/docker/volumes/root_dnsconfig/ /var/lib/docker/volumes/root_dnsconfig-backup/
  28. cp -r /var/lib/docker/volumes/root_mosquitto_data/ /var/lib/docker/volumes/root_mosquitto_data-backup/
  29. cp -r /var/lib/docker/volumes/root_mosquitto_logs/ /var/lib/docker/volumes/root_mosquitto_logs-backup/
  30. cp -r /var/lib/docker/volumes/root_sqldata/ /var/lib/docker/volumes/root_sqldata-backup/
  31. }
  32. restore_old_netmaker_instructions() {
  33. echo "There was a problem with the installation. Your config files and volumes have been backed up."
  34. echo "To restore Netmaker back to v0.17.1, copy all the netmaker volume backups (caddy_conf-backup, caddy_data-backup, dnsconfig-backup, mosquitto_data-backup, mosquitto_logs-backup, and sqldata-backup) back to their regular names with out the -backup."
  35. echo "Your config files should be located in ${INSTALL_PATH}/netmaker_0.17.1_backup. Simply run cp ${INSTALL_PATH}/netmaker_0.17.1_backup/* . (include the .) and run docker-compose up -d."
  36. echo "Your netmaker should be back to v0.17.1"
  37. }
  38. get_install_path() {
  39. echo "-----------------------------------------------------"
  40. echo "Is your docker-compose located in $INSTALL_PATH ?"
  41. echo "-----------------------------------------------------"
  42. select install_option in "yes" "no (enter manually)"; do
  43. case $REPLY in
  44. 1)
  45. echo "using $INSTALL_PATH for an installation path."
  46. break
  47. ;;
  48. 2)
  49. read -p "Enter path where your docker-compose is located: " install_path
  50. SERVER_HTTP_HOST=$install_path
  51. echo "using $INSTALL_PATH"
  52. break
  53. ;;
  54. *) echo "invalid option $REPLY";;
  55. esac
  56. done
  57. }
  58. # wait_seconds - wait a number of seconds, print a log
  59. wait_seconds() {
  60. for ((a=1; a <= $1; a++))
  61. do
  62. echo ". . ."
  63. sleep 1
  64. done
  65. }
  66. # confirm - confirm a choice, or exit script
  67. confirm() {
  68. while true; do
  69. read -p 'Does everything look right? [y/n]: ' yn
  70. case $yn in
  71. [Yy]* ) override="true"; break;;
  72. [Nn]* ) echo "exiting..."; exit 1;;
  73. * ) echo "Please answer yes or no.";;
  74. esac
  75. done
  76. }
  77. # install_dependencies - install system dependencies necessary for script to run
  78. install_dependencies() {
  79. OS=$(uname)
  80. if [ -f /etc/debian_version ]; then
  81. dependencies="jq wireguard jq dnsutils docker-compose"
  82. update_cmd='apt update'
  83. install_cmd='apt install -y'
  84. elif [ -f /etc/centos-release ]; then
  85. dependencies="wireguard jq bind-utils docker-compose"
  86. update_cmd='yum update'
  87. install_cmd='yum install -y'
  88. elif [ -f /etc/fedora-release ]; then
  89. dependencies="wireguard jq bind-utils docker-compose"
  90. update_cmd='dnf update'
  91. install_cmd='dnf install -y'
  92. elif [ -f /etc/redhat-release ]; then
  93. dependencies="wireguard jq bind-utils docker-compose"
  94. update_cmd='yum update'
  95. install_cmd='yum install -y'
  96. elif [ -f /etc/arch-release ]; then
  97. dependencies="wireguard-tools jq dnsutils docker-compose netclient"
  98. update_cmd='pacman -Sy'
  99. install_cmd='pacman -S --noconfirm'
  100. else
  101. echo "OS not supported for automatic install"
  102. exit 1
  103. fi
  104. set -- $dependencies
  105. if command -v docker >/dev/null 2>&1 ; then
  106. echo "Docker found"
  107. echo "version: $(docker version)"
  108. else
  109. echo "Docker not found. adding to dependencies"
  110. dependencies+=" docker.io"
  111. fi
  112. ${update_cmd}
  113. set +e
  114. while [ -n "$1" ]; do
  115. is_installed=$(dpkg-query -W --showformat='${Status}\n' $1 | grep "install ok installed")
  116. if [ "${is_installed}" != "" ]; then
  117. echo " " $1 is installed
  118. else
  119. echo " " $1 is not installed. Attempting install.
  120. ${install_cmd} $1
  121. sleep 5
  122. if [ "${OS}" = "OpenWRT" ] || [ "${OS}" = "TurrisOS" ]; then
  123. is_installed=$(opkg list-installed $1 | grep $1)
  124. else
  125. is_installed=$(dpkg-query -W --showformat='${Status}\n' $1 | grep "install ok installed")
  126. fi
  127. if [ "${is_installed}" != "" ]; then
  128. echo " " $1 is installed
  129. elif [ -x "$(command -v $1)" ]; then
  130. echo " " $1 is installed
  131. else
  132. echo " " FAILED TO INSTALL $1
  133. echo " " This may break functionality.
  134. fi
  135. fi
  136. shift
  137. done
  138. set -e
  139. echo "-----------------------------------------------------"
  140. echo "dependency install complete"
  141. echo "-----------------------------------------------------"
  142. }
  143. # install_yq - install yq if not present
  144. install_yq() {
  145. if ! command -v yq &> /dev/null; then
  146. wget -O /usr/bin/yq https://github.com/mikefarah/yq/releases/download/v4.31.1/yq_linux_$(dpkg --print-architecture)
  147. chmod +x /usr/bin/yq
  148. fi
  149. set +e
  150. if ! command -v yq &> /dev/null; then
  151. set -e
  152. wget -O /usr/bin/yq https://github.com/mikefarah/yq/releases/download/v4.31.1/yq_linux_amd64
  153. chmod +x /usr/bin/yq
  154. fi
  155. set -e
  156. if ! command -v yq &> /dev/null; then
  157. echo "failed to install yq. Please install yq and try again."
  158. echo "https://github.com/mikefarah/yq/#install"
  159. exit 1
  160. fi
  161. }
  162. # collect_server_settings - retrieve server settings from existing compose file
  163. collect_server_settings() {
  164. MASTER_KEY=$(yq -r .services.netmaker.environment.MASTER_KEY docker-compose.yml)
  165. echo "-----------------------------------------------------"
  166. echo "Is $MASTER_KEY the correct master key for your Netmaker installation?"
  167. echo "-----------------------------------------------------"
  168. select mkey_option in "yes" "no (enter manually)"; do
  169. case $REPLY in
  170. 1)
  171. echo "using $MASTER_KEY for master key"
  172. break
  173. ;;
  174. 2)
  175. read -p "Enter Master Key: " mkey
  176. MASTER_KEY=$mkey
  177. echo "using $MASTER_KEY"
  178. break
  179. ;;
  180. *) echo "invalid option $REPLY, choose 1 or 2";;
  181. esac
  182. done
  183. SERVER_HTTP_HOST=$(yq -r .services.netmaker.environment.SERVER_HTTP_HOST docker-compose.yml)
  184. echo "-----------------------------------------------------"
  185. echo "Is $SERVER_HTTP_HOST the correct api endpoint for your Netmaker installation?"
  186. echo "-----------------------------------------------------"
  187. select endpoint_option in "yes" "no (enter manually)"; do
  188. case $REPLY in
  189. 1)
  190. echo "using $SERVER_HTTP_HOST for api endpoint"
  191. break
  192. ;;
  193. 2)
  194. read -p "Enter API Endpoint: " endpoint
  195. SERVER_HTTP_HOST=$endpoint
  196. echo "using $SERVER_HTTP_HOST"
  197. break
  198. ;;
  199. *) echo "invalid option $REPLY";;
  200. esac
  201. done
  202. BROKER_NAME=$(yq -r .services.netmaker.environment.SERVER_NAME docker-compose.yml)
  203. echo "-----------------------------------------------------"
  204. echo "Is $BROKER_NAME the correct domain for your MQ broker?"
  205. echo "-----------------------------------------------------"
  206. select broker_option in "yes" "no (enter manually)"; do
  207. case $REPLY in
  208. 1)
  209. echo "using $BROKER_NAME for endpoint"
  210. break
  211. ;;
  212. 2)
  213. read -p "Enter Broker Domain: " broker
  214. BROKER_NAME=$broker
  215. echo "using $BROKER_NAME"
  216. break
  217. ;;
  218. *) echo "invalid option $REPLY";;
  219. esac
  220. done
  221. SERVER_NAME=${BROKER_NAME#"broker."}
  222. echo "-----------------------------------------------------"
  223. echo "Is $SERVER_NAME the correct base domain for your installation?"
  224. echo "-----------------------------------------------------"
  225. select domain_option in "yes" "no (enter manually)"; do
  226. case $REPLY in
  227. 1)
  228. echo "using $SERVER_NAME for domain"
  229. break
  230. ;;
  231. 2)
  232. read -p "Enter Server Domain: " broker
  233. SERVER_NAME=$server
  234. echo "using $SERVER_NAME"
  235. break
  236. ;;
  237. *) echo "invalid option $REPLY";;
  238. esac
  239. done
  240. TURN_DOMAIN="turn.$SERVER_NAME"
  241. TURNAPI_DOMAIN="turnapi.$SERVER_NAME"
  242. echo "-----------------------------------------------------"
  243. echo "Netmaker v0.19 requires new DNS entries for $STUN_DOMAIN, $TURN_DOMAIN, and $TURNAPI_DOMAIN."
  244. echo "Please confirm this is added to your DNS provider before continuing."
  245. echo "You can skip this step if using a wildcard DNS entry (e.g. *.$SERVER_NAME) or a nip.io address."
  246. echo "-----------------------------------------------------"
  247. confirm
  248. }
  249. # collect_node_settings - get existing server node configuration
  250. collect_node_settings() {
  251. curl -s -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://$SERVER_HTTP_HOST/api/nodes | jq -c '[ .[] | select(.isserver=="yes") ]' > nodejson.tmp
  252. NODE_LEN=$(jq length nodejson.tmp)
  253. HAS_INGRESS="no"
  254. HAS_RELAY="no"
  255. if [ "$NODE_LEN" -gt 0 ]; then
  256. echo "===SERVER NODES==="
  257. for i in $(seq 1 $NODE_LEN); do
  258. NUM=$(($i-1))
  259. echo " SERVER NODE $NUM:"
  260. echo " network: $(jq -r ".[$NUM].network" ./nodejson.tmp)"
  261. echo " name: $(jq -r ".[$NUM].name" ./nodejson.tmp)"
  262. echo " private ipv4: $(jq -r ".[$NUM].address" ./nodejson.tmp)"
  263. echo " private ipv6: $(jq -r ".[$NUM].address6" ./nodejson.tmp)"
  264. echo " is egress: $(jq -r ".[$NUM].isegressgateway" ./nodejson.tmp)"
  265. if [[ $(jq -r ".[$NUM].isegressgateway" ./nodejson.tmp) == "yes" ]]; then
  266. echo " egress range: $(jq -r ".[$NUM].egressgatewayranges" ./nodejson.tmp)"
  267. fi
  268. echo " is ingress: $(jq -r ".[$NUM].isingressgateway" ./nodejson.tmp)"
  269. if [[ $(jq -r ".[$NUM].isingressgateway" ./nodejson.tmp) == "yes" ]]; then
  270. HAS_INGRESS="yes"
  271. fi
  272. echo " is relay: $(jq -r ".[$NUM].isrelay" ./nodejson.tmp)"
  273. if [[ $(jq -r ".[$NUM].isrelay" ./nodejson.tmp) == "yes" ]]; then
  274. HAS_RELAY="yes"
  275. echo " relay addrs: $(jq -r ".[$NUM].relayaddrs" ./nodejson.tmp | tr -d '[]\n"[:space:]')"
  276. fi
  277. echo " is failover: $(jq -r ".[$NUM].failover" ./nodejson.tmp)"
  278. echo " ------------"
  279. done
  280. echo "=================="
  281. else
  282. echo "no nodes to parse"
  283. fi
  284. echo "Please confirm that the above output matches the server nodes in your Netmaker server."
  285. confirm
  286. if [[ $HAS_INGRESS == "yes" ]]; then
  287. echo "WARNING: Your server contains an Ingress Gateway. After upgrading, existing Ext Clients will be lost and must be recreated. Please confirm that you would like to continue."
  288. confirm
  289. fi
  290. if [[ $HAS_RELAY == "yes" ]]; then
  291. echo "WARNING: Your server contains a Relay. After upgrading, relay will be unset. Relay functionality has been moved to the 'host' level, and must be reconfigured once all machines are upgraded."
  292. confirm
  293. fi
  294. }
  295. # setup_caddy - updates Caddy with new info
  296. setup_caddy() {
  297. echo "backing up Caddyfile to ${INSTALL_PATH}/Caddyfile.backup"
  298. cp $INSTALL_PATH/Caddyfile $INSTALL_PATH/Caddyfile.backup
  299. if grep -wq "acme.zerossl.com/v2/DV90" Caddyfile; then
  300. echo "zerossl already set, continuing"
  301. else
  302. echo "editing Caddyfile"
  303. sed -i '0,/email/{s~email~acme_ca https://acme.zerossl.com/v2/DV90\n\t&~}' $INSTALL_PATH/Caddyfile
  304. fi
  305. cat <<EOT >> $INSTALL_PATH/Caddyfile
  306. # STUN
  307. https://$STUN_DOMAIN {
  308. reverse_proxy netmaker:3478
  309. }
  310. # TURN
  311. https://$TURN_DOMAIN {
  312. reverse_proxy netmaker:3479
  313. }
  314. #TURN API
  315. https://turnapi.$TURNAPI_DOMAIN {
  316. reverse_proxy http://host.docker.internal:8089
  317. }
  318. EOT
  319. }
  320. # set_mq_credentials - sets mq credentials
  321. set_mq_credentials() {
  322. unset GET_MQ_USERNAME
  323. unset GET_MQ_PASSWORD
  324. unset CONFIRM_MQ_PASSWORD
  325. echo "Enter Credentials For MQ..."
  326. read -p "MQ Username (click 'enter' to use 'netmaker'): " GET_MQ_USERNAME
  327. if [ -z "$GET_MQ_USERNAME" ]; then
  328. echo "using default username for mq"
  329. MQ_USERNAME="netmaker"
  330. else
  331. MQ_USERNAME="$GET_MQ_USERNAME"
  332. fi
  333. select domain_option in "Auto Generated Password" "Input Your Own Password"; do
  334. case $REPLY in
  335. 1)
  336. echo "generating random password for mq"
  337. MQ_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
  338. break
  339. ;;
  340. 2)
  341. while true
  342. do
  343. echo "Enter your Password For MQ: "
  344. read -s GET_MQ_PASSWORD
  345. echo "Enter your password again to confirm: "
  346. read -s CONFIRM_MQ_PASSWORD
  347. if [ ${GET_MQ_PASSWORD} != ${CONFIRM_MQ_PASSWORD} ]; then
  348. echo "wrong password entered, try again..."
  349. continue
  350. fi
  351. MQ_PASSWORD="$GET_MQ_PASSWORD"
  352. echo "MQ Password Saved Successfully!!"
  353. break
  354. done
  355. break
  356. ;;
  357. *) echo "invalid option $REPLY";;
  358. esac
  359. done
  360. }
  361. # set_turn_credentials - sets mq credentials
  362. set_turn_credentials() {
  363. unset GET_TURN_USERNAME
  364. unset GET_TURN_PASSWORD
  365. unset CONFIRM_TURN_PASSWORD
  366. echo "Enter Credentials For TURN..."
  367. read -p "TURN Username (click 'enter' to use 'netmaker'): " GET_TURN_USERNAME
  368. if [ -z "$GET_TURN_USERNAME" ]; then
  369. echo "using default username for turn"
  370. TURN_USERNAME="netmaker"
  371. else
  372. TURN_USERNAME="$GET_TURN_USERNAME"
  373. fi
  374. select domain_option in "Auto Generated Password" "Input Your Own Password"; do
  375. case $REPLY in
  376. 1)
  377. echo "generating random password for TURN"
  378. TURN_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
  379. break
  380. ;;
  381. 2)
  382. while true
  383. do
  384. echo "Enter your Password For TURN: "
  385. read -s GET_TURN_PASSWORD
  386. echo "Enter your password again to confirm: "
  387. read -s CONFIRM_TURN_PASSWORD
  388. if [ ${GET_TURN_PASSWORD} != ${CONFIRM_TURN_PASSWORD} ]; then
  389. echo "wrong password entered, try again..."
  390. continue
  391. fi
  392. TURN_PASSWORD="$GET_TURN_PASSWORD"
  393. echo "TURN Password Saved Successfully!!"
  394. break
  395. done
  396. break
  397. ;;
  398. *) echo "invalid option $REPLY";;
  399. esac
  400. done
  401. }
  402. # set_compose - set compose file with proper values
  403. set_compose() {
  404. set_mq_credentials
  405. set_turn_credentials
  406. echo "retrieving updated wait script and mosquitto conf"
  407. rm $INSTALL_PATH/wait.sh
  408. rm $INSTALL_PATH/mosquitto.conf
  409. wget -O $INSTALL_PATH/wait.sh https://raw.githubusercontent.com/gravitl/netmaker/master/docker/wait.sh
  410. chmod +x $INSTALL_PATH/wait.sh
  411. wget -O $INSTALL_PATH/mosquitto.conf https://raw.githubusercontent.com/gravitl/netmaker/master/docker/mosquitto.conf
  412. chmod +x $INSTALL_PATH/mosquitto.conf
  413. # DEV_TEMP
  414. sed -i "s/v0.17.1/$LATEST/g" $INSTALL_PATH/docker-compose.yml
  415. STUN_PORT=3478
  416. yq ".services.netmaker.environment.SERVER_NAME = \"$SERVER_NAME\"" -i $INSTALL_PATH/docker-compose.yml
  417. yq ".services.netmaker.environment += {\"BROKER_ENDPOINT\": \"wss://$BROKER_NAME\"}" -i $INSTALL_PATH/docker-compose.yml
  418. yq ".services.netmaker.environment += {\"SERVER_BROKER_ENDPOINT\": \"ws://mq:1883\"}" -i $INSTALL_PATH/docker-compose.yml
  419. yq ".services.netmaker.environment += {\"STUN_LIST\": \"$STUN_DOMAIN:$STUN_PORT,stun1.netmaker.io:3478,stun2.netmaker.io:3478,stun1.l.google.com:19302,stun2.l.google.com:19302\"}" -i $INSTALL_PATH/docker-compose.yml
  420. yq ".services.netmaker.environment += {\"MQ_USERNAME\": \"$MQ_USERNAME\"}" -i $INSTALL_PATH/docker-compose.yml
  421. yq ".services.netmaker.environment += {\"MQ_PASSWORD\": \"$MQ_PASSWORD\"}" -i $INSTALL_PATH/docker-compose.yml
  422. yq ".services.netmaker.environment += {\"TURN_SERVER_HOST\": \"turn.$SERVER_NAME\"}" -i $INSTALL_PATH/docker-compose.yml
  423. yq ".services.netmaker.environment += {\"TURN_SERVER_API_HOST\": \"turnapi.$SERVER_NAME\"}" -i $INSTALL_PATH/docker-compose.yml
  424. yq ".services.netmaker.environment += {\"TURN_USERNAME\": \"$TURN_USERNAME\"}" -i $INSTALL_PATH/docker-compose.yml
  425. yq ".services.netmaker.environment += {\"TURN_PASSWORD\": \"$TURN_PASSWORD\"}" -i $INSTALL_PATH/docker-compose.yml
  426. yq ".services.netmaker.environment += {\"STUN_PORT\": \"$STUN_PORT\"}" -i $INSTALL_PATH/docker-compose.yml
  427. yq ".services.netmaker.environment += {\"TURN_PORT\": \"3479\"}" -i $INSTALL_PATH/docker-compose.yml
  428. yq ".services.netmaker.environment += {\"USE_TURN\": \"true\"}" -i $INSTALL_PATH/docker-compose.yml
  429. yq ".services.netmaker.ports += \"3478:3478/udp\"" -i $INSTALL_PATH/docker-compose.yml
  430. yq ".services.mq.environment += {\"MQ_USERNAME\": \"$MQ_USERNAME\"}" -i $INSTALL_PATH/docker-compose.yml
  431. yq ".services.mq.environment += {\"MQ_PASSWORD\": \"$MQ_PASSWORD\"}" -i $INSTALL_PATH/docker-compose.yml
  432. yq ".services.turn += {\"container_name\": \"turn\"}" -i $INSTALL_PATH/docker-compose.yml
  433. yq ".services.turn += {\"image\": \"gravitl/turnserver:v1.0.0\"}" -i $INSTALL_PATH/docker-compose.yml
  434. yq ".services.turn += {\"network_mode\": \"host\"}" -i $INSTALL_PATH/docker-compose.yml
  435. yq ".services.turn.volumes += {\"turn_server:/etc/config\"}" -i $INSTALL_PATH/docker-compose.yml
  436. yq ".services.turn.environment += {\"DEBUG_MODE\": \"off\"}" -i $INSTALL_PATH/docker-compose.yml
  437. yq ".services.turn.environment += {\"VERBOSITY\": \"1\"}" -i $INSTALL_PATH/docker-compose.yml
  438. yq ".services.turn.environment += {\"TURN_PORT\": \"3479\"}" -i $INSTALL_PATH/docker-compose.yml
  439. yq ".services.turn.environment += {\"TURN_API_PORT\": \"8089\"}" -i $INSTALL_PATH/docker-compose.yml
  440. yq ".services.turn.environment += {\"CORS_ALLOWED_ORIGIN\": \"*\"}" -i $INSTALL_PATH/docker-compose.yml
  441. yq ".services.turn.environment += {\"TURN_SERVER_HOST\": \"$TURN_DOMAIN\"}" -i $INSTALL_PATH/docker-compose.yml
  442. yq ".services.turn.environment += {\"TURN_USERNAME\": \"$TURN_USERNAME\"}" -i $INSTALL_PATH/docker-compose.yml
  443. yq ".services.turn.environment += {\"TURN_PASSWORD\": \"$TURN_PASSWORD\"}" -i $INSTALL_PATH/docker-compose.yml
  444. yq ".services.volumes += {\".turn_server\": \"{}\"}" -i $INSTALL_PATH/docker-compose.yml
  445. #remove unnecessary ports
  446. yq eval 'del( .services.netmaker.ports[] | select(. == "51821*") )' -i $INSTALL_PATH/docker-compose.yml
  447. yq eval 'del( .services.mq.ports[] | select(. == "8883*") )' -i $INSTALL_PATH/docker-compose.yml
  448. yq eval 'del( .services.mq.ports[] | select(. == "1883*") )' -i $INSTALL_PATH/docker-compose.yml
  449. yq eval 'del( .services.mq.expose[] | select(. == "8883*") )' -i $INSTALL_PATH/docker-compose.yml
  450. yq eval 'del( .services.mq.expose[] | select(. == "1883*") )' -i $INSTALL_PATH/docker-compose.yml
  451. # delete unnecessary compose sections
  452. yq eval 'del(.services.netmaker.cap_add)' -i $INSTALL_PATH/docker-compose.yml
  453. yq eval 'del(.services.netmaker.sysctls)' -i $INSTALL_PATH/docker-compose.yml
  454. yq eval 'del(.services.netmaker.environment.MQ_ADMIN_PASSWORD)' -i $INSTALL_PATH/docker-compose.yml
  455. yq eval 'del(.services.netmaker.environment.MQ_HOST)' -i $INSTALL_PATH/docker-compose.yml
  456. yq eval 'del(.services.netmaker.environment.MQ_PORT)' -i $INSTALL_PATH/docker-compose.yml
  457. yq eval 'del(.services.netmaker.environment.MQ_SERVER_PORT)' -i $INSTALL_PATH/docker-compose.yml
  458. yq eval 'del(.services.netmaker.environment.PORT_FORWARD_SERVICES)' -i $INSTALL_PATH/docker-compose.yml
  459. yq eval 'del(.services.netmaker.environment.CLIENT_MODE)' -i $INSTALL_PATH/docker-compose.yml
  460. yq eval 'del(.services.netmaker.environment.HOST_NETWORK)' -i $INSTALL_PATH/docker-compose.yml
  461. yq eval 'del(.services.mq.environment.NETMAKER_SERVER_HOST)' -i $INSTALL_PATH/docker-compose.yml
  462. yq eval 'del( .services.netmaker.volumes[] | select(. == "mosquitto_data*") )' -i $INSTALL_PATH/docker-compose.yml
  463. yq eval 'del( .services.mq.volumes[] | select(. == "mosquitto_data*") )' -i $INSTALL_PATH/docker-compose.yml
  464. yq eval 'del( .volumes.mosquitto_data )' -i $INSTALL_PATH/docker-compose.yml
  465. }
  466. # start_containers - run docker-compose up -d
  467. start_containers() {
  468. docker-compose -f $INSTALL_PATH/docker-compose.yml up -d
  469. }
  470. # test_caddy - make sure caddy is working
  471. test_caddy() {
  472. echo "Testing Caddy setup (please be patient, this may take 1-2 minutes)"
  473. for i in 1 2 3 4 5 6 7 8
  474. do
  475. curlresponse=$(curl -vIs https://${SERVER_HTTP_HOST} 2>&1)
  476. if [[ "$i" == 8 ]]; then
  477. echo " Caddy is having an issue setting up certificates, please investigate (docker logs caddy)"
  478. echo " Exiting..."
  479. exit 1
  480. elif [[ "$curlresponse" == *"failed to verify the legitimacy of the server"* ]]; then
  481. echo " Certificates not yet configured, retrying..."
  482. elif [[ "$curlresponse" == *"left intact"* ]]; then
  483. echo " Certificates ok"
  484. break
  485. else
  486. secs=$(($i*5+10))
  487. echo " Issue establishing connection...retrying in $secs seconds..."
  488. fi
  489. sleep $secs
  490. done
  491. }
  492. # setup_netclient - adds netclient to docker-compose
  493. setup_netclient() {
  494. set +e
  495. netclient uninstall
  496. HAS_APT=false
  497. set -e
  498. if command -v apt >/dev/null; then
  499. HAS_APT=true
  500. fi
  501. set +e
  502. if [ "$HAS_APT" = "true" ]; then
  503. curl -sL 'https://apt.netmaker.org/gpg.key' | sudo tee /etc/apt/trusted.gpg.d/netclient.asc
  504. curl -sL 'https://apt.netmaker.org/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/netclient.list
  505. sudo apt update
  506. sudo apt install netclient
  507. else
  508. wget -O /tmp/netclient https://github.com/gravitl/netclient/releases/download/$LATEST/netclient_linux_amd64
  509. chmod +x /tmp/netclient
  510. /tmp/netclient install
  511. fi
  512. netclient register -t $KEY
  513. echo "waiting for client to become available"
  514. wait_seconds 10
  515. }
  516. # setup_nmctl - pulls nmctl and makes it executable
  517. setup_nmctl() {
  518. wget -O nmctl https://github.com/gravitl/netmaker/releases/download/$LATEST/nmctl-linux-amd64
  519. chmod +x nmctl
  520. echo "using server $SERVER_HTTP_HOST"
  521. echo "using master key $MASTER_KEY"
  522. ./nmctl context set default --endpoint="https://$SERVER_HTTP_HOST" --master_key="$MASTER_KEY"
  523. ./nmctl context use default
  524. RESP=$(./nmctl network list)
  525. if [[ $RESP == *"unauthorized"* ]]; then
  526. echo "Unable to properly configure NMCTL, exiting..."
  527. exit 1
  528. fi
  529. }
  530. # join_networks - joins netclient into the networks using old settings
  531. join_networks() {
  532. NODE_LEN=$(jq length nodejson.tmp)
  533. if [ "$NODE_LEN" -gt 0 ]; then
  534. for i in $(seq 1 $NODE_LEN); do
  535. HAS_INGRESS="no"
  536. HAS_EGRESS="no"
  537. EGRESS_RANGES=""
  538. HAS_RELAY="no"
  539. RELAY_ADDRS=""
  540. HAS_FAILOVER="no"
  541. NUM=$(($i-1))
  542. NETWORK=$(jq -r ".[$NUM].network" ./nodejson.tmp)
  543. echo " joining network $NETWORK with following settings. Please confirm:"
  544. echo " network: $(jq -r ".[$NUM].network" ./nodejson.tmp)"
  545. echo " name: $(jq -r ".[$NUM].name" ./nodejson.tmp)"
  546. echo " private ipv4: $(jq -r ".[$NUM].address" ./nodejson.tmp)"
  547. echo " private ipv6: $(jq -r ".[$NUM].address6" ./nodejson.tmp)"
  548. echo " is egress: $(jq -r ".[$NUM].isegressgateway" ./nodejson.tmp)"
  549. if [[ $(jq -r ".[$NUM].isegressgateway" ./nodejson.tmp) == "yes" ]]; then
  550. HAS_EGRESS="yes"
  551. echo " egress ranges: $(jq -r ".[$NUM].egressgatewayranges" ./nodejson.tmp | tr -d '[]\n"[:space:]')"
  552. EGRESS_RANGES=$(jq -r ".[$NUM].egressgatewayranges" ./nodejson.tmp | tr -d '[]\n"[:space:]')
  553. EGRESS_RANGES=${EGRESS_RANGES//0.0.0.0\/0/0.0.0.0\/5,8.0.0.0\/7,11.0.0.0\/8,12.0.0.0\/6,16.0.0.0\/4,32.0.0.0\/3,64.0.0.0\/2,128.0.0.0\/3,160.0.0.0\/5,168.0.0.0\/6,172.0.0.0\/12,172.32.0.0\/11,172.64.0.0\/10,172.128.0.0\/9,173.0.0.0\/8,174.0.0.0\/7,176.0.0.0\/4,192.0.0.0\/9,192.128.0.0\/11,192.160.0.0\/13,192.169.0.0\/16,192.170.0.0\/15,192.172.0.0\/14,192.176.0.0\/12,192.192.0.0\/10,193.0.0.0\/8,194.0.0.0\/7,196.0.0.0\/6,200.0.0.0\/5,208.0.0.0\/4}
  554. EGRESS_RANGES=${EGRESS_RANGES//0::\/0/}
  555. EGRESS_RANGES=${EGRESS_RANGES//,,/,}
  556. EGRESS_RANGES=`echo $EGRESS_RANGES | sed 's/,*$//g'`
  557. EGRESS_RANGES=`echo $EGRESS_RANGES | sed 's/^,*//g'`
  558. fi
  559. echo " is ingress: $(jq -r ".[$NUM].isingressgateway" ./nodejson.tmp)"
  560. if [[ $(jq -r ".[$NUM].isingressgateway" ./nodejson.tmp) == "yes" ]]; then
  561. HAS_INGRESS="yes"
  562. fi
  563. echo " is relay: $(jq -r ".[$NUM].isrelay" ./nodejson.tmp)"
  564. if [[ $(jq -r ".[$NUM].isrelay" ./nodejson.tmp) == "yes" ]]; then
  565. HAS_RELAY="yes"
  566. RELAY_ADDRS=$(jq -r ".[$NUM].relayaddrs" ./nodejson.tmp | tr -d '[]\n"[:space:]')
  567. fi
  568. echo " is failover: $(jq -r ".[$NUM].failover" ./nodejson.tmp)"
  569. if [[ $(jq -r ".[$NUM].failover" ./nodejson.tmp) == "yes" ]]; then
  570. HAS_FAILOVER="yes"
  571. fi
  572. echo " ------------"
  573. confirm
  574. if [[ $NUM -eq 0 ]]; then
  575. echo "running command: ./nmctl enrollment_key create --uses 1 --networks $NETWORK"
  576. KEY_JSON=$(./nmctl enrollment_key create --uses 1 --networks $NETWORK)
  577. KEY=$(jq -r '.token' <<< ${KEY_JSON})
  578. echo "enrollment key created: $KEY"
  579. setup_netclient
  580. else
  581. HOST_ID=$(sudo cat /etc/netclient/netclient.yml | yq -r .host.id)
  582. ./nmctl host add_network $HOST_ID $NETWORK
  583. fi
  584. NAME=$(jq -r ".[$NUM].name" ./nodejson.tmp)
  585. ADDRESS=$(jq -r ".[$NUM].address" ./nodejson.tmp)
  586. ADDRESS6=$(jq -r ".[$NUM].address6" ./nodejson.tmp)
  587. echo "wait 10 seconds for netclient to be ready"
  588. sleep 10
  589. NODE_ID=$(sudo cat /etc/netclient/nodes.yml | yq -r .$NETWORK.commonnode.id)
  590. echo "join complete. New node ID: $NODE_ID"
  591. if [[ $NUM -eq 0 ]]; then
  592. HOST_ID=$(sudo cat /etc/netclient/netclient.yml | yq -r .host.id)
  593. echo "For first join, making host a default"
  594. echo "Host ID: $HOST_ID"
  595. # set as a default host
  596. set +e
  597. ./nmctl host update $HOST_ID --default
  598. sleep 2
  599. set -e
  600. fi
  601. # create an egress if necessary
  602. if [[ $HAS_EGRESS == "yes" ]]; then
  603. echo "creating egress"
  604. ./nmctl node create_egress $NETWORK $NODE_ID $EGRESS_RANGES
  605. sleep 2
  606. fi
  607. echo "HAS INGRESS: $HAS_INGRESS"
  608. # create an ingress if necessary
  609. if [[ $HAS_INGRESS == "yes" ]]; then
  610. if [[ $HAS_FAILOVER == "yes" ]]; then
  611. echo "creating ingress and failover..."
  612. ./nmctl node create_ingress $NETWORK $NODE_ID --failover
  613. sleep 2
  614. else
  615. echo "creating ingress..."
  616. ./nmctl node create_ingress $NETWORK $NODE_ID
  617. sleep 2
  618. fi
  619. fi
  620. # relay
  621. if [[ $HAS_RELAY == "yes" ]]; then
  622. echo "cannot recreate relay; relay functionality moved to host"
  623. # ./nmctl node create_relay $NETWORK $NODE_ID $RELAY_ADDRS
  624. # sleep 2
  625. fi
  626. done
  627. echo "=================="
  628. else
  629. echo "no networks to join"
  630. fi
  631. }
  632. cat << "EOF"
  633. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  634. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  635. The Netmaker Upgrade Script: Upgrading to v0.18 so you don't have to!
  636. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  637. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  638. EOF
  639. set -e
  640. if [ $(id -u) -ne 0 ]; then
  641. echo "This script must be run as root"
  642. exit 1
  643. fi
  644. set +e
  645. #backup volumes and v0.17.1 configs in case of failure.
  646. backup_volumes
  647. backup_v17_files
  648. # get the installation path for docker-compose.yml and other config files
  649. get_install_path
  650. echo "...installing dependencies for script"
  651. install_dependencies
  652. echo "...installing yq if necessary"
  653. install_yq
  654. set -e
  655. echo "...confirming version is correct"
  656. check_version
  657. echo "...collecting necessary server settings"
  658. collect_server_settings
  659. echo "...setup nmctl"
  660. setup_nmctl
  661. echo "...retrieving current server node settings"
  662. collect_node_settings
  663. echo "...backing up docker compose to docker-compose.yml.backup"
  664. cp $INSTALL_PATH/docker-compose.yml $INSTALL_PATH/docker-compose.yml.backup
  665. echo "...setting Caddyfile values"
  666. setup_caddy
  667. echo "...setting docker-compose values"
  668. set_compose
  669. echo "...starting containers"
  670. start_containers
  671. echo "...remove old mosquitto data"
  672. # TODO - yq is not removing volume from docker compose
  673. # docker volume rm root_mosquitto_data
  674. wait_seconds 3
  675. echo "..testing Caddy proxy"
  676. test_caddy
  677. echo "..testing Netmaker health"
  678. # TODO, implement health check
  679. # netmaker_health_check
  680. # wait_seconds 2
  681. wait_seconds 2
  682. echo "...setup netclient"
  683. join_networks
  684. echo "-----------------------------------------------------------------"
  685. echo "-----------------------------------------------------------------"
  686. echo "Netmaker setup is now complete. You are ready to begin using Netmaker."
  687. echo "Visit dashboard.$SERVER_NAME to log in"
  688. echo "-----------------------------------------------------------------"
  689. echo "-----------------------------------------------------------------"