module: add openssh
diff --git a/MANIFEST.container.openssh b/MANIFEST.container.openssh
new file mode 100644
index 0000000..41706f2
--- /dev/null
+++ b/MANIFEST.container.openssh
@@ -0,0 +1,71 @@
+#!/bin/bash
+#
+# MANIFEST
+#
+# Copyright 2019 Luigi Santivetti <luigi.santivetti@gmail.com>
+
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+# @@MIRROR_BEGIN@@
+#module=
+#mirror=
+#protocol=
+#branch=
+#host=
+#user=
+#format=
+#file=
+#method={git-archive|git-clone|wget-file}
+# @@MIRROR_ENDED@@
+
+# @@MIRROR_BEGIN@@
+modname=apache
+mirror=code-igniter-v3-giggi.git
+protocol=file
+branch=gg.rel
+host=/mirror
+method=git-clone
+# @@MIRROR_ENDED@@
+
+# @@MIRROR_BEGIN@@
+modname=apache
+mirror=pelican-subtle-giggi.git
+protocol=file
+branch=gg.rel
+host=/mirror
+method=git-clone
+# @@MIRROR_ENDED@@
+
+# @@MIRROR_BEGIN@@
+modname=apache
+mirror=mdcon.git
+protocol=file
+branch=master
+host=/mirror
+method=git-clone
+# @@MIRROR_ENDED@@
+
+# @@MIRROR_BEGIN@@
+modname=gerrit
+mirror=gerrit-hooks.git
+protocol=file
+branch=master
+host=/mirror
+method=git-clone
+# @@MIRROR_ENDED@@
diff --git a/module/compose/module.sh b/module/compose/module.sh
index d7e397e..546f50c 100644
--- a/module/compose/module.sh
+++ b/module/compose/module.sh
@@ -26,7 +26,7 @@
 source $common_sh
 
 module_enable $module
-declare -ar depmod=( gerrit mysql apache )
+declare -ar depmod=( gerrit mysql apache openssh )
 
 declare -r environment="common.env"
 declare -r environment_f="${instance_d}/${environment}"
diff --git a/module/compose/scheme.sh b/module/compose/scheme.sh
index 17255ca..e134384 100644
--- a/module/compose/scheme.sh
+++ b/module/compose/scheme.sh
@@ -26,8 +26,12 @@
 	declare -r compose_has_mount_media="\
       - ${_APACHE_HTML_PHOTOS_D_}:/var/www/html/photos
       - ${_APACHE_HTML_VIDEOS_D_}:/var/www/html/videos"
+	declare -r compose_openssh_has_mount_media="\
+      - ${_APACHE_HTML_PHOTOS_D_}:${_APACHE_HTML_PHOTOS_D_}
+      - ${_APACHE_HTML_VIDEOS_D_}:${_APACHE_HTML_VIDEOS_D_}"
 else
 	declare -r compose_has_mount_media=""
+	declare -r compose_openssh_has_mount_media=""
 fi
 
 if [ "${_GERRIT_HAS_HTTPS_}" -eq 1 ]; then
@@ -75,8 +79,14 @@
       - CANONICAL_WEB_URL=${_GERRIT_CANON_URL_}
       - 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_REMOTE_HOST=${_OPENSSH_IP_}
+      - HOOKS_REMOTE_PATH=${_OPENSSH_MIRROR_CON_D_}
+      - HOOKS_REMOTE_PORT=${_OPENSSH_PORT_}
+      - HOOKS_REMOTE_USER=${_OPENSSH_GIT_USER_}
+      - HOOKS_GERRIT_HOST=${host_name}
+      - HOOKS_GERRIT_PORT=${_GERRIT_SSH_PORT_}
+      - HOOKS_DEPLOY_EXEC=${_OPENSSH_TOD_EXEC_}
       - HOOKS_LOG_DIR=${_GERRIT_HOOKS_LOG_CON_D_}
     depends_on:
       - ${_APACHE_DKRC_SERVICE_}
@@ -140,7 +150,36 @@
       - ${_MYSQL_INITDB_F_}:/docker-entrypoint-initdb.d/initdb.sql
       - ${_MYSQL_MYCONF_F_}:/etc/mysql/my.cnf:ro
       - ${_MYSQL_MYSQL_D_}:/var/lib/mysql
-      - ${_MYSQL_LOG_D_}:${_MYSQL_CON_LOG_D_}"
+      - ${_MYSQL_LOG_D_}:${_MYSQL_CON_LOG_D_}
+  ${_OPENSSH_DKRC_SERVICE_}:
+    environment:
+      - PUID=${_OPENSSH_GIT_UID_}
+      - PGID=${_OPENSSH_GIT_GID_}
+      - TZ=Europe/London
+      - SUDO_ACCESS=true
+      - PASSWORD_ACCESS=false
+      - USER_NAME=${_OPENSSH_GIT_USER_}
+      - PUBLIC_KEY_FILE=${_OPENSSH_CLIENT_PUBKEY_}
+    image: ${_OPENSSH_DKRC_IMAGE_}
+    build:
+      context: ${_OPENSSH_DKRC_CONTEXT_}
+      dockerfile: ${_OPENSSH_DKRC_DOCKERFILE_}
+    container_name: ${_OPENSSH_DKRC_CONTAINER_}
+    restart: unless-stopped
+    networks:
+      frontend:
+        ipv4_address: ${_OPENSSH_IP_}
+    expose:
+      - ${_OPENSSH_PORT_}
+    volumes:
+      - ${_GERRIT_HOST_RSA_ID_F_}.pub:${_OPENSSH_CLIENT_PUBKEY_}
+      - ${_OPENSSH_MIRROR_D_}:${_OPENSSH_MIRROR_CON_D_}
+      - ${_OPENSSH_TOD_D_}:${_OPENSSH_TOD_CON_D_}
+      - ${_OPENSSH_LOG_D_}:/config/logs
+      - ${_APACHE_DKRC_WWW_D_}:/rootfs/var/www
+      - ${_GERRIT_DKRC_HOOKS_D_}:/rootfs/hooks
+      - ${_GERRIT_DKRC_ETC_D_}:/rootfs/etc
+${compose_openssh_has_mount_media}"
 
 declare -r environment_t="\
 MYSQL_DATABASE=${_MYSQL_DB_NAME_}
diff --git a/module/openssh/holder.sh b/module/openssh/holder.sh
new file mode 100644
index 0000000..85cc582
--- /dev/null
+++ b/module/openssh/holder.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+#
+# openssh - holder
+#
+# Copyright 20209 Luigi Santivetti <luigi.santivetti@gmail.com>
+
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+_OPENSSH_DKRC_SERVICE_="openssh"
+_OPENSSH_DKRC_IMAGE_="${host_name}-img-${_OPENSSH_DKRC_SERVICE_}"
+_OPENSSH_DKRC_CONTAINER_="${host_name}-con-${_OPENSSH_DKRC_SERVICE_}"
+_OPENSSH_DKRC_CONTEXT_="${mod_docker_d}"
+_OPENSSH_DKRC_DOCKERFILE_="Dockerfile"
+# If trying to reach from within the docker network, it must be on the same
+# subnet.
+_OPENSSH_IP_="172.28.0.4"
+_OPENSSH_PORT_="2222"
+_OPENSSH_MIRROR_D_="$HOME/__vc/mirror"
+_OPENSSH_MIRROR_CON_D_="/mirror"
+_OPENSSH_TOD_D_="$HOME/tod"
+_OPENSSH_TOD_CON_D_="/tod"
+_OPENSSH_GIT_USER_="githuser"
+_OPENSSH_GIT_GID_="$(stat -c '%g' "${_OPENSSH_MIRROR_D_}")"
+_OPENSSH_GIT_UID_="$(stat -c '%u' "${_OPENSSH_MIRROR_D_}")"
+_OPENSSH_CLIENT_PUBKEY_="/client_rsa_id.pub"
+_OPENSSH_TOD_EXEC_="${_OPENSSH_TOD_CON_D_}/tod.container.openssh"
+_OPENSSH_LOG_D_="${log_d}"
diff --git a/module/openssh/module.sh b/module/openssh/module.sh
new file mode 100644
index 0000000..2244cea
--- /dev/null
+++ b/module/openssh/module.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+#
+# openssh - module
+#
+# Copyright 20209 Luigi Santivetti <luigi.santivetti@gmail.com>
+
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+declare -r module="openssh"
+source $common_sh
+
+module_enable $module
+
+declare -r dockerfile_f="$mod_docker_d/Dockerfile"
+declare -r log_d="${mod_rootfs_d}/var/log/openssh"
+
+declare -ar mod_mor_dirs=( $log_d )
+declare -ar mod_more_files=( $dockerfile_f )
+declare -ar mod_more_trefs=( dockerfile_t )
+
+function tod_watch
+{
+	__watch_module_common || return $s_err
+}
+
+function tod_doins
+{
+	__doins_module_common || return $s_err
+}
+
+function tod_upins
+{
+	__upins_module_common || return $s_err
+}
+
+function tod_clins
+{
+	__clins_module_common || return $s_err
+}
diff --git a/module/openssh/scheme.sh b/module/openssh/scheme.sh
new file mode 100644
index 0000000..cdb2bb5
--- /dev/null
+++ b/module/openssh/scheme.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+#
+# openssh - scheme
+#
+# Copyright 20209 Luigi Santivetti <luigi.santivetti@gmail.com>
+
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+# https://github.com/linuxserver/docker-openssh-server
+declare -r dockerfile_t="\
+FROM linuxserver/openssh-server:latest AS base
+RUN \\
+ echo \"**** upgrade runtime packages ****\" && \\
+ apk -U upgrade \\
+ echo \"**** install runtime packages: git ****\" && \\
+ apk add --no-cache --upgrade git && \\
+ echo \"**** install runtime packages: make ****\" && \\
+ apk add --no-cache --upgrade make && \\
+ echo \"**** install runtime packages: rsync ****\" && \\
+ apk add --no-cache --upgrade rsync && \\
+ echo \"**** install runtime packages: ffmpeg ****\" && \\
+ apk add --no-cache --upgrade ffmpeg && \\
+ echo \"**** install runtime packages: python3 ****\" && \\
+ apk add --no-cache --upgrade python3 && \\
+ echo \"**** install runtime packages: pip3 ****\" && \\
+ apk add --no-cache --upgrade py3-pip && \\
+ echo \"**** install runtime packages: virtualenv ****\" && \\
+ apk add --no-cache --upgrade py3-virtualenv && \\
+ echo \"**** install runtime packages: build-base ****\" && \\
+ apk add --no-cache --upgrade build-base && \\
+ echo \"**** install runtime packages: python3-dev ****\" && \\
+ apk add --no-cache --upgrade python3-dev && \\
+ echo \"**** install runtime packages: jpeg-dev ****\" && \\
+ apk add --no-cache --upgrade jpeg-dev && \\
+ echo \"**** install runtime packages: zlib-dev ****\" && \\
+ apk add --no-cache --upgrade zlib-dev
+
+RUN sed -i \"s%#PubkeyAuthentication yes%PubkeyAuthentication yes%g\" /etc/ssh/sshd_config"
diff --git a/tod.container.openssh b/tod.container.openssh
new file mode 100755
index 0000000..945f055
--- /dev/null
+++ b/tod.container.openssh
@@ -0,0 +1,57 @@
+#!/bin/bash
+
+if (return 0 2>/dev/null); then
+	echo "Do not source, instead run ${BASH_SOURCE[0]}" >&2
+else
+	export INSTANCE_MODE="release"
+	export HOST_NAME="giggi.me"
+	export INSTANCE_DIR=""
+	export MANIFEST_F="MANIFEST.container.openssh"
+	export DEFANS="n"
+
+	LOG_DIR="/config/logs"
+	TOD_DIR="/tod"
+	args="${@}"
+
+	declare -ar apache_live=( code-igniter-v3-giggi pelican-subtle-giggi mdcon )
+	declare -ar gerrit_live=( gerrit-hooks )
+
+	declare -A CHANGE=(
+		[change]=""
+		[change-url]=""
+		[change-owner]=""
+		[change-owner-username]=""
+		[project]=""
+		[branch]=""
+		[topic]=""
+		[submitter]=""
+		[submitter-username]=""
+		[commit]=""
+		[newrev]=""
+	)
+
+	set -x
+	while read -a line; do
+		for K in ${!CHANGE[@]}; do
+			if [ "${line[0]}" == "--$K" ]; then
+				CHANGE[$K]="${line[@]:1}"
+				break
+			fi
+		done
+	done <<< $(echo -e ${args// --/\\n--})
+
+	pushd $TOD_DIR >/dev/null
+	case "${CHANGE[project]}" in
+		${apache_live[0]} | ${apache_live[1]} | ${apache_live[2]} )
+			./tod --upmod=apache &> $LOG_DIR/tod.hooks-upmod_apache_live.txt
+			;;
+		${gerrit_live[0]} )
+			./tod --upmod=gerrit &> $LOG_DIR/tod.hooks-upmod_gerrit_live.txt
+			;;
+	esac
+	RET=$?
+	popd >/dev/null
+	set +x
+fi
+
+[ "$RET" -eq 0 ]