module/gerrit: add ssh rsa id and public key support
diff --git a/module/compose/scheme.sh b/module/compose/scheme.sh
index 1310cf5..17255ca 100644
--- a/module/compose/scheme.sh
+++ b/module/compose/scheme.sh
@@ -76,6 +76,7 @@
       - LISTEN_URL=${_GERRIT_LISTEN_URL_}
       - HOOKS_REMOTE_ALIAS=${_GERRIT_HOOKS_REMOTE_NAME_}
       - HOOKS_REMOTE_HOST=${_APACHE_DKRC_FRONTEND_IP_}
+      - HOOKS_REMOTE_RSAID=${_GERRIT_SSH_RSA_ID_F_}
       - HOOKS_LOG_DIR=${_GERRIT_HOOKS_LOG_CON_D_}
     depends_on:
       - ${_APACHE_DKRC_SERVICE_}
diff --git a/module/gerrit/holder.sh b/module/gerrit/holder.sh
index df60f71..463d044 100644
--- a/module/gerrit/holder.sh
+++ b/module/gerrit/holder.sh
@@ -73,3 +73,6 @@
 	_GERRIT_APT_GET_INSTALL_PING_="# Skip install ping for ${mod_mode}"
 fi
 _GERRIT_USER_CON_="root"
+_GERRIT_SSH_RSA_ID_NAME_="$rsa_id"
+_GERRIT_SSH_RSA_ID_F_="/var/gerrit/etc/${_GERRIT_SSH_RSA_ID_NAME_}"
+_GERRIT_HOST_RSA_ID_F_="$rsa_id_f"
diff --git a/module/gerrit/module.sh b/module/gerrit/module.sh
index 1edc3b2..3653598 100644
--- a/module/gerrit/module.sh
+++ b/module/gerrit/module.sh
@@ -47,6 +47,9 @@
 declare -r war_mirror="https://gerrit-releases.storage.googleapis.com"
 declare -r revision="1"
 
+declare -r rsa_id="${host_name}-con-gerrit.id_rsa"
+declare -r rsa_id_f="$mod_rootfs_d/etc/$rsa_id"
+
 # Gerrit is always configured with a loopback on localhost. If the web server
 # is configured to only utilise SSL encryption for all the public incoming
 # and outgoing traffic, unencrypted requests and responses over simple http
@@ -120,9 +123,10 @@
 
 function tod_upmod
 {
-	__fetch_module_common || return $s_err
-	__gerrit_do_keystore  || return $s_err
-	__gerrit_do_hooks     || return $s_err
+	__fetch_module_common  || return $s_err
+	__gerrit_do_keystore   || return $s_err
+	__gerrit_do_hooks      || return $s_err
+	__gerrit_do_ssh_rsa_id || return $s_err
 }
 
 function __gerrit_do_lock
@@ -276,3 +280,35 @@
 		return $s_err
 	}
 }
+
+function __gerrit_do_ssh_rsa_id
+{
+	if [ -f "$mod_staging_d/$rsa_id" ] && [ -f "$mod_staging_d/$rsa_id.pub" ]; then
+		lets -l -w "$rsa_id already exists"
+	else
+		sudo rm -f ${mod_staging_d}/${rsa_id}
+		sudo rm -f ${mod_staging_d}/${rsa_id}.pub
+
+		ssh-keygen -b 2048 -t rsa -f $mod_staging_d/$rsa_id -C "con@drkc" -N "" 2>&1 | \
+			lets -l -x "keygen"
+		if [ "${PIPESTATUS[0]}" -ne 0 ]; then
+			lets -l -e "failed to create new rsa_id"
+			return $s_err
+		fi
+	fi
+
+	diff ${rsa_id_f}.pub $mod_staging_d/${rsa_id}.pub 2>&1 | lets -l -x "diff"
+	if [ "${PIPESTATUS[0]}" -ne 0 ]; then
+		sudo cp -a --preserve=all ${mod_staging_d}/${rsa_id} ${rsa_id_f} || {
+			lets -l -e "failed to copy new rsa_id"
+			return $s_err
+		}
+		sudo cp -a --preserve=all ${mod_staging_d}/${rsa_id}.pub ${rsa_id_f}.pub || {
+			lets -l -e "failed to copy new rsa_id.pub"
+			sudo rm -f ${rsa_id_f}
+			return $s_err
+		}
+	else
+		lets -l -i "no need to copy new rsa_id.pub"
+	fi
+}
diff --git a/module/gerrit/scheme.sh b/module/gerrit/scheme.sh
index 04932ee..8f0f8f8 100644
--- a/module/gerrit/scheme.sh
+++ b/module/gerrit/scheme.sh
@@ -217,6 +217,10 @@
                       create named project with additional flags
   create-permission   <project name>
                       create permission project, for access control only
