#!/bin/sh
# Common functions

# Customizable environment variables:
# * $U7S_DEBUG: enable debug mode if set to "1"

# Environment variables set by this script:
# * $XDG_DATA_HOME: $HOME/.local/share if not set
# * $XDG_CONFIG_HOME: $HOME/.config if not set
# * $XDG_CACHE_HOME: $HOME/.cache if not set

USERNAME='u7s-admin'

# set -eo pipefail

# logging utilities
debug_enabled() {
	: ${U7S_DEBUG=0}
	[[ $U7S_DEBUG == 1 ]] || [[ $U7S_DEBUG == true ]]
}

log_debug() {
	if debug_enabled; then
		echo -e "\e[102m\e[97m[DEBUG]\e[49m\e[39m $@" >&2
	fi
}

log_info() {
	echo -e "\e[104m\e[97m[INFO]\e[49m\e[39m $@" >&2
}

log_info_n() {
	echo -n -e "\e[104m\e[97m[INFO]\e[49m\e[39m $@" >&2
}

log_warning() {
	echo -e "\e[101m\e[97m[WARN]\e[49m\e[39m $@" >&2
}

log_error() {
	echo -e "\e[101m\e[97m[ERROR]\e[49m\e[39m $@" >&2
}

# nsenter utilities
nsenter_main() {
	: ${_U7S_NSENTER_CHILD=0}
	if [[ $_U7S_NSENTER_CHILD == 0 ]]; then
		_U7S_NSENTER_CHILD=1
		export _U7S_NSENTER_CHILD
		nsenter__nsenter_retry_loop
		rc=0
		nsenter__nsenter $@ || rc=$?
		exit $rc
	fi
}

nsenter__nsenter_retry_loop() {
	local max_trial=10
	log_info_n "$(gettext 'Entering RootlessKit namespaces'): "
	for ((i = 0; i < max_trial; i++)); do
		rc=0
		nsenter__nsenter echo OK 2>/dev/null || rc=$?
		if [[ rc -eq 0 ]]; then
			return 0
		fi
		echo -n .
		sleep 1
	done
	echo ""
	log_error "$(gettext 'nsenter failed after') ${max_trial} $(gettext 'attempts, RootlessKit not running')?"
	return 1
}

nsenter__nsenter() {
	local pidfile=$XDG_RUNTIME_DIR/usernetes/rootlesskit/child_pid
	if ! [[ -f $pidfile ]]; then
		return 1
	fi
	# workaround for https://github.com/rootless-containers/rootlesskit/issues/37
	# see the corresponding code in rootlesskit
	local pidreadyfile=$XDG_RUNTIME_DIR/usernetes/rootlesskit/_child_pid.u7s-ready
	if ! [[ -f $pidreadyfile ]]; then
		return 1
	fi
	if ! [[ $(cat $pidfile) -eq $(cat $pidreadyfile) ]]; then
		return 1
	fi
	export ROOTLESSKIT_STATE_DIR=$XDG_RUNTIME_DIR/usernetes/rootlesskit
	# TODO(AkihiroSuda): ping to $XDG_RUNTIME_DIR/usernetes/rootlesskit/api.sock
	nsenter --user --preserve-credential --mount --net --cgroup --pid --ipc --uts -t $(cat $pidfile) --wd=$PWD -- $@
}

setEnvsByYaml() {
	yamlFile=$1
	ifs=$IFS
	for assign in $(yq '.spec.containers[0].command' $yamlFile | grep -- '"--')
	do
	  if [ "${assign:0-1}" = ',' ]
	  then
			assign=${assign:3:-2}
		else
			assign=${assign:3:-1}
		fi
		IFS==
		set -- $assign
		IFS=$ifs
		var=$1
		value=$2
		IFS=-
		set -- $var
		IFS=$ifs
		varsh=$1
		shift
		for p
		do
		  varsh+="_$p"
		done
		echo "export $varsh=$value"
	done
}

# Применение маски сети к указанному адресу
maskAddr() {
	set +e
  addr=$1
  mask=$2
  if [ $mask -eq 0 -o $mask -gt 32 ] 2>/dev/null
  then
		echo "$(gettext 'Incorrect mask') $mask" >&2
    exit
  fi
  let tail=32-$mask
  ifs=$IFS
  IFS=.
  set -- $addr
  IFS=$ifs
  if [ $# -ne 4 ] 2>/dev/null
  then
		echo "$(gettext 'Incorrect address') $addr" >&2
    exit
  fi

  Val=0
  for val
  do
    let Val=$Val*256+$val
  done
  let "Val=$Val>>$tail"
  let "Val=$Val<<$tail"

  let "ret=$Val&255"
  for i in 1 2 3
  do
    let "Val=$Val>>8"
    let "val=$Val&255"
    ret="$val.$ret"
  done

  echo $ret
}

# Получение внешнего IP
getExtIP() {
  set -- $(ip r | grep default)
  export router=$3

  ip a | grep 'inet ' |
  (
  while read inet
  do
    set -- $inet
    AddrMask=$2
    ifs=$IFS
    IFS=/
    set -- $AddrMask
    IFS=$ifs
    addr=$1
    mask=$2
    maskedAddr=$(maskAddr "$addr" "$mask")
    maskedRoute=$(maskAddr "$router" "$mask")
    if [ "$maskedAddr" = "$maskedRoute" ]
    then
      echo $addr
      break
    fi
  done
  )
}

# Получение имени внешнего устройства
getExtDev() {
	export extIP=$1
	ifs=$IFS
	IFS=.
	set -- $extIP
	IFS=$ifs
	if [ $# -ne 4 ]
	then
		echo "$(gettext 'Incorrect address') $extIP" >&2
		exit
	fi
	ip a | grep $extIP |
	(
  while read inet
  do
    set -- $inet
    if [ "$1" != 'inet' ]
    then
      continue
    fi
    addr=$2
    l=${#extIP}
    if [ "${addr:0:$l}" = "$extIP" -a "${addr:$l:1}" == '/' ]
    then
      while [ $# -gt 1 ]; do shift; done
      echo $1
      break
    fi
  done
	)
}

getCidr() {
	export CIDRIP CIDRMASK
	cidr=$1
# 	shift; shift
	IFS=/
	set -- $cidr
	IFS=$ifs
	CIDRIP=$1
	CIDRMASK=$2
	IFS=.
	set -- $cidr
	IFS=$ifs
	if [ $# -ne 4 ]
	then
		echo "$(gettext 'Incorrect address') --service-cidr '$cidr'" >&2
		exit 1
	fi
# 	echo $cidr $serviceMask
}

# Функция формирует ClusterIP как cidr с 1-чкой в последнем кварте
getKubernetesClusterIP() {
	cidr=$1
	ifs=$IFS
	IFS=.
	set -- $cidr
	IFS=$ifs
	echo "${1}.${2}.${3}.1"
}

# Функция модифицирует файл /kubernetes/manifests/kube-apiserver.yaml запуска kube-apiserver
# для настройки аудита
function tuneAudit() {
	haveAudit=$(cat /etc/kubernetes/manifests/kube-apiserver.yaml   | yq  '[.spec.volumes[].hostPath][].path | select(. == "/etc/kubernetes/audit")')
	if [ -z "$haveAudit" ]
	then
		TMPFILE="/tmp/kube-api-server.$$"
		confFile="/etc/kubernetes/manifests/kube-apiserver.yaml"
		cat $confFile |
		yq -y  '.spec.containers[].command |= . +
		["--audit-policy-file=/etc/kubernetes/audit/policy.yaml"] +
		["--audit-log-path=/etc/kubernetes/audit/audit.log"] +
		["--audit-log-maxsize=500"] +
		["--audit-log-maxbackup=3"]
		' |
		yq -y  '.spec.containers[].volumeMounts |= . +
		[{ "mountPath": "/etc/kubernetes/audit", "name": "audit" }]
		' |
		yq -y '.spec.volumes |= . +
		[{ "hostPath": {"path": "/etc/kubernetes/audit" , "type": "DirectoryOrCreate" }, "name": "audit" }]
		' > $TMPFILE
		if [ -s $TMPFILE ]
		then
			mv $TMPFILE $confFile
		fi
	fi
}

export U7S_REGISTRY_PLATFORM U7S_REGISTRY
# Функция устанавливает имя регистратора обрвзов в переменнную U7S_REGISTRY_PLATFORM
function setRegistryName() {
  export U7S_ALTREGISTRY="registry.altlinux.org"
  if [  ! -z "${U7S_REGISTRY+x}" -a ${#U7S_REGISTRY} -eq 0  ]
  then
		export U7S_REGISTRY="registry.k8s.io"
		U7S_PLATFORM=
  else
		if grep registry.local /etc/hosts >/dev/null 2>&1
		then
			export U7S_REGISTRY="registry.local"
		else
			export U7S_REGISTRY=$U7S_ALTREGISTRY
		fi
# 		source podsec-get-platform
	fi
	U7S_REGISTRY_PLATFORM=$U7S_REGISTRY
	if [ -n "$U7S_PLATFORM" ]
	then
		if [ ${U7S_PLATFORM:0:8} = 'k8s-c10f' ]
		then
			U7S_REGISTRY_PLATFORM+="/c10f"
		else
			U7S_REGISTRY_PLATFORM+="/$U7S_PLATFORM"
		fi
	fi
# 	getKuberLastPatchVersion
	export U7S_REGISTRY_PLATFORM
}

function currentKubeVersion() {
	ifs=$IFS
  common=$(rpm -qa | grep kubernetes-common)
  IFS=-
  set -- $common
  IFS=$ifs
  echo v$3
}

function kubeVersionToMinorVersion() {
	ifs=$IFS
	IFS=.
	set -- $1
	IFS=$ifs
	echo "$1.$2"
}

function getMinorVersion() {
	ifs=$IFS
	IFS=.
	set -- $1
	IFS=$ifs
	echo "$1.$2"
}


function decreaseMinorVersion() {
	ifs=$IFS
	IFS=.
	set -- $1
	IFS=$ifs
	minor=$2
	let minor-=1
	echo "$1.$minor"
}

function getKubePatchVersionByKubeadm() {
	ret=$(/usr/bin/kubeadm version -o json | jq -r .clientVersion.gitVersion)
	echo $ret
}

function getKubePatchVersionByCrio() {
	ret=$(/usr/bin/crio version --json 2>/dev/null | jq -r .version)
	echo $ret
}

# Устанавливает требуемую доступную версию kubeadm и переменную U7S_KUBEVERSION при ее отсутствии
function installKubeadm() {
	apt-get update
	lastKubeAdmMinorVersion=$(getLastKubeAdmMinorVersion)
	LastKubeAdmMinorVersion="v$lastKubeAdmMinorVersion"
	lastKubeAdmPatchVersion=$(getPacketPatchVersion "kubernetes${lastKubeAdmMinorVersion}-kubeadm")
	LastKubeAdmPatchVersion="v$lastKubeAdmPatchVersion"
	if [ -z "$U7S_KUBEVERSION" ]
	then
		kubeMinorVersion=$lastKubeAdmMinorVersion
		U7S_KUBEVERSION=$LastKubeAdmPatchVersion
		KubeMinorVersion="v$kubeMinorVersion"
	else
		KubeMinorVersion=$(getMinorVersion $U7S_KUBEVERSION)
		kubeMinorVersion=${KubeMinorVersion:1}
	fi
	if [ "${U7S_KUBEVERSION:0:1}" != 'v' ]
	then
		echo "$(gettext 'Variable value') U7S_KUBEVERSION $(gettext 'must start with a symbol') 'v'" >&2
		exit
	fi
	pkgNames=
  if [ -f '/usr/bin/kubeadm' -o -f '/usr/bin/crio' ]
  then
		if [ -f '/usr/bin/kubeadm' ]
		then
			KubePatchVersionByKubeadm=$(getKubePatchVersionByKubeadm)
			kubePatchVersionByKubeadm=${KubePatchVersionByKubeadm:1}
			kubeMinorVersionByKubeadm=$(getMinorVersion $kubePatchVersionByKubeadm)
			KubeMinorVersionByKubeadm="v$kubeMinorVersionByKubeadm"
			echo "$(gettext 'Warning'): $(gettext 'version of kubeadm command') $kubePatchVersionByKubeadm $(gettext 'already installed')" >&2
			if [ "$KubeMinorVersionByKubeadm" != "$KubeMinorVersion" ]
			then
				pkgNames+=" kubernetes${KubeMinorVersionByKubeadm:1}-kubeadm"
			else
			echo "$(gettext 'Minor version') $U7S_KUBEVERSION kubeadm $(gettext 'matches the established one') $KubeMinorVersionByKubeadm" >&2
			fi
		fi
		if [ -f '/usr/bin/crio' ]
		then
			kubePatchVersionByCrio=$(getKubePatchVersionByCrio)
			KubePatchVersionByCrio="v$kubePatchVersionByCrio"
			kubeMinorVersionByCrio=$(getMinorVersion $kubePatchVersionByCrio)
			KubeMinorVersionByCrio="v$kubeMinorVersionByCrio"
			echo "$(gettext 'Warning'): $(gettext 'command crio version') $kubePatchVersionByCrio $(gettext 'already installed')" >&2
			if [ "${kubeMinorVersionByCrio}" != "$kubeMinorVersion" ]
			then
				pkgNames+=" kubernetes${kubeMinorVersionByCrio}-crio cri-o${kubeMinorVersionByCrio} cri-tools${kubeMinorVersionByCrio}"
			else
			echo "$(gettext 'Minor version') ${kubeMinorVersionByCrio} crio $(gettext 'matches the established one') $KubeMinorVersionByKubeadm" >&2
			fi
		fi
  fi

	if [[ "$kubeMinorVersion" < '1.26' ]]
	then
		echo "$(gettext 'Minor version')  kubeadm $kubeMinorVersion $(gettext 'less than 1.26 is not supported')" >&2
		exit 1
	fi
	minorDelta=0
	pkgNames="kubernetes$kubeMinorVersion-kubeadm kubernetes$kubeMinorVersion-kubelet kubernetes$kubeMinorVersion-crio "
	kuberPkgList=$(rpm -qa | grep -e "^kubernetes")
	installPkgNames=
	for pkgName in $pkgNames
	do
# 		fullPkgName="$pkgName"
		if echo "$kuberPkgList" | grep $pkgName >/dev/null
		then :;
		else
			installPkgNames+=" $pkgName"
		fi
	done
	if [ -n "$installPkgNames" ]
	then
		installPkgNames+=" cri-tools$kubeMinorVersion"
		echo "$(gettext 'Installing packages') $installPkgNames" >&2
		until apt-get install -y $installPkgNames 2>/dev/null
		do
			echo "$(gettext 'Version') $kubeMinorVersion $(gettext 'packages') $installPkgNames $(gettext 'unavailable')" >&2
			kubeMinorVersion=$(decreaseMinorVersion $kubeMinorVersion)
			installPkgNames="kubernetes$kubeMinorVersion-kubeadm  kubernetes$kubeMinorVersion-crio kubernetes$kubeMinorVersion-kubelet"
			echo "$(gettext 'Trying to install a previous minor version') $kubeMinorVersion $(gettext 'packages') $installPkgNames" >&2
			if [[ "$kubeMinorVersion" < '1.26' ]]
			then
				echo "$(gettext 'Minor version of kubeadm') $kubeMinorVersion $(gettext 'less than 1.26 is not supported')" >&2
				exit 1
			fi
			let minorDelta+=1
		done
		usermod -G kube,systemd-journal,podman u7s-admin
		if [ $minorDelta -gt 1 ]
		then
			echo "$(gettext 'Warning'): $(gettext 'The kubeadm minor version is more than one release behind the kubernetes image minor version. Deployment issues may occur')" >&2
		fi
	fi
}

# Функция выводит команду apt-get install использую механизм удаления (${packege}-) и добавления (${packege}-+) пакетов
# обновляет пакеты kubernetes и cri-o до указанной версии с сохранением пакетов podsec
function replaceKubeCommand() {
	IFS=.
	set -- $1
	IFS=$ifs
	kubeVersion=${1:1}.$2
	rpm -qa | grep -E  "kubernetes|cri-o" | (
	ifs=$IFS
	cmd='apt-get install -y'
	while read pName
	do
		if [ ${pName:0:10} != 'kubernetes' -a  ${pName:0:5} != 'cri-o' ]; then continue; fi
		IFS=-
		set -- $pName
		IFS=$ifs
		if [ ${pName:0:10} = 'kubernetes' ]
		then
			delName="${1}-${2}-"
			addName="kubernetes${kubeVersion}-${2}+"
		else
			if [ ${pName:0:5} = 'cri-o' ]
			then
				delName="${1}-${2}-"
				addName="cri-o${kubeVersion}+"
			fi
		fi
		cmd+=" $delName $addName"
	done
	echo $cmd
	)
}

function getPacketPatchVersion() {
	package=$1
	set -- $(apt-cache show $package | grep "^Version:")
	version=$2
	ifs=$IFS
	IFS=-
	set -- $version
	IFS=$ifs
	echo $1
}

function getLastKubeAdmMinorVersion() {
	apt-cache search kubernetes-kubeadm |
	(
	ret=
	while read version tail
	do
		if [ "${version:0:10}" = 'kubernetes' ]
		then
			version=${version:10:-8}
			if [ -z "$version" ]; then continue; fi
			if [[ "$ret" < $version ]]
			then
				ret=$version
			fi
		fi
	done
	echo $ret
  )
}

# Получить из регистратора список доступных тrгов образа
function getKubernetesPatchVersions() {
	image=$1
	if [ "$U7S_REGISTRY" == 'registry.local' ]
	then
		flags="-s"
		url="http://$U7S_REGISTRY/v2/$image/tags/list"
	else
		flags="-ks"
		url="https://$U7S_REGISTRY/v2/$image/tags/list"
	fi
  versions=$(curl $flags $url | jq -r  '.tags | sort | .[]')
  ret=
  for version in $versions
  do
		if [ "$version" = 'latest' ]; then continue; fi
		ret+=" $version"
  done
  echo $ret
}

# Получить из регистратора список доступных минорных версий
function getKubernetesMinorVersions() {
	versions=$(getKubernetesPatchVersions $1)
	ret=
	lastVersion=
	for version in $versions
	do
		minorVersion=$(getMinorVersion $version)
		if [ "$minorVersion" != "$lastVersion" ]
		then
			ret+=" $minorVersion"
			lastVersion=$minorVersion
		fi
	done
	echo $ret
}

# Проверить наличие на регистраторе образа с указанным тегом
function checkKubernetesPatchVersions() {
  minorVersion=$1
  if [ ${#minorVersion} -gt 0 -a "${minorVersion:0:1}" != 'v' ]; then minorVersion="v$minorVersion"; fi
	image=$2
	tag=$3
	versions=$(getKubernetesPatchVersions $image)
	set -- $versions
	while [ $# -gt 0 ]
	do
		if [ "$tag" = "${1}" ]
		then
			return 0
		fi
		shift
	done
  return 1
}

# Получить из регистратора последнюю доступную версию образа в указанной минорной версии
function getKuberLastPatchVersion() {
  minorVersion=$1
  if [ ${#minorVersion} -gt 0 -a "${minorVersion:0:1}" != 'v' ]; then minorVersion="v$minorVersion"; fi
	image=$2
	versions=$(getKubernetesPatchVersions $image)
	set -- $versions
	l=${#minorVersion}
	ret=
	while [ $# -gt 0 ]
	do
		if [ "$1" = 'latest' ]; then shift; continue; fi
		if [ ${1:0:$l} = $minorVersion ]
		then
			ret=$1
		fi
		shift
	done
  echo $ret
}

# Параметры:
# - архитектура процессора
# - каталог размещения образов относительно ~$user/.local
# - пользователь для которого размещается образы
# - группа пользователя
function getKuberImages() {
  export U7S_ARCHIMAGES
  arch=$1
	storage=$2
	user=$3
	if [ $# -eq 3 ]
	then
		group=$user
	else
		group=$4
	fi

	case $arch in
		'x86_64') arch='amd64';;
		#break;;
	esac

	eval storage="~$user/.local/$storage"

  minorVersion=$(getMinorVersion $U7S_KUBEVERSION)

  imageList=$(/usr/bin/kubeadm --kubernetes-version=$U7S_KUBEVERSION --image-repository $U7S_REGISTRY_PLATFORM config images list 2>/dev/null)
  if [ -z "$imageList" ]
  then
		echo "$(gettext 'Kubernet version') $U7S_KUBEVERSION  $(gettext 'not supported')" >&2
    exit 1
  fi
  imageList+=" $U7S_ARCHIMAGES"
  let lenRegistry=${#U7S_REGISTRY}+1
  let lenRegistryPlatform=${#U7S_REGISTRY_PLATFORM}+1
  ifs=$IFS
  U7S_IMAGES=

  for image in $imageList
  do
    fullImage=$image
    IFS=:
    set -- $image
    IFS=$ifs
    imageWithoutTag=$1
    imageTag=$2
    imageWithoutRegistry=${image:lenRegistry}
    imageWithoutRegistryAndTag=${imageWithoutTag:lenRegistry}
    shortImageName=${imageWithoutTag:$lenRegistryPlatform}

    if checkKubernetesPatchVersions $minorVersion $imageWithoutRegistryAndTag $imageTag
    then
			echo "$(gettext 'Image version') $imageWithoutRegistryAndTag $(gettext 'with tag') $imageTag $(gettext 'available. Loading...')" >&2
      skopeo --override-arch $arch copy\
				docker://$fullImage\
				containers-storage:[$storage]$fullImage 2>/dev/null  || :
    else
			echo "$(gettext 'Image version') $imageWithoutRegistryAndTag  $(gettext 'with tag') $imageTag $(gettext 'unavailable')" >&2
      if [ "$U7S_SETAVAILABLEIMAGES" != 'yes' ]
      then
				lastPatchVerison=$(getKuberLastPatchVersion $minorVersion $imageWithoutRegistryAndTag)
				if [ -z "$lastPatchVerison" ]
				then
					echo "$(gettext 'Within the specified minor version') $minorVersion $(gettext 'no images available')" >&2
					echo  -ne "$(gettext 'The following minor versions are available'): " >&2
					getKubernetesMinorVersions $imageWithoutRegistryAndTag
					echo -ne "$(gettext 'and the following patch versions of images'): " >&2
					getKubernetesPatchVersions $imageWithoutRegistryAndTag
					echo -ne "$(gettext 'To install one of the specified image versions, specify the selected image version in the environment variable')\nexport U7S_KUBEVERSION=...\n" >&2
# 					echo -ne "Для установки одной из указанных версий образов укажите выбранную версию образа в переменной среды:\nexport U7S_KUBEVERSION=...\n"
				else
					echo -ne "$(gettext 'To install the latest patch versions') $lastPatchVerison $(gettext 'images set environment variable'):\nexport U7S_KUBEVERSION=$lastPatchVerison\n$(gettext 'or')\nexport U7S_KUBEVERSION=$lastPatchVerison\n" >&2
				fi
        exit 1
      else
        mVersion=
        if [ "${shortImageName:0:5}" = 'kube-' ]
        then
          mVersion=$minorVersion
        fi
        repoImageLastTag=$(getKuberLastPatchVersion "$mVersion" $imageWithoutRegistryAndTag)
        if [ -z "$repoImageLastTag" ]
        then
					echo -ne "$(gettext 'Within the framework of the minor version') $mVersion $(gettext 'images') $imageWithoutRegistryAndTag $(gettext 'are absent')" >&2
					exit 1
        fi
        imageWithNewTag="$imageWithoutTag:$repoImageLastTag"
        echo -ne "$(gettext 'Selected available on the registry') $U7S_REGISTRY $(gettext 'last tag') $repoImageLastTag" >&2
        # Загрузка образа в rootless каталог образов
        skopeo --override-arch $arch\
					copy docker://$imageWithNewTag\
					containers-storage:[$storage]$imageWithNewTag 2>/dev/null  || :
        # Навешивание тега
        skopeo --override-arch $arch copy\
					containers-storage:[$storage]$imageWithNewTag\
					containers-storage:[$storage]$fullImage 2>/dev/null || :
      fi
    fi

    U7S_IMAGES+=" $imageWithoutRegistry"
    case $shortImageName in
      coredns)
        export U7S_COREDNS_IMAGE=$imageWithoutRegistry
        ;;
      pause)
        export U7S_PAUSE_IMAGE=$imageWithoutRegistry
        ;;
      etcd)
        export U7S_ETCD_IMAGE=$imageWithoutRegistry
        ;;
      kube-controller-manager)
        export U7S_KUBECONTROLLER_IMAGE=$imageWithoutRegistry
        ;;
      kube-apiserver)
        export U7S_KUBEAPISERVER_IMAGE=$imageWithoutRegistry
        ;;
      kube-proxy)
        export U7S__KUBEPROXY_IMAGE=$imageWithoutRegistry
        ;;
      kube-scheduler)
        export U7S_KUBESCHEDULER_IMAGE=$imageWithoutRegistry
        ;;
    esac
  done

  case $U7S_REGISTRY in
    registry.altlinux.org | registry.local) # Образы ALTLINUX
      prefix="$U7S_PLATFORM/"
      U7S_FLANNEL_REGISTRY=$U7S_REGISTRY
      ;;
    *)
      prefix=''
      U7S_FLANNEL_REGISTRY="docker.io/flannel"
      ;;
  esac

if [ -z "$U7S_FLANNEL_TAG" ]
then
  flannelTag=$(getKuberLastPatchVersion 'v' "${prefix}flannel" 2>/dev/null)
  if [ -z "$flannelTag" ];
  then
		echo "$(gettext 'Image') ${prefix}flannel $(gettext 'on registry') $U7S_REGISTRY $(gettext 'unavailable')" >&2
		exit;
	fi
  U7S_FLANNEL_TAG=$flannelTag
  flannelImage="$U7S_FLANNEL_REGISTRY/${prefix}flannel:$flannelTag"
else
  flannelImage="$U7S_FLANNEL_REGISTRY/${prefix}flannel:$U7S_FLANNEL_TAG"
fi
skopeo --override-arch $arch copy docker://$flannelImage containers-storage:[$storage]$flannelImage

set -- $(getFlannelCniPluginName $U7S_FLANNEL_TAG)
flannelCniPluginRegistry=$1
flannelCniPluginImage=$2
flannelCniPluginTag=$3
if [ -z "$U7S_FLANNELCNIPLUGIN_TAG" ]
then
  U7S_FLANNELCNIPLUGIN_TAG=$flannelCniPluginTag
  if [ -z "$flannelCniPluginTag" ];
  then
		echo "$(gettext 'Image') ${prefix}flannel-cni-plugin $(gettext 'on registry') $U7S_REGISTRY $(gettext 'unavailable')" >&2
		exit;
	fi
  flannelCNIImage="$U7S_FLANNEL_REGISTRY/${prefix}flannel-cni-plugin:$flannelCniPluginTag"
else
  flannelCNIImage="$flannelCniPluginRegistry/$flannelCniPluginImage:$flannelCniPluginTag"
fi
skopeo --override-arch $arch copy docker://$flannelCNIImage containers-storage:[$storage]$flannelCNIImage

#   if [ -z "$U7S_CERTMANAGER_TAG" ]
#   then
#     # U7S_CERTMANAGER_TAG="v1.9.1"
#     U7S_CERTMANAGER_TAG=$(getKuberLastPatchVersion 'v' "${prefix}cert-manager-controller")
#     if [ -z "$U7S_CERTMANAGER_TAG" ];
#     then
# 			echo "$(gettext 'Image') ${prefix}cert-manager-controller $(gettext 'on registry') $U7S_REGISTRY $(gettext 'unavailable')" >&2
# 			exit;
# 		fi
#
#     certManagesImage="$U7S_REGISTRY/${prefix}cert-manager-controller:$U7S_CERTMANAGER_TAG"
#     echo -ne "\n--------------------------\n$(gettext 'Loading the image') $certManagesImage\n"  || :
#     skopeo --override-arch $arch copy\
# 			docker://$certManagesImage\
# 			containers-storage:[$storage]$certManagesImage  || :
#
#     certManagesImage="$U7S_REGISTRY/${prefix}cert-manager-cainjector:$U7S_CERTMANAGER_TAG"
#     echo -ne "\n--------------------------\n$(gettext 'Loading the image') $certManagesImage\n" >&2
#     skopeo --override-arch $arch copy\
# 			docker://$certManagesImage\
# 			containers-storage:[$storage]$certManagesImage 2>/dev/null  || :
#
#     echo -ne "\n--------------------------\n$(gettext 'Loading the image') $certManagesImage\n" >&2
#     certManagesImage="$U7S_REGISTRY/${prefix}cert-manager-webhook:$U7S_CERTMANAGER_TAG"
#     skopeo --override-arch $arch copy\
# 			docker://$certManagesImage\
# 			containers-storage:[$storage]$certManagesImage 2>/dev/null  || :
#
#   fi

  echo "$(gettext 'For the image') flannel $(gettext 'image with tag selected') $U7S_FLANNEL_TAG" >&2
  export U7S_FLANNEL_IMAGE="${prefix}flannel:$U7S_FLANNEL_TAG"

  echo "$(gettext 'For the image') flannel-cni-plugin $(gettext 'image with tag selected') $U7S_FLANNELCNIPLUGIN_TAG" >&2
  export U7S_FLANNEL_CNI_IMAGE="${prefix}flannel-cni-plugin:$U7S_FLANNELCNIPLUGIN_TAG"

#   echo "$(gettext 'For the image') cert-manager-controller $(gettext 'image with tag selected') $U7S_CERTMANAGER_TAG" >&2
#   export U7S_CERTMANAGER_CONTROLLER_IMAGE="$U7S_PLATFORM/cert-manager-controller:$U7S_CERTMANAGER_TAG"
#
#   echo "$(gettext 'For the image') cert-manager-cainjector $(gettext 'image with tag selected') $U7S_CERTMANAGER_TAG" >&2
#   export U7S_CERTMANAGER_CAINJECTOR_IMAGE="$U7S_PLATFORM/cert-manager-cainjector:$U7S_CERTMANAGER_TAG"
#
#    echo "$(gettext 'For the image') cert-manager-webhook $(gettext 'image with tag selected') $U7S_CERTMANAGER_TAG" >&2
#   export U7S_CERTMANAGER_WEBHOOK_IMAGE="$U7S_PLATFORM/cert-manager-webhook:$U7S_CERTMANAGER_TAG"

	eval chown -R $user:$user ~$user/.local


  export U7S_IMAGES+="
  $U7S_FLANNEL_IMAGE
  $U7S_FLANNEL_CNI_IMAGE
  "

#   export U7S_IMAGES+="
#   $U7S_FLANNEL_IMAGE
#   $U7S_FLANNEL_CNI_IMAGE
#   $U7S_CERTMANAGER_CONTROLLER_IMAGE
#   $U7S_CERTMANAGER_CAINJECTOR_IMAGE
#   $U7S_CERTMANAGER_WEBHOOK_IMAGE
#   "
}

function checkNetCrossing {
	ifs=$IFS
	for netName in U7S_PODNETWORKCIDR U7S_SERVICECIDR
	do
		eval net=\$${netName}
		if [ -z "$net" ]; then continue; fi
		IFS=/
		set -- $net
		IFS=$ifs
		netAddr=$1
		netMask=$2
		ip a | grep 'inet ' |
		(
		ifs=$IFS
		while read inet
		do
			set -- $inet
			dev=${@:$#}
			AddrMask=$2
			IFS=/
			set -- $AddrMask
			IFS=$ifs
			addr=$1
			mask=$2
			if [ $netMask -lt $mask ]; then minMask=$netMask; else minMask=$mask; fi
			maskedNet=$(maskAddr "$netAddr" "$minMask")
			maskedAddr=$(maskAddr "$addr" "$minMask")
			if [ "$maskedAddr" = "$maskedNet" ]
			then
				echo "$(gettext 'Interface') $dev $(gettext 'supports network') $AddrMask $(gettext 'intersecting with the internal network') $net $(gettext 'kubernetes cluster')" >&2
				exit 1
			fi
		done
		exit 0
		)
		if [ $? -ne 0 ]; then exit 1; fi
	done
	return $?
}

function getKubeFlannelFile() {
  flannelTag=$1
  ifs=$IFS
  IFS=.
  set -- $flannelTag
  IFS=$ifs
  Major=$1
  if [ ${Major:0:1} = 'v' ]; then Major=${Major:1}; fi
  Minor=$2
  Patch=$3
  file="/etc/podsec/u7s/manifests/kube-flannel/$Major/$Minor/$Patch/kube-flannel.yml"
  echo $file
}

function getFlannelCniPluginName() {
	kubeFlannelFile=$(getKubeFlannelFile $1)
	cniPluginImage=$(yq -y 'select(.kind=="DaemonSet").spec.template.spec.initContainers[0]' $kubeFlannelFile |  yq -r '.image')
	ifs=$IFS IFS=:
	set -- $cniPluginImage
	IFS=$ifs
	tag=$2
	Image=$1
	image=$(basename $Image)
	registry=$(dirname $Image)
	echo $registry $image $tag
}

function FlannelNameToAlt() {
	image=$1
	ifs=$IFS
	IFS=:
	set -- $image
	image=$1
	tag=$2
  if [[ $1 =~ "flannel-cni-plugin" ]]
  then
		echo "$U7S_PLATFORM/flannel-cni-plugin:$tag"
  else
		echo "$U7S_PLATFORM/flannel:$tag"
  fi
}

function kubeflannelYMLToALT() {
	registry=$1
	flannelTag=$2
	kubeFlannelFile=$(getKubeFlannelFile $flannelTag)
  initCount=$(cat $kubeFlannelFile |
  yq -y 'select(.kind=="DaemonSet").spec.template.spec.initContainers' |
  yq 'length')
  q='.' i=0
  while [ $i -lt $initCount ]
  do
		image=$(cat $kubeFlannelFile |
			yq -y 'select(.kind=="DaemonSet").spec.template.spec.initContainers['$i']' |
			yq -r '.image')
			altImage="$registry/$(FlannelNameToAlt $image)"
		q+='| select(.kind=="DaemonSet").spec.template.spec.initContainers['$i'].image="'$altImage'"'
		let i=$i+1
  done
	image=$(cat $kubeFlannelFile |
		yq -y 'select(.kind=="DaemonSet").spec.template.spec.containers[0]' |
		yq -r '.image')
	altImage="$registry/$(FlannelNameToAlt $image)"
	q+='| select(.kind=="DaemonSet").spec.template.spec.containers[0].image="'$altImage'"'
	yq -y "$q" $kubeFlannelFile
}

# export XDG_{DATA,CONFIG,CACHE}_HOME
if [ -z "$USER" ]; then USER=$USERNAME; fi
HOME=$(eval echo ~$USER)
: ${XDG_DATA_HOME=$HOME/.local/share}
: ${XDG_CONFIG_HOME=$HOME/.config}
: ${XDG_CACHE_HOME=$HOME/.cache}
envFile=/var/lib/u7s-admin/.config/usernetes/env
export PATH=/usr/libexec/podsec/u7s/bin/:$PATH
export XDG_DATA_HOME XDG_CONFIG_HOME XDG_CACHE_HOME envFile
