Browse Source

[Update] Prepare for native IPv6 NAT in Docker

andryyy 4 years ago
parent
commit
85cc346e88
1 changed files with 61 additions and 1 deletions
  1. 61 1
      update.sh

+ 61 - 1
update.sh

@@ -114,6 +114,65 @@ docker_garbage() {
   echo "If you want to cleanup further garbage collected by Docker, please make sure all containers are up and running before cleaning your system by executing \"docker system prune\""
   echo "If you want to cleanup further garbage collected by Docker, please make sure all containers are up and running before cleaning your system by executing \"docker system prune\""
 }
 }
 
 
+in_array() {
+  local e match="$1"
+  shift
+  for e; do [[ "$e" == "$match" ]] && return 0; done
+  return 1
+}
+
+migrate_docker_nat() {
+  NAT_CONFIG='{"ipv6":true,"fixed-cidr-v6":"fd00:dead:beef:c0::/80","experimental":true,"ip6tables":true}'
+  # Min Docker version
+  DOCKERV_REQ=20.10.2
+  # Current Docker version
+  DOCKERV_CUR=$(docker version -f '{{.Server.Version}}')
+  if grep -qi "ipv6nat-mailcow" docker-compose.yml; then
+    echo -e "\e[32mNative IPv6 implementation available.\e[0m"
+    echo "This will enable experimental features in the Docker daemon and configure Docker to do the IPv6 NATing instead of ipv6nat-mailcow. This step is recommended."
+    echo "mailcow will try to roll back the changes if starting Docker fails after modifying the daemon.json configuration file."
+    read -r -p "Should we try to enable the native IPv6 implementation in Docker now (recommended)? [y/N] " dockernatresponse
+    if [[ ! "${dockernatresponse}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
+      echo "OK, skipping this step."
+      return 0
+    fi
+  fi
+  # Sort versions and check if we are running a newer or equal version to req
+  if [ $(printf "${DOCKERV_REQ}\n${DOCKERV_CUR}" | sort -V | tail -n1) == "${DOCKERV_CUR}" ]; then
+    # If Dockerd daemon json exists
+    if [ -s /etc/docker/daemon.json ]; then
+      IFS=',' read -r -a dockerconfig <<< $(cat /etc/docker/daemon.json | tr -cd '[:alnum:],')
+      if ! in_array ipv6true "${dockerconfig[@]}" || \
+        ! in_array experimentaltrue "${dockerconfig[@]}" || \
+        ! in_array ip6tablestrue "${dockerconfig[@]}" || \
+        ! grep -qi "fixed-cidr-v6" /etc/docker/daemon.json; then
+          echo -e "\e[33mWarning:\e[0m You seem to have modified the /etc/docker/daemon.json configuration by yourself and not fully/correctly activated the native IPv6 NAT implementation."
+          echo "You will need to merge your existing configuration manually or fix/delete the existing daemon.json configuration before trying the update process again."
+          echo -e "Please merge the following content and restart the Docker daemon:\n"
+          echo ${NAT_CONFIG}
+          return 1
+      fi
+    else
+      echo "Working on IPv6 NAT, please wait..."
+      echo ${NAT_CONFIG} > /etc/docker/daemon.json
+      ip6tables -F -t nat
+      if ! systemctl restart docker.service; then
+        echo -e "\e[31mError:\e[0m Failed to activate IPv6 NAT! Reverting and exiting."
+        rm /etc/docker/daemon.json
+        systemctl reset-failed docker.service
+        systemctl restart docker.service
+        return 1
+      fi
+    fi
+    # Removing legacy container
+    sed -i '/ipv6nat-mailcow:$/,/^$/d' docker-compose.yml
+    echo -e "\e[32mGreat! \e[0mNative IPv6 NAT is active.\e[0m"
+  else
+    echo -e "\e[31mPlease upgrade Docker to version ${DOCKERV_REQ} or above.\e[0m"
+    return 0
+  fi
+}
+
 while (($#)); do
 while (($#)); do
   case "${1}" in
   case "${1}" in
     --check|-c)
     --check|-c)
@@ -182,6 +241,7 @@ if [ ${#DOTS} -lt 2 ]; then
 fi
 fi
 
 
 if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox grep detected, please install gnu grep, \"apk add --no-cache --upgrade grep\""; exit 1; fi
 if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox grep detected, please install gnu grep, \"apk add --no-cache --upgrade grep\""; exit 1; fi
+# This will also cover sort
 if cp --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox cp detected, please install coreutils, \"apk add --no-cache --upgrade coreutils\""; exit 1; fi
 if cp --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox cp detected, please install coreutils, \"apk add --no-cache --upgrade coreutils\""; exit 1; fi
 if sed --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox sed detected, please install gnu sed, \"apk add --no-cache --upgrade sed\""; exit 1; fi
 if sed --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox sed detected, please install gnu sed, \"apk add --no-cache --upgrade sed\""; exit 1; fi
 
 
@@ -478,7 +538,7 @@ fi
 
 
 if [ ! $FORCE ]; then
 if [ ! $FORCE ]; then
   read -r -p "Are you sure you want to update mailcow: dockerized? All containers will be stopped. [y/N] " response
   read -r -p "Are you sure you want to update mailcow: dockerized? All containers will be stopped. [y/N] " response
-  if [[ ! "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
+  if [[ ! "${response}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
     echo "OK, exiting."
     echo "OK, exiting."
     exit 0
     exit 0
   fi
   fi