+  add-ssh-key         <container-user> <container-name>
+                      import into Gerrit its own container id_rsa.pub. Then, copy
+                      Gerrit's container public key into <container-name> to allow
+                      pubkey authentication. Create a new pubkey if doesn't exists.
   cli                 <$@>
                       any valid list of arguments
 
@@ -419,6 +423,71 @@
 	gcp_import_repo_list \$dry \$src \$dst \${list[@]//\$src\\//}
 }
 
+function gssh_add_container_pubkey
+{
+	local -r running_services=\\
+\"sudo -E docker-compose ps --services --filter \\\"status=running\\\"\"
+	local -r host_container=\"\$2\"
+
+	local -r host_user=\"\$1\"
+	if [ \"\$host_user\" = \"root\" ]; then
+		local -r keys_f=\"/\$host_user/.ssh/authorized_keys\"
+	else
+		local -r keys_f=\"/home/\$host_user/.ssh/authorized_keys\"
+	fi
+
+	pushd ${instance_d} >/dev/null || exit 1
+	if ! (eval \"\${running_services}\" | \\
+		grep -q -- \"${_GERRIT_DKRC_SERVICE_}\"); then
+		echo \"error: ${_GERRIT_DKRC_SERVICE_} not running\" >&2
+		popd >/dev/null || exit 1
+		exit 1
+	fi
+	popd >/dev/null || exit 1
+
+	if sudo -E docker exec ${_GERRIT_DKRC_CONTAINER_} /bin/bash -c \\
+		'test -f ${_GERRIT_SSH_RSA_ID_F_}'; then
+		echo \"info: '${_GERRIT_SSH_RSA_ID_F_}' found\" >&2
+	else
+		echo \"error: ${_GERRIT_SSH_RSA_ID_F_} not found\" >&2
+		echo \"error: run --upmod=gerrit and restart the instance\" >&2
+		exit 1
+	fi
+
+	if (sudo -E docker exec ${_GERRIT_DKRC_CONTAINER_} \\
+		/bin/bash -c 'cat ${_GERRIT_SSH_RSA_ID_F_}.pub') | \\
+		gerrit_cli set-account --add-ssh-key - \$SSH_USER; then
+		echo \"info: public key added to Gerrit\" >&2
+	else
+		echo \"error: failed to add public key to Gerrit\" >&2
+		exit 1
+	fi
+
+	if (sudo -E docker exec \${host_container} /bin/bash -c \"cat \$keys_f\") | \\
+		grep -q -- \"\$(sudo -E docker exec ${_GERRIT_DKRC_CONTAINER_} \\
+				/bin/bash -c 'cat ${_GERRIT_SSH_RSA_ID_F_}.pub')\"; then
+		echo \"warning: public key already added to \$host_container\" >&2
+		exit 0
+	fi
+
+	local -r gerrit_pub=\"\$(sudo -E docker exec ${_GERRIT_DKRC_CONTAINER_} \\
+				/bin/bash -c 'cat ${_GERRIT_SSH_RSA_ID_F_}.pub')\"
+	if (sudo -E docker exec \${host_container} /bin/bash -c \\
+		\"echo \\\"\$gerrit_pub\\\" | tee -a \$keys_f\"); then
+
+		if (sudo -E docker exec \${host_container} /bin/bash -c \\
+			\"chmod 0600 \$keys_f && chown \$host_user:\$host_user \$keys_f\"); then
+			echo \"info: public key added to \$host_container\" >&2
+			exit 0
+		fi
+		echo \"error: failed to set public key file mode\" >&2
+		exit 1
+	fi
+
+	echo \"error: public key *NOT* added to \$host_container\" >&2
+	exit 1
+}
+
 function __do_import
 {
 	if [ -z \"\$1\" ] || [ ! -d \"\$1\" ]; then
@@ -484,6 +553,11 @@
 	gcp_permission_only \$@
 }
 
+function __do_ssh_id
+{
+	gssh_add_container_pubkey \$@
+}
+
 function __do_unknown
 {
 	if [ \"\$1\" != help ]; then
@@ -519,6 +593,7 @@
 	delete            ) __do_delete \$@     ;;
 	create            ) __do_create \$@     ;;
 	create-permission ) __do_cpermi \$@     ;;
+	add-ssh-key       ) __do_ssh_id \$@     ;;
 	cli               ) __do_cli \$@        ;;
 	*                 ) __do_unknown \$__do ;;
 esac"