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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. #!/bin/bash
  2. LATEST="v0.20.2"
  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. STUN_DOMAIN="stun.$SERVER_NAME"
  241. TURN_DOMAIN="turn.$SERVER_NAME"
  242. TURNAPI_DOMAIN="turnapi.$SERVER_NAME"
  243. echo "-----------------------------------------------------"
  244. echo "Netmaker v0.19 requires new DNS entries for $STUN_DOMAIN, $TURN_DOMAIN, and $TURNAPI_DOMAIN."
  245. echo "Please confirm this is added to your DNS provider before continuing."
  246. echo "You can skip this step if using a wildcard DNS entry (e.g. *.$SERVER_NAME) or a nip.io address."
  247. echo "-----------------------------------------------------"
  248. confirm
  249. }
  250. # collect_node_settings - get existing server node configuration
  251. collect_node_settings() {
  252. 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
  253. NODE_LEN=$(jq length nodejson.tmp)
  254. HAS_INGRESS="no"
  255. HAS_RELAY="no"
  256. if [ "$NODE_LEN" -gt 0 ]; then
  257. echo "===SERVER NODES==="
  258. for i in $(seq 1 $NODE_LEN); do
  259. NUM=$(($i-1))
  260. echo " SERVER NODE $NUM:"
  261. echo " network: $(jq -r ".[$NUM].network" ./nodejson.tmp)"
  262. echo " name: $(jq -r ".[$NUM].name" ./nodejson.tmp)"
  263. echo " private ipv4: $(jq -r ".[$NUM].address" ./nodejson.tmp)"
  264. echo " private ipv6: $(jq -r ".[$NUM].address6" ./nodejson.tmp)"
  265. echo " is egress: $(jq -r ".[$NUM].isegressgateway" ./nodejson.tmp)"
  266. if [[ $(jq -r ".[$NUM].isegressgateway" ./nodejson.tmp) == "yes" ]]; then
  267. echo " egress range: $(jq -r ".[$NUM].egressgatewayranges" ./nodejson.tmp)"
  268. fi
  269. echo " is ingress: $(jq -r ".[$NUM].isingressgateway" ./nodejson.tmp)"
  270. if [[ $(jq -r ".[$NUM].isingressgateway" ./nodejson.tmp) == "yes" ]]; then
  271. HAS_INGRESS="yes"
  272. fi
  273. echo " is relay: $(jq -r ".[$NUM].isrelay" ./nodejson.tmp)"
  274. if [[ $(jq -r ".[$NUM].isrelay" ./nodejson.tmp) == "yes" ]]; then
  275. HAS_RELAY="yes"
  276. echo " relay addrs: $(jq -r ".[$NUM].relayaddrs" ./nodejson.tmp | tr -d '[]\n"[:space:]')"
  277. fi
  278. echo " is failover: $(jq -r ".[$NUM].failover" ./nodejson.tmp)"
  279. echo " ------------"
  280. done
  281. echo "=================="
  282. else
  283. echo "no nodes to parse"
  284. fi
  285. echo "Please confirm that the above output matches the server nodes in your Netmaker server."
  286. confirm
  287. if [[ $HAS_INGRESS == "yes" ]]; then
  288. 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."
  289. confirm
  290. fi
  291. if [[ $HAS_RELAY == "yes" ]]; then
  292. 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."
  293. confirm
  294. fi
  295. }
  296. # setup_caddy - updates Caddy with new info
  297. setup_caddy() {
  298. echo "backing up Caddyfile to ${INSTALL_PATH}/Caddyfile.backup"
  299. cp $INSTALL_PATH/Caddyfile $INSTALL_PATH/Caddyfile.backup
  300. if grep -wq "acme.zerossl.com/v2/DV90" Caddyfile; then
  301. echo "zerossl already set, continuing"
  302. else
  303. echo "editing Caddyfile"
  304. sed -i '0,/email/{s~email~acme_ca https://acme.zerossl.com/v2/DV90\n\t&~}' $INSTALL_PATH/Caddyfile
  305. fi
  306. cat <<EOT >> $INSTALL_PATH/Caddyfile
  307. # STUN
  308. https://$STUN_DOMAIN {
  309. reverse_proxy netmaker:3478
  310. }
  311. # TURN
  312. https://$TURN_DOMAIN {
  313. reverse_proxy netmaker:3479
  314. }
  315. #TURN API
  316. https://turnapi.$TURNAPI_DOMAIN {
  317. reverse_proxy http://host.docker.internal:8089
  318. }
  319. EOT
  320. }
  321. # set_mq_credentials - sets mq credentials
  322. set_mq_credentials() {
  323. unset GET_MQ_USERNAME
  324. unset GET_MQ_PASSWORD
  325. unset CONFIRM_MQ_PASSWORD
  326. echo "Enter Credentials For MQ..."
  327. read -p "MQ Username (click 'enter' to use 'netmaker'): " GET_MQ_USERNAME
  328. if [ -z "$GET_MQ_USERNAME" ]; then
  329. echo "using default username for mq"
  330. MQ_USERNAME="netmaker"
  331. else
  332. MQ_USERNAME="$GET_MQ_USERNAME"
  333. fi
  334. select domain_option in "Auto Generated Password" "Input Your Own Password"; do
  335. case $REPLY in
  336. 1)
  337. echo "generating random password for mq"
  338. MQ_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
  339. break
  340. ;;
  341. 2)
  342. while true
  343. do
  344. echo "Enter your Password For MQ: "
  345. read -s GET_MQ_PASSWORD
  346. echo "Enter your password again to confirm: "
  347. read -s CONFIRM_MQ_PASSWORD
  348. if [ ${GET_MQ_PASSWORD} != ${CONFIRM_MQ_PASSWORD} ]; then
  349. echo "wrong password entered, try again..."
  350. continue
  351. fi
  352. MQ_PASSWORD="$GET_MQ_PASSWORD"
  353. echo "MQ Password Saved Successfully!!"
  354. break
  355. done
  356. break
  357. ;;
  358. *) echo "invalid option $REPLY";;
  359. esac
  360. done
  361. }
  362. # set_turn_credentials - sets mq credentials
  363. set_turn_credentials() {
  364. unset GET_TURN_USERNAME
  365. unset GET_TURN_PASSWORD
  366. unset CONFIRM_TURN_PASSWORD
  367. echo "Enter Credentials For TURN..."
  368. read -p "TURN Username (click 'enter' to use 'netmaker'): " GET_TURN_USERNAME
  369. if [ -z "$GET_TURN_USERNAME" ]; then
  370. echo "using default username for turn"
  371. TURN_USERNAME="netmaker"
  372. else
  373. TURN_USERNAME="$GET_TURN_USERNAME"
  374. fi
  375. select domain_option in "Auto Generated Password" "Input Your Own Password"; do
  376. case $REPLY in
  377. 1)
  378. echo "generating random password for TURN"
  379. TURN_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
  380. break
  381. ;;
  382. 2)
  383. while true
  384. do
  385. echo "Enter your Password For TURN: "
  386. read -s GET_TURN_PASSWORD
  387. echo "Enter your password again to confirm: "
  388. read -s CONFIRM_TURN_PASSWORD
  389. if [ ${GET_TURN_PASSWORD} != ${CONFIRM_TURN_PASSWORD} ]; then
  390. echo "wrong password entered, try again..."
  391. continue
  392. fi
  393. TURN_PASSWORD="$GET_TURN_PASSWORD"
  394. echo "TURN Password Saved Successfully!!"
  395. break
  396. done
  397. break
  398. ;;
  399. *) echo "invalid option $REPLY";;
  400. esac
  401. done
  402. }
  403. # set_compose - set compose file with proper values
  404. set_compose() {
  405. set_mq_credentials
  406. set_turn_credentials
  407. echo "retrieving updated wait script and mosquitto conf"
  408. rm $INSTALL_PATH/wait.sh
  409. rm $INSTALL_PATH/mosquitto.conf
  410. wget -O $INSTALL_PATH/wait.sh https://raw.githubusercontent.com/gravitl/netmaker/master/docker/wait.sh
  411. chmod +x $INSTALL_PATH/wait.sh
  412. wget -O $INSTALL_PATH/mosquitto.conf https://raw.githubusercontent.com/gravitl/netmaker/master/docker/mosquitto.conf
  413. chmod +x $INSTALL_PATH/mosquitto.conf
  414. # DEV_TEMP
  415. sed -i "s/v0.17.1/$LATEST/g" $INSTALL_PATH/docker-compose.yml
  416. STUN_PORT=3478
  417. yq ".services.netmaker.environment.SERVER_NAME = \"$SERVER_NAME\"" -i $INSTALL_PATH/docker-compose.yml
  418. yq ".services.netmaker.environment += {\"BROKER_ENDPOINT\": \"wss://$BROKER_NAME\"}" -i $INSTALL_PATH/docker-compose.yml
  419. yq ".services.netmaker.environment += {\"SERVER_BROKER_ENDPOINT\": \"ws://mq:1883\"}" -i $INSTALL_PATH/docker-compose.yml
  420. 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
  421. yq ".services.netmaker.environment += {\"MQ_USERNAME\": \"$MQ_USERNAME\"}" -i $INSTALL_PATH/docker-compose.yml
  422. yq ".services.netmaker.environment += {\"MQ_PASSWORD\": \"$MQ_PASSWORD\"}" -i $INSTALL_PATH/docker-compose.yml
  423. yq ".services.netmaker.environment += {\"TURN_SERVER_HOST\": \"turn.$SERVER_NAME\"}" -i $INSTALL_PATH/docker-compose.yml
  424. yq ".services.netmaker.environment += {\"TURN_SERVER_API_HOST\": \"turnapi.$SERVER_NAME\"}" -i $INSTALL_PATH/docker-compose.yml
  425. yq ".services.netmaker.environment += {\"TURN_USERNAME\": \"$TURN_USERNAME\"}" -i $INSTALL_PATH/docker-compose.yml
  426. yq ".services.netmaker.environment += {\"TURN_PASSWORD\": \"$TURN_PASSWORD\"}" -i $INSTALL_PATH/docker-compose.yml
  427. yq ".services.netmaker.environment += {\"STUN_PORT\": \"$STUN_PORT\"}" -i $INSTALL_PATH/docker-compose.yml
  428. yq ".services.netmaker.environment += {\"TURN_PORT\": \"3479\"}" -i $INSTALL_PATH/docker-compose.yml
  429. yq ".services.netmaker.environment += {\"USE_TURN\": \"true\"}" -i $INSTALL_PATH/docker-compose.yml
  430. yq ".services.netmaker.ports += \"3478:3478/udp\"" -i $INSTALL_PATH/docker-compose.yml
  431. yq ".services.mq.environment += {\"MQ_USERNAME\": \"$MQ_USERNAME\"}" -i $INSTALL_PATH/docker-compose.yml
  432. yq ".services.mq.environment += {\"MQ_PASSWORD\": \"$MQ_PASSWORD\"}" -i $INSTALL_PATH/docker-compose.yml
  433. yq ".services.turn += {\"container_name\": \"turn\"}" -i $INSTALL_PATH/docker-compose.yml
  434. yq ".services.turn += {\"image\": \"gravitl/turnserver:v1.0.0\"}" -i $INSTALL_PATH/docker-compose.yml
  435. yq ".services.turn += {\"network_mode\": \"host\"}" -i $INSTALL_PATH/docker-compose.yml
  436. yq ".services.turn.volumes += {\"turn_server:/etc/config\"}" -i $INSTALL_PATH/docker-compose.yml
  437. yq ".services.turn.environment += {\"DEBUG_MODE\": \"off\"}" -i $INSTALL_PATH/docker-compose.yml
  438. yq ".services.turn.environment += {\"VERBOSITY\": \"1\"}" -i $INSTALL_PATH/docker-compose.yml
  439. yq ".services.turn.environment += {\"TURN_PORT\": \"3479\"}" -i $INSTALL_PATH/docker-compose.yml
  440. yq ".services.turn.environment += {\"TURN_API_PORT\": \"8089\"}" -i $INSTALL_PATH/docker-compose.yml
  441. yq ".services.turn.environment += {\"CORS_ALLOWED_ORIGIN\": \"*\"}" -i $INSTALL_PATH/docker-compose.yml
  442. yq ".services.turn.environment += {\"TURN_SERVER_HOST\": \"$TURN_DOMAIN\"}" -i $INSTALL_PATH/docker-compose.yml
  443. yq ".services.turn.environment += {\"TURN_USERNAME\": \"$TURN_USERNAME\"}" -i $INSTALL_PATH/docker-compose.yml
  444. yq ".services.turn.environment += {\"TURN_PASSWORD\": \"$TURN_PASSWORD\"}" -i $INSTALL_PATH/docker-compose.yml
  445. yq ".services.volumes += {\".turn_server\": \"{}\"}" -i $INSTALL_PATH/docker-compose.yml
  446. #remove unnecessary ports
  447. yq eval 'del( .services.netmaker.ports[] | select(. == "51821*") )' -i $INSTALL_PATH/docker-compose.yml
  448. yq eval 'del( .services.mq.ports[] | select(. == "8883*") )' -i $INSTALL_PATH/docker-compose.yml
  449. yq eval 'del( .services.mq.ports[] | select(. == "1883*") )' -i $INSTALL_PATH/docker-compose.yml
  450. yq eval 'del( .services.mq.expose[] | select(. == "8883*") )' -i $INSTALL_PATH/docker-compose.yml
  451. yq eval 'del( .services.mq.expose[] | select(. == "1883*") )' -i $INSTALL_PATH/docker-compose.yml
  452. # delete unnecessary compose sections
  453. yq eval 'del(.services.netmaker.cap_add)' -i $INSTALL_PATH/docker-compose.yml
  454. yq eval 'del(.services.netmaker.sysctls)' -i $INSTALL_PATH/docker-compose.yml
  455. yq eval 'del(.services.netmaker.environment.MQ_ADMIN_PASSWORD)' -i $INSTALL_PATH/docker-compose.yml
  456. yq eval 'del(.services.netmaker.environment.MQ_HOST)' -i $INSTALL_PATH/docker-compose.yml
  457. yq eval 'del(.services.netmaker.environment.MQ_PORT)' -i $INSTALL_PATH/docker-compose.yml
  458. yq eval 'del(.services.netmaker.environment.MQ_SERVER_PORT)' -i $INSTALL_PATH/docker-compose.yml
  459. yq eval 'del(.services.netmaker.environment.PORT_FORWARD_SERVICES)' -i $INSTALL_PATH/docker-compose.yml
  460. yq eval 'del(.services.netmaker.environment.CLIENT_MODE)' -i $INSTALL_PATH/docker-compose.yml
  461. yq eval 'del(.services.netmaker.environment.HOST_NETWORK)' -i $INSTALL_PATH/docker-compose.yml
  462. yq eval 'del(.services.mq.environment.NETMAKER_SERVER_HOST)' -i $INSTALL_PATH/docker-compose.yml
  463. yq eval 'del( .services.netmaker.volumes[] | select(. == "mosquitto_data*") )' -i $INSTALL_PATH/docker-compose.yml
  464. yq eval 'del( .services.mq.volumes[] | select(. == "mosquitto_data*") )' -i $INSTALL_PATH/docker-compose.yml
  465. yq eval 'del( .volumes.mosquitto_data )' -i $INSTALL_PATH/docker-compose.yml
  466. }
  467. # start_containers - run docker-compose up -d
  468. start_containers() {
  469. docker-compose -f $INSTALL_PATH/docker-compose.yml up -d
  470. }
  471. # test_caddy - make sure caddy is working
  472. test_caddy() {
  473. echo "Testing Caddy setup (please be patient, this may take 1-2 minutes)"
  474. for i in 1 2 3 4 5 6 7 8
  475. do
  476. curlresponse=$(curl -vIs https://${SERVER_HTTP_HOST} 2>&1)
  477. if [[ "$i" == 8 ]]; then
  478. echo " Caddy is having an issue setting up certificates, please investigate (docker logs caddy)"
  479. echo " Exiting..."
  480. exit 1
  481. elif [[ "$curlresponse" == *"failed to verify the legitimacy of the server"* ]]; then
  482. echo " Certificates not yet configured, retrying..."
  483. elif [[ "$curlresponse" == *"left intact"* ]]; then
  484. echo " Certificates ok"
  485. break
  486. else
  487. secs=$(($i*5+10))
  488. echo " Issue establishing connection...retrying in $secs seconds..."
  489. fi
  490. sleep $secs
  491. done
  492. }
  493. # setup_netclient - adds netclient to docker-compose
  494. setup_netclient() {
  495. set +e
  496. netclient uninstall
  497. HAS_APT=false
  498. set -e
  499. if command -v apt >/dev/null; then
  500. HAS_APT=true
  501. fi
  502. set +e
  503. if [ "$HAS_APT" = "true" ]; then
  504. curl -sL 'https://apt.netmaker.org/gpg.key' | sudo tee /etc/apt/trusted.gpg.d/netclient.asc
  505. curl -sL 'https://apt.netmaker.org/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/netclient.list
  506. sudo apt update
  507. sudo apt install netclient
  508. else
  509. wget -O /tmp/netclient https://github.com/gravitl/netclient/releases/download/$LATEST/netclient_linux_amd64
  510. chmod +x /tmp/netclient
  511. /tmp/netclient install
  512. fi
  513. netclient register -t $KEY
  514. echo "waiting for client to become available"
  515. wait_seconds 10
  516. }
  517. # setup_nmctl - pulls nmctl and makes it executable
  518. setup_nmctl() {
  519. wget -O nmctl https://github.com/gravitl/netmaker/releases/download/$LATEST/nmctl-linux-amd64
  520. chmod +x nmctl
  521. echo "using server $SERVER_HTTP_HOST"
  522. echo "using master key $MASTER_KEY"
  523. ./nmctl context set default --endpoint="https://$SERVER_HTTP_HOST" --master_key="$MASTER_KEY"
  524. ./nmctl context use default
  525. RESP=$(./nmctl network list)
  526. if [[ $RESP == *"unauthorized"* ]]; then
  527. echo "Unable to properly configure NMCTL, exiting..."
  528. exit 1
  529. fi
  530. }
  531. # join_networks - joins netclient into the networks using old settings
  532. join_networks() {
  533. NODE_LEN=$(jq length nodejson.tmp)
  534. if [ "$NODE_LEN" -gt 0 ]; then
  535. for i in $(seq 1 $NODE_LEN); do
  536. HAS_INGRESS="no"
  537. HAS_EGRESS="no"
  538. EGRESS_RANGES=""
  539. HAS_RELAY="no"
  540. RELAY_ADDRS=""
  541. HAS_FAILOVER="no"
  542. NUM=$(($i-1))
  543. NETWORK=$(jq -r ".[$NUM].network" ./nodejson.tmp)
  544. echo " joining network $NETWORK with following settings. Please confirm:"
  545. echo " network: $(jq -r ".[$NUM].network" ./nodejson.tmp)"
  546. echo " name: $(jq -r ".[$NUM].name" ./nodejson.tmp)"
  547. echo " private ipv4: $(jq -r ".[$NUM].address" ./nodejson.tmp)"
  548. echo " private ipv6: $(jq -r ".[$NUM].address6" ./nodejson.tmp)"
  549. echo " is egress: $(jq -r ".[$NUM].isegressgateway" ./nodejson.tmp)"
  550. if [[ $(jq -r ".[$NUM].isegressgateway" ./nodejson.tmp) == "yes" ]]; then
  551. HAS_EGRESS="yes"
  552. echo " egress ranges: $(jq -r ".[$NUM].egressgatewayranges" ./nodejson.tmp | tr -d '[]\n"[:space:]')"
  553. EGRESS_RANGES=$(jq -r ".[$NUM].egressgatewayranges" ./nodejson.tmp | tr -d '[]\n"[:space:]')
  554. 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}
  555. EGRESS_RANGES=${EGRESS_RANGES//0::\/0/}
  556. EGRESS_RANGES=${EGRESS_RANGES//,,/,}
  557. EGRESS_RANGES=`echo $EGRESS_RANGES | sed 's/,*$//g'`
  558. EGRESS_RANGES=`echo $EGRESS_RANGES | sed 's/^,*//g'`
  559. fi
  560. echo " is ingress: $(jq -r ".[$NUM].isingressgateway" ./nodejson.tmp)"
  561. if [[ $(jq -r ".[$NUM].isingressgateway" ./nodejson.tmp) == "yes" ]]; then
  562. HAS_INGRESS="yes"
  563. fi
  564. echo " is relay: $(jq -r ".[$NUM].isrelay" ./nodejson.tmp)"
  565. if [[ $(jq -r ".[$NUM].isrelay" ./nodejson.tmp) == "yes" ]]; then
  566. HAS_RELAY="yes"
  567. RELAY_ADDRS=$(jq -r ".[$NUM].relayaddrs" ./nodejson.tmp | tr -d '[]\n"[:space:]')
  568. fi
  569. echo " is failover: $(jq -r ".[$NUM].failover" ./nodejson.tmp)"
  570. if [[ $(jq -r ".[$NUM].failover" ./nodejson.tmp) == "yes" ]]; then
  571. HAS_FAILOVER="yes"
  572. fi
  573. echo " ------------"
  574. confirm
  575. if [[ $NUM -eq 0 ]]; then
  576. echo "running command: ./nmctl enrollment_key create --uses 1 --networks $NETWORK"
  577. KEY_JSON=$(./nmctl enrollment_key create --uses 1 --networks $NETWORK)
  578. KEY=$(jq -r '.token' <<< ${KEY_JSON})
  579. echo "enrollment key created: $KEY"
  580. setup_netclient
  581. else
  582. HOST_ID=$(sudo cat /etc/netclient/netclient.yml | yq -r .host.id)
  583. ./nmctl host add_network $HOST_ID $NETWORK
  584. fi
  585. NAME=$(jq -r ".[$NUM].name" ./nodejson.tmp)
  586. ADDRESS=$(jq -r ".[$NUM].address" ./nodejson.tmp)
  587. ADDRESS6=$(jq -r ".[$NUM].address6" ./nodejson.tmp)
  588. echo "wait 10 seconds for netclient to be ready"
  589. sleep 10
  590. NODE_ID=$(sudo cat /etc/netclient/nodes.yml | yq -r .$NETWORK.commonnode.id)
  591. echo "join complete. New node ID: $NODE_ID"
  592. if [[ $NUM -eq 0 ]]; then
  593. HOST_ID=$(sudo cat /etc/netclient/netclient.yml | yq -r .host.id)
  594. echo "For first join, making host a default"
  595. echo "Host ID: $HOST_ID"
  596. # set as a default host
  597. set +e
  598. ./nmctl host update $HOST_ID --default
  599. sleep 2
  600. set -e
  601. fi
  602. # create an egress if necessary
  603. if [[ $HAS_EGRESS == "yes" ]]; then
  604. echo "creating egress"
  605. ./nmctl node create_egress $NETWORK $NODE_ID $EGRESS_RANGES
  606. sleep 2
  607. fi
  608. echo "HAS INGRESS: $HAS_INGRESS"
  609. # create an ingress if necessary
  610. if [[ $HAS_INGRESS == "yes" ]]; then
  611. if [[ $HAS_FAILOVER == "yes" ]]; then
  612. echo "creating ingress and failover..."
  613. ./nmctl node create_ingress $NETWORK $NODE_ID --failover
  614. sleep 2
  615. else
  616. echo "creating ingress..."
  617. ./nmctl node create_ingress $NETWORK $NODE_ID
  618. sleep 2
  619. fi
  620. fi
  621. # relay
  622. if [[ $HAS_RELAY == "yes" ]]; then
  623. echo "cannot recreate relay; relay functionality moved to host"
  624. # ./nmctl node create_relay $NETWORK $NODE_ID $RELAY_ADDRS
  625. # sleep 2
  626. fi
  627. done
  628. echo "=================="
  629. else
  630. echo "no networks to join"
  631. fi
  632. }
  633. cat << "EOF"
  634. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  635. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  636. The Netmaker Upgrade Script: Upgrading to v0.18 so you don't have to!
  637. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  638. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  639. EOF
  640. set -e
  641. if [ $(id -u) -ne 0 ]; then
  642. echo "This script must be run as root"
  643. exit 1
  644. fi
  645. set +e
  646. #backup volumes and v0.17.1 configs in case of failure.
  647. backup_volumes
  648. backup_v17_files
  649. # get the installation path for docker-compose.yml and other config files
  650. get_install_path
  651. echo "...installing dependencies for script"
  652. install_dependencies
  653. echo "...installing yq if necessary"
  654. install_yq
  655. set -e
  656. echo "...confirming version is correct"
  657. check_version
  658. echo "...collecting necessary server settings"
  659. collect_server_settings
  660. echo "...setup nmctl"
  661. setup_nmctl
  662. echo "...retrieving current server node settings"
  663. collect_node_settings
  664. echo "...backing up docker compose to docker-compose.yml.backup"
  665. cp $INSTALL_PATH/docker-compose.yml $INSTALL_PATH/docker-compose.yml.backup
  666. echo "...setting Caddyfile values"
  667. setup_caddy
  668. echo "...setting docker-compose values"
  669. set_compose
  670. echo "...starting containers"
  671. start_containers
  672. echo "...remove old mosquitto data"
  673. # TODO - yq is not removing volume from docker compose
  674. # docker volume rm root_mosquitto_data
  675. wait_seconds 3
  676. echo "..testing Caddy proxy"
  677. test_caddy
  678. echo "..testing Netmaker health"
  679. # TODO, implement health check
  680. # netmaker_health_check
  681. # wait_seconds 2
  682. wait_seconds 2
  683. echo "...setup netclient"
  684. join_networks
  685. echo "-----------------------------------------------------------------"
  686. echo "-----------------------------------------------------------------"
  687. echo "Netmaker setup is now complete. You are ready to begin using Netmaker."
  688. echo "Visit dashboard.$SERVER_NAME to log in"
  689. echo "-----------------------------------------------------------------"
  690. echo "-----------------------------------------------------------------"