summaryrefslogtreecommitdiff
path: root/addons/point_of_sale/tools/posbox
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/point_of_sale/tools/posbox
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/point_of_sale/tools/posbox')
-rw-r--r--addons/point_of_sale/tools/posbox/.gitignore3
-rwxr-xr-xaddons/point_of_sale/tools/posbox/configuration/connect_to_server.sh48
-rwxr-xr-xaddons/point_of_sale/tools/posbox/configuration/connect_to_server_wifi.sh133
-rwxr-xr-xaddons/point_of_sale/tools/posbox/configuration/connect_to_wifi.sh90
-rwxr-xr-xaddons/point_of_sale/tools/posbox/configuration/keep_wifi_alive.sh17
-rwxr-xr-xaddons/point_of_sale/tools/posbox/configuration/led_status.sh19
-rw-r--r--addons/point_of_sale/tools/posbox/configuration/nginx_ap.conf97
-rw-r--r--addons/point_of_sale/tools/posbox/configuration/odoo.conf7
-rwxr-xr-xaddons/point_of_sale/tools/posbox/configuration/posbox_update.sh33
-rwxr-xr-xaddons/point_of_sale/tools/posbox/configuration/setup_ramdisks.sh28
-rwxr-xr-xaddons/point_of_sale/tools/posbox/configuration/upgrade.sh232
-rwxr-xr-xaddons/point_of_sale/tools/posbox/configuration/wireless_ap.sh53
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/X11/xorg.conf60
-rwxr-xr-xaddons/point_of_sale/tools/posbox/overwrite_after_init/etc/cron.daily/odoo3
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/cups/cups-files.conf93
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/cups/cupsd.conf186
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/default/hostapd20
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/default/ifplugd17
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dhcp/dhcpd.conf113
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dhcpcd.conf47
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dnsmasq.conf669
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/fstab4
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/hostapd/hostapd.conf3
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ld.so.preload1
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf8
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/network/interfaces3
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/nginx/sites-enabled/default92
-rwxr-xr-xaddons/point_of_sale/tools/posbox/overwrite_after_init/etc/rc.local25
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/resolv.conf5
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ssl/certs/nginx-cert.crt23
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ssl/private/nginx-cert.key28
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/home/pi/odoo/addons/point_of_sale/__manifest__.py4
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/usr/local/lib/python3.7/dist-packages/v4l2.py.iotpatch20
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/usr/share/eftdvs/eftdvs.cfg1
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/usr/share/firefox-esr/browser/defaults/preferences/all-posbox.js12
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/var/www/iot.jpgbin0 -> 5444 bytes
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/etc/default/keyboard10
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/etc/fstab5
-rwxr-xr-xaddons/point_of_sale/tools/posbox/overwrite_before_init/etc/init.d/odoo78
-rwxr-xr-xaddons/point_of_sale/tools/posbox/overwrite_before_init/etc/init.d/timesyncd41
-rwxr-xr-xaddons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh171
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/etc/ld.so.preload1
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/etc/locale.gen7
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/etc/logrotate.conf32
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/etc/logrotate.d/odoo5
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/etc/logrotate.d/rsyslog37
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/etc/nginx/sites-enabled/default87
-rwxr-xr-xaddons/point_of_sale/tools/posbox/overwrite_before_init/etc/rc.local22
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/etc/systemd/system/led-status.service10
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/etc/systemd/system/ramdisks.service12
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/90-qemu.rules3
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/99-usb.rules2
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/99-z-input.rules2
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.inputrc53
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.vimrc27
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.xsession5
-rwxr-xr-xaddons/point_of_sale/tools/posbox/posbox_create_image.sh162
57 files changed, 2969 insertions, 0 deletions
diff --git a/addons/point_of_sale/tools/posbox/.gitignore b/addons/point_of_sale/tools/posbox/.gitignore
new file mode 100644
index 00000000..b26eafa3
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/.gitignore
@@ -0,0 +1,3 @@
+kernel-qemu
+posbox.img
+raspbian.img \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/configuration/connect_to_server.sh b/addons/point_of_sale/tools/posbox/configuration/connect_to_server.sh
new file mode 100755
index 00000000..3c6e8be5
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/configuration/connect_to_server.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+
+# Write the server configuration
+function connect () {
+ SERVER="${1}"
+ CURRENT_SERVER_FILE=/home/pi/odoo-remote-server.conf
+ TOKEN_FILE=/home/pi/token
+ TOKEN="${3}"
+ REBOOT="${4}"
+ HOSTS=/root_bypass_ramdisks/etc/hosts
+ HOST_FILE=/root_bypass_ramdisks/etc/hostname
+ HOSTNAME="$(hostname)"
+ IOT_NAME="${2}"
+ IOT_NAME="${IOT_NAME//[^[:ascii:]]/}"
+ IOT_NAME="${IOT_NAME//[^a-zA-Z0-9-]/}"
+ if [ -z "$IOT_NAME" ]
+ then
+ IOT_NAME="${HOSTNAME}"
+ fi
+ sudo mount -o remount,rw /
+ sudo mount -o remount,rw /root_bypass_ramdisks
+ if [ ! -z "${1}" ]
+ then
+ echo "${SERVER}" > ${CURRENT_SERVER_FILE}
+ echo "${TOKEN}" > ${TOKEN_FILE}
+ fi
+ if [ "${IOT_NAME}" != "${HOSTNAME}" ]
+ then
+ sudo sed -i "s/${HOSTNAME}/${IOT_NAME}/g" ${HOSTS}
+ echo "${IOT_NAME}" > /tmp/hostname
+ sudo cp /tmp/hostname "${HOST_FILE}"
+
+ echo "interface=wlan0" > /root_bypass_ramdisks/etc/hostapd/hostapd.conf
+ echo "ssid=${IOT_NAME}" >> /root_bypass_ramdisks/etc/hostapd/hostapd.conf
+ echo "channel=1" >> /root_bypass_ramdisks/etc/hostapd/hostapd.conf
+
+ sudo hostname "${IOT_NAME}"
+ sudo reboot
+ fi
+ sudo mount -o remount,ro /
+ sudo mount -o remount,ro /root_bypass_ramdisks
+ if [ "$REBOOT" == 'reboot' ]
+ then
+ sudo service odoo restart
+ fi
+}
+
+connect "${1}" "${2}" "${3}" "${4}" \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/configuration/connect_to_server_wifi.sh b/addons/point_of_sale/tools/posbox/configuration/connect_to_server_wifi.sh
new file mode 100755
index 00000000..12c74f61
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/configuration/connect_to_server_wifi.sh
@@ -0,0 +1,133 @@
+#!/usr/bin/env bash
+
+# Write the server configuration
+# call with ESSID and optionally a password
+# when called without an ESSID, it will attempt
+# to reconnect to a previously chosen network
+function connect () {
+ SERVER="${1}"
+ CURRENT_SERVER_FILE=/home/pi/odoo-remote-server.conf
+ HOSTS=/root_bypass_ramdisks/etc/hosts
+ HOST_FILE=/root_bypass_ramdisks/etc/hostname
+ HOSTNAME="$(hostname)"
+ TOKEN_FILE=/home/pi/token
+ TOKEN="${3}"
+ IOT_NAME="${2}"
+ IOT_NAME="${IOT_NAME//[^[:ascii:]]/}"
+ IOT_NAME="${IOT_NAME//[^a-zA-Z0-9-]/}"
+ if [ -z "$IOT_NAME" ]
+ then
+ IOT_NAME="${HOSTNAME}"
+ fi
+ sudo mount -o remount,rw /
+ sudo mount -o remount,rw /root_bypass_ramdisks
+ if [ ! -z "${1}" ]
+ then
+ echo "${SERVER}" > ${CURRENT_SERVER_FILE}
+ echo "${TOKEN}" > ${TOKEN_FILE}
+ fi
+ if [ "${IOT_NAME}" != "${HOSTNAME}" ]
+ then
+ sudo sed -i "s/${HOSTNAME}/${IOT_NAME}/g" ${HOSTS}
+ echo "${IOT_NAME}" > /tmp/hostname
+ sudo cp /tmp/hostname "${HOST_FILE}"
+
+ echo "interface=wlan0" > /root_bypass_ramdisks/etc/hostapd/hostapd.conf
+ echo "ssid=${IOT_NAME}" >> /root_bypass_ramdisks/etc/hostapd/hostapd.conf
+ echo "channel=1" >> /root_bypass_ramdisks/etc/hostapd/hostapd.conf
+
+ sudo hostname "${IOT_NAME}"
+ fi
+ sudo mount -o remount,ro /
+ sudo mount -o remount,ro /root_bypass_ramdisks
+
+ WPA_PASS_FILE="/tmp/wpa_pass.txt"
+ PERSISTENT_WIFI_NETWORK_FILE="/home/pi/wifi_network.txt"
+ CURRENT_WIFI_NETWORK_FILE="/tmp/current_wifi_network.txt" # used to repair connection when we lose it
+ LOST_WIFI_FILE="/tmp/lost_wifi.txt"
+ ESSID="${4}"
+ PASSWORD="${5}"
+ PERSIST="${6}"
+ NO_AP="${7}"
+
+ sleep 3
+
+ sudo pkill -f keep_wifi_alive.sh
+ WIFI_WAS_LOST=$?
+
+ # make network choice persistent
+ if [ -n "${ESSID}" ] ; then
+ if [ -n "${PERSIST}" ] ; then
+ logger -t posbox_connect_to_wifi "Making network selection permanent"
+ sudo mount -o remount,rw /
+ echo "${ESSID}" > ${PERSISTENT_WIFI_NETWORK_FILE}
+ echo "${PASSWORD}" >> ${PERSISTENT_WIFI_NETWORK_FILE}
+ sudo mount -o remount,ro /
+ fi
+ else
+ logger -t posbox_connect_to_wifi "Reading configuration from ${PERSISTENT_WIFI_NETWORK_FILE}"
+ ESSID=$(head -n 1 "${PERSISTENT_WIFI_NETWORK_FILE}" | tr -d '\n')
+ PASSWORD=$(tail -n 1 "${PERSISTENT_WIFI_NETWORK_FILE}" | tr -d '\n')
+ fi
+
+ echo "${ESSID}" > ${CURRENT_WIFI_NETWORK_FILE}
+ echo "${PASSWORD}" >> ${CURRENT_WIFI_NETWORK_FILE}
+
+ logger -t posbox_connect_to_wifi "Connecting to ${ESSID}"
+ sudo service hostapd stop
+ sudo killall nginx
+ sudo service nginx restart
+ sudo service dnsmasq stop
+
+ sudo pkill wpa_supplicant
+ sudo ifconfig wlan0 down
+ sudo ifconfig wlan0 0.0.0.0 # this is how you clear the interface's configuration
+ sudo ifconfig wlan0 up
+
+ if [ -z "${PASSWORD}" ] ; then
+ sudo iwconfig wlan0 essid "${ESSID}"
+ else
+ # Necessary in stretch: https://www.raspberrypi.org/forums/viewtopic.php?t=196927
+ sudo cp /etc/wpa_supplicant/wpa_supplicant.conf "${WPA_PASS_FILE}"
+ sudo chmod 777 "${WPA_PASS_FILE}"
+ sudo wpa_passphrase "${ESSID}" "${PASSWORD}" >> "${WPA_PASS_FILE}"
+ sudo wpa_supplicant -B -i wlan0 -c "${WPA_PASS_FILE}"
+ fi
+
+ sudo systemctl daemon-reload
+ sudo service dhcpcd restart
+
+ # give dhcp some time
+ timeout 30 sh -c 'until ifconfig wlan0 | grep "inet " ; do sleep 0.1 ; done'
+ TIMEOUT_RETURN=$?
+
+
+ if [ ${TIMEOUT_RETURN} -eq 124 ] && [ -z "${NO_AP}" ] ; then
+ logger -t posbox_connect_to_wifi "Failed to connect, forcing Posbox AP"
+ sudo /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/wireless_ap.sh "force" &
+ else
+ if [ ${TIMEOUT_RETURN} -ne 124 ] ; then
+ rm -f "${LOST_WIFI_FILE}"
+ fi
+
+ if [ ! -f "${LOST_WIFI_FILE}" ] ; then
+ logger -t posbox_connect_to_wifi "Restarting odoo"
+ fi
+
+ if [ ${WIFI_WAS_LOST} -eq 0 ] ; then
+ touch "${LOST_WIFI_FILE}"
+ fi
+
+ logger -t posbox_connect_to_wifi "Starting wifi keep alive script"
+ /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/keep_wifi_alive.sh &
+ fi
+
+ if [ "${IOT_NAME}" != "${HOSTNAME}" ]
+ then
+ sudo reboot
+ else
+ sudo service odoo restart
+ fi
+}
+
+connect "${1}" "${2}" "${3}" "${4}" "${5}" "${6}" "${7}" &
diff --git a/addons/point_of_sale/tools/posbox/configuration/connect_to_wifi.sh b/addons/point_of_sale/tools/posbox/configuration/connect_to_wifi.sh
new file mode 100755
index 00000000..c843d605
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/configuration/connect_to_wifi.sh
@@ -0,0 +1,90 @@
+#!/usr/bin/env bash
+
+# call with ESSID and optionally a password
+# when called without an ESSID, it will attempt
+# to reconnect to a previously chosen network
+function connect () {
+ WPA_PASS_FILE="/tmp/wpa_pass.txt"
+ PERSISTENT_WIFI_NETWORK_FILE="/home/pi/wifi_network.txt"
+ CURRENT_WIFI_NETWORK_FILE="/tmp/current_wifi_network.txt" # used to repair connection when we lose it
+ LOST_WIFI_FILE="/tmp/lost_wifi.txt"
+ ESSID="${1}"
+ PASSWORD="${2}"
+ PERSIST="${3}"
+ NO_AP="${4}"
+
+ sleep 3
+
+ sudo pkill -f keep_wifi_alive.sh
+ WIFI_WAS_LOST=$?
+
+ # make network choice persistent
+ if [ -n "${ESSID}" ] ; then
+ if [ -n "${PERSIST}" ] ; then
+ logger -t posbox_connect_to_wifi "Making network selection permanent"
+ sudo mount -o remount,rw /
+ echo "${ESSID}" > ${PERSISTENT_WIFI_NETWORK_FILE}
+ echo "${PASSWORD}" >> ${PERSISTENT_WIFI_NETWORK_FILE}
+ sudo mount -o remount,ro /
+ fi
+ else
+ logger -t posbox_connect_to_wifi "Reading configuration from ${PERSISTENT_WIFI_NETWORK_FILE}"
+ ESSID=$(head -n 1 "${PERSISTENT_WIFI_NETWORK_FILE}" | tr -d '\n')
+ PASSWORD=$(tail -n 1 "${PERSISTENT_WIFI_NETWORK_FILE}" | tr -d '\n')
+ fi
+
+ echo "${ESSID}" > ${CURRENT_WIFI_NETWORK_FILE}
+ echo "${PASSWORD}" >> ${CURRENT_WIFI_NETWORK_FILE}
+
+ logger -t posbox_connect_to_wifi "Connecting to ${ESSID}"
+ sudo service hostapd stop
+ sudo killall nginx
+ sudo service nginx restart
+ sudo service dnsmasq stop
+
+ sudo pkill wpa_supplicant
+ sudo ifconfig wlan0 down
+ sudo ifconfig wlan0 0.0.0.0 # this is how you clear the interface's configuration
+ sudo ifconfig wlan0 up
+
+ if [ -z "${PASSWORD}" ] ; then
+ sudo iwconfig wlan0 essid "${ESSID}"
+ else
+ # Necessary in stretch: https://www.raspberrypi.org/forums/viewtopic.php?t=196927
+ sudo cp /etc/wpa_supplicant/wpa_supplicant.conf "${WPA_PASS_FILE}"
+ sudo chmod 777 "${WPA_PASS_FILE}"
+ sudo wpa_passphrase "${ESSID}" "${PASSWORD}" >> "${WPA_PASS_FILE}"
+ sudo wpa_supplicant -B -i wlan0 -c "${WPA_PASS_FILE}"
+ fi
+
+ sudo systemctl daemon-reload
+ sudo service dhcpcd restart
+
+ # give dhcp some time
+ timeout 30 sh -c 'until ifconfig wlan0 | grep "inet " ; do sleep 0.1 ; done'
+ TIMEOUT_RETURN=$?
+
+
+ if [ ${TIMEOUT_RETURN} -eq 124 ] && [ -z "${NO_AP}" ] ; then
+ logger -t posbox_connect_to_wifi "Failed to connect, forcing Posbox AP"
+ sudo /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/wireless_ap.sh "force" &
+ else
+ if [ ${TIMEOUT_RETURN} -ne 124 ] ; then
+ rm -f "${LOST_WIFI_FILE}"
+ fi
+
+ if [ ! -f "${LOST_WIFI_FILE}" ] ; then
+ logger -t posbox_connect_to_wifi "Restarting odoo"
+ sudo service odoo restart
+ fi
+
+ if [ ${WIFI_WAS_LOST} -eq 0 ] ; then
+ touch "${LOST_WIFI_FILE}"
+ fi
+
+ logger -t posbox_connect_to_wifi "Starting wifi keep alive script"
+ /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/keep_wifi_alive.sh &
+ fi
+}
+
+connect "${1}" "${2}" "${3}" "${4}" &
diff --git a/addons/point_of_sale/tools/posbox/configuration/keep_wifi_alive.sh b/addons/point_of_sale/tools/posbox/configuration/keep_wifi_alive.sh
new file mode 100755
index 00000000..5c8a2749
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/configuration/keep_wifi_alive.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+CURRENT_WIFI_NETWORK_FILE="/tmp/current_wifi_network.txt"
+while true ; do
+ if [ -z "$(cat <(ifconfig eth0) <(ifconfig wlan0) | grep "inet ";)" ] ; then
+ ESSID=$(head -n 1 "${CURRENT_WIFI_NETWORK_FILE}" | tr -d '\n')
+ PASSWORD=$(tail -n 1 "${CURRENT_WIFI_NETWORK_FILE}" | tr -d '\n')
+
+ logger -t posbox_keep_wifi_alive "Lost wifi, trying to reconnect to ${ESSID}"
+
+ sudo /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/connect_to_wifi.sh "${ESSID}" "${PASSWORD}" "" "NO_AP"
+
+ sleep 30
+ fi
+
+ sleep 2
+done
diff --git a/addons/point_of_sale/tools/posbox/configuration/led_status.sh b/addons/point_of_sale/tools/posbox/configuration/led_status.sh
new file mode 100755
index 00000000..8d272d7d
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/configuration/led_status.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+set_brightness() {
+ echo "${1}" > /sys/class/leds/led0/brightness
+}
+
+check_status_loop() {
+ while true ; do
+ if wget --quiet localhost:8069/hw_proxy/hello -O /dev/null ; then
+ set_brightness 255
+ else
+ set_brightness 0
+ fi
+ sleep 5
+ done
+}
+
+echo none > /sys/class/leds/led0/trigger
+check_status_loop
diff --git a/addons/point_of_sale/tools/posbox/configuration/nginx_ap.conf b/addons/point_of_sale/tools/posbox/configuration/nginx_ap.conf
new file mode 100644
index 00000000..a64a6f6b
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/configuration/nginx_ap.conf
@@ -0,0 +1,97 @@
+user www-data;
+worker_processes auto;
+pid /run/nginx.pid;
+include /etc/nginx/modules-enabled/*.conf;
+
+events {
+ worker_connections 768;
+ # multi_accept on;
+}
+
+http {
+
+ ##
+ # Basic Settings
+ ##
+
+ sendfile on;
+ tcp_nopush on;
+ tcp_nodelay on;
+ keepalive_timeout 65;
+ types_hash_max_size 2048;
+ # server_tokens off;
+
+ # server_names_hash_bucket_size 64;
+ # server_name_in_redirect off;
+
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+
+ ##
+ # SSL Settings
+ ##
+
+ ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
+ ssl_prefer_server_ciphers on;
+
+ ##
+ # Logging Settings
+ ##
+
+ access_log /var/log/nginx/access.log;
+ error_log /var/log/nginx/error.log;
+
+ ##
+ # Gzip Settings
+ ##
+
+ gzip on;
+ gzip_disable "msie6";
+
+ # gzip_vary on;
+ # gzip_proxied any;
+ # gzip_comp_level 6;
+ # gzip_buffers 16 8k;
+ # gzip_http_version 1.1;
+ # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
+
+ ##
+ # Virtual Host Configs
+ ##
+
+ include /etc/nginx/conf.d/*.conf;
+ #include /etc/nginx/sites-enabled/*;
+ server {
+ listen 80 default_server;
+
+ location / {
+ # Every OS request specific address and .txt file to test if hotspot are connected to internet however login splash page don't display
+ # this line respond true for every request and send a login splash page to client
+ # it work for every OS
+ return 301 $scheme://10.11.12.1:8069;
+ }
+
+}
+}
+
+
+#mail {
+# # See sample authentication script at:
+# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
+#
+# # auth_http localhost/auth.php;
+# # pop3_capabilities "TOP" "USER";
+# # imap_capabilities "IMAP4rev1" "UIDPLUS";
+#
+# server {
+# listen localhost:110;
+# protocol pop3;
+# proxy on;
+# }
+#
+# server {
+# listen localhost:143;
+# protocol imap;
+# proxy on;
+# }
+#}
diff --git a/addons/point_of_sale/tools/posbox/configuration/odoo.conf b/addons/point_of_sale/tools/posbox/configuration/odoo.conf
new file mode 100644
index 00000000..e274a0fe
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/configuration/odoo.conf
@@ -0,0 +1,7 @@
+[options]
+data_dir = /var/run/odoo
+log_level = error
+logfile = /var/log/odoo/odoo-server.log
+pidfile = /var/run/odoo/odoo.pid
+limit_time_cpu = 600
+limit_time_real = 1200
diff --git a/addons/point_of_sale/tools/posbox/configuration/posbox_update.sh b/addons/point_of_sale/tools/posbox/configuration/posbox_update.sh
new file mode 100755
index 00000000..2bfb9f3a
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/configuration/posbox_update.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+
+sudo mount -o remount,rw /
+
+sudo service led-status stop
+
+cd /home/pi/odoo
+localbranch=$(git symbolic-ref -q --short HEAD)
+localremote=$(git config branch.$localbranch.remote)
+
+echo "addons/point_of_sale/tools/posbox/overwrite_after_init/home/pi/odoo" >> .git/info/sparse-checkout
+
+git fetch "${localremote}" "${localbranch}" --depth=1
+git reset "${localremote}"/"${localbranch}" --hard
+
+git clean -df
+cp -a /home/pi/odoo/addons/point_of_sale/tools/posbox/overwrite_after_init/home/pi/odoo/* /home/pi/odoo/
+rm -r /home/pi/odoo/addons/point_of_sale/tools/posbox/overwrite_after_init
+
+sudo find / -type f -name "*.iotpatch" 2> /dev/null | while read iotpatch; do
+ DIR=$(dirname "${iotpatch}")
+ BASE=$(basename "${iotpatch%.iotpatch}")
+ sudo find "${DIR}" -type f -name "${BASE}" ! -name "*.iotpatch" | while read file; do
+ sudo patch -f "${file}" < "${iotpatch}"
+ done
+done
+
+sudo mount -o remount,ro /
+sudo mount -o remount,rw /root_bypass_ramdisks/etc/cups
+
+sudo service led-status start
+
+(sleep 5 && sudo service odoo restart) &
diff --git a/addons/point_of_sale/tools/posbox/configuration/setup_ramdisks.sh b/addons/point_of_sale/tools/posbox/configuration/setup_ramdisks.sh
new file mode 100755
index 00000000..01470fff
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/configuration/setup_ramdisks.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+set -o errexit
+set -o nounset
+set -o pipefail
+# set -o xtrace
+
+create_ramdisk () {
+ ORIGINAL="${1}"
+ RAMDISK="${ORIGINAL}_ram"
+ SIZE="${2}"
+ echo "Creating ramdisk for ${1} of size ${SIZE}..."
+
+ mount -t tmpfs -o size="${SIZE}" tmpfs "${RAMDISK}"
+ rsync -a --exclude="swap" --exclude="apt" --exclude="dpkg" --exclude=".mozilla" "${ORIGINAL}/" "${RAMDISK}/"
+ mount --bind "${RAMDISK}" "${ORIGINAL}"
+}
+
+echo "Creating ramdisks..."
+create_ramdisk "/var" "192M"
+create_ramdisk "/etc" "16M"
+create_ramdisk "/tmp" "64M"
+
+# bind mount / so that we can get to the real /var and /etc
+mount --bind / /root_bypass_ramdisks
+
+# allow to cups server to save configuration file of printers
+mount --bind /root_bypass_ramdisks/etc/cups /root_bypass_ramdisks/etc/cups
+mount -o remount,rw /root_bypass_ramdisks/etc/cups /root_bypass_ramdisks/etc/cups
diff --git a/addons/point_of_sale/tools/posbox/configuration/upgrade.sh b/addons/point_of_sale/tools/posbox/configuration/upgrade.sh
new file mode 100755
index 00000000..ed3fd11a
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/configuration/upgrade.sh
@@ -0,0 +1,232 @@
+#!/usr/bin/env bash
+
+file_exists () {
+ [[ -f $1 ]];
+}
+
+create_partition () {
+ mount -o remount,rw /
+
+ if [ -f start_upgrade ]
+ then
+ echo "Error_Upgrade_Already_Started"
+ exit 0
+ fi
+
+ touch start_upgrade
+
+ echo "Fdisking"
+
+ PARTITION=$(lsblk | awk 'NR==2 {print $1}')
+ PARTITION="/dev/${PARTITION}"
+ SECTORS_SIZE=$(fdisk -l "${PARTITION}" | awk 'NR==1 {print $7}')
+
+ if [ "${SECTORS_SIZE}" -lt 15583488 ] # self-flash not permited if SD size < 16gb
+ then
+ rm start_upgrade
+ echo "Error_Card_Size"
+ exit 0
+ fi
+
+ PART_ODOO_ROOT=$(fdisk -l | tail -n 1 | awk '{print $1}')
+ START_OF_ODOO_ROOT_PARTITION=$(fdisk -l | tail -n 1 | awk '{print $2}')
+ END_OF_ODOO_ROOT_PARTITION=$((START_OF_ODOO_ROOT_PARTITION + 11714061)) # sectors to have a partition of ~5.6Go
+ START_OF_UPGRADE_ROOT_PARTITION=$((END_OF_ODOO_ROOT_PARTITION + 1)) # sectors to have a partition of ~7.0Go
+ (echo 'p'; # print
+ echo 'd'; # delete partition
+ echo '2'; # number 2
+ echo 'n'; # create new partition
+ echo 'p'; # primary
+ echo '2'; # number 2
+ echo "${START_OF_ODOO_ROOT_PARTITION}"; # starting at previous offset
+ echo "${END_OF_ODOO_ROOT_PARTITION}"; # ending at ~9.9Go
+ echo 'n'; # create new partition
+ echo 'p'; # primary
+ echo '3'; # number 3
+ echo "${START_OF_UPGRADE_ROOT_PARTITION}"; # starting at previous offset
+ echo ''; # ending at default (fdisk should propose max) ~7.0Go
+ echo 'p'; # print
+ echo 'w') |fdisk "${PARTITION}" # write and quit
+
+ PART_RASPIOS_ROOT=$(sudo fdisk -l | tail -n 1 | awk '{print $1}')
+ sleep 5
+
+ # Clean partition
+ mount -o remount,rw /
+ partprobe # apply changes to partitions
+ resize2fs "${PART_ODOO_ROOT}"
+ mkfs.ext4 -Fv "${PART_RASPIOS_ROOT}" # change file sytstem
+
+ echo "end fdisking"
+}
+
+download_raspios () {
+ if [ ! -f *raspios*.img ] ; then
+ # download latest Raspios image and check integrity
+ LATEST_RASPIOS=$(curl -LIsw %{url_effective} http://downloads.raspberrypi.org/raspios_lite_armhf_latest | tail -n 1)
+ wget -c "${LATEST_RASPIOS}"
+ RASPIOS=$(echo *raspios*.zip)
+ wget -c "${LATEST_RASPIOS}".sha256
+ CHECK=$(sha256sum -c "${RASPIOS}".sha256)
+ if [ "${CHECK}" != "${RASPIOS}: OK" ]
+ then
+ # Checksum is not correct so clean and reset self-flashing
+ mount -o remount,rw /
+ # Clean raspios img
+ rm "${RASPIOS}" "${RASPIOS}".sha256
+
+ rm start_upgrade
+ echo "Error_Raspios_Download"
+ exit 0
+ fi
+ unzip "${RASPIOS}"
+ fi
+
+ echo "end dowloading raspios"
+}
+
+copy_raspios () {
+ umount -v /boot
+
+ # mapper raspios
+ PART_RASPIOS_ROOT=$(fdisk -l | tail -n 1 | awk '{print $1}')
+ PART_ODOO_ROOT=$(fdisk -l | tail -n 2 | awk 'NR==1 {print $1}')
+ PART_BOOT=$(fdisk -l | tail -n 3 | awk 'NR==1 {print $1}')
+ RASPIOS=$(echo *raspios*.img)
+ LOOP_RASPIOS=$(kpartx -avs "${RASPIOS}")
+ LOOP_RASPIOS_ROOT=$(echo "${LOOP_RASPIOS}" | tail -n 1 | awk '{print $3}')
+ LOOP_RASPIOS_ROOT="/dev/mapper/${LOOP_RASPIOS_ROOT}"
+ LOOP_BOOT=$(echo "${LOOP_RASPIOS}" | tail -n 2 | awk 'NR==1 {print $3}')
+ LOOP_BOOT="/dev/mapper/${LOOP_BOOT}"
+
+ mount -o remount,rw /
+ # copy raspios
+ dd if="${LOOP_RASPIOS_ROOT}" of="${PART_RASPIOS_ROOT}" bs=4M status=progress
+ e2fsck -fv "${PART_RASPIOS_ROOT}" # resize2fs requires clean fs
+
+ # Modify startup
+ mkdir -v raspios
+ mount -v "${PART_RASPIOS_ROOT}" raspios
+ resize2fs "${PART_RASPIOS_ROOT}"
+ chroot raspios/ /bin/bash -c "sudo apt-get -y update"
+ chroot raspios/ /bin/bash -c "sudo apt-get -y install kpartx"
+ PATH_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+ cp -v "${PATH_DIR}"/upgrade.sh raspios/home/pi/
+ NBR_LIGNE=$(sed -n -e '$=' raspios/etc/rc.local)
+ sed -ie "${NBR_LIGNE}"'i\. /home/pi/upgrade.sh; copy_iot' raspios/etc/rc.local
+ cp -v /etc/fstab raspios/etc/fstab
+ sed -ie "s/$(echo ${PART_ODOO_ROOT} | sed -e 's/\//\\\//g')/$(echo ${PART_RASPIOS_ROOT} | sed -e 's/\//\\\//g')/g" raspios/etc/fstab
+ mkdir raspios/home/pi/config
+ find /home/pi -maxdepth 1 -type f ! -name ".*" -exec cp {} raspios/home/pi/config/ \;
+
+ # download latest IoT Box image and check integrity
+ wget -c 'https://nightly.odoo.com/master/iotbox/iotbox-latest.zip' -O raspios/iotbox-latest.zip
+ wget -c 'https://nightly.odoo.com/master/iotbox/SHA1SUMS.txt' -O raspios/SHA1SUMS.txt
+ cd raspios/
+ CHECK=$(sha1sum -c --ignore-missing SHA1SUMS.txt)
+ cd ..
+
+ umount -v raspios
+ if [ "${CHECK}" != "iotbox-latest.zip: OK" ]
+ then
+ # Checksum is not correct so clean and reset self-flashing
+ rm start_upgrade
+ echo "Error_Iotbox_Download"
+ exit 0
+ fi
+
+ # copy boot
+ mkfs.ext4 -Fv "${PART_BOOT}" # format /boot file sytstem
+ e2fsck -fv "${PART_BOOT}" # clean /boot fs
+ dd if="${LOOP_BOOT}" of="${PART_BOOT}" bs=4M status=progress
+
+ # Modify boot file
+ mkdir -v boot
+ mount -v "${PART_BOOT}" boot
+ PART_IOT_BOOT_ID=$(grep -oP '(?<=root=).*(?=rootfstype)' boot/cmdline.txt)
+ sed -ie "s/$(echo ${PART_IOT_BOOT_ID} | sed -e 's/\//\\\//g')/$(echo ${PART_RASPIOS_ROOT} | sed -e 's/\//\\\//g')/g" boot/cmdline.txt
+ umount -v boot
+
+ kpartx -dv "${RASPIOS}"
+ rm -v "${RASPIOS}"
+
+ reboot
+}
+
+copy_iot () {
+ mount -o remount,rw /
+
+ PART_IOTBOX_ROOT=$(fdisk -l | tail -n 2 | awk 'NR==1 {print $1}')
+ PART_BOOT=$(fdisk -l | tail -n 3 | awk 'NR==1 {print $1}')
+
+ # unzip latest IoT Box image
+ unzip iotbox-latest.zip
+ rm -v iotbox-latest.zip
+ IOTBOX=$(echo *iotbox*.img)
+
+ # mapper IoTBox
+ LOOP_IOTBOX=$(kpartx -avs "${IOTBOX}")
+ LOOP_IOTBOX_ROOT=$(echo "${LOOP_IOTBOX}" | tail -n 1 | awk '{print $3}')
+ LOOP_IOTBOX_ROOT="/dev/mapper/${LOOP_IOTBOX_ROOT}"
+ LOOP_BOOT=$(echo "${LOOP_IOTBOX}" | tail -n 2 | awk 'NR==1 {print $3}')
+ LOOP_BOOT="/dev/mapper/${LOOP_BOOT}"
+
+ umount -v /boot
+ sleep 5
+
+ echo "----------------------------------"
+ echo "Flash in progress - Please wait..."
+ echo "----------------------------------"
+ # copy new IoT Box
+ dd if="${LOOP_IOTBOX_ROOT}" of="${PART_IOTBOX_ROOT}" bs=4M status=progress
+ # copy boot of new IoT Box
+ dd if="${LOOP_BOOT}" of="${PART_BOOT}" bs=4M status=progress
+
+ mount -v "${PART_BOOT}" /boot
+
+ # Modify boot file
+ PART_BOOT_ID=$(grep -oP '(?<=root=).*(?=rootfstype)' /boot/cmdline.txt)
+ sed -ie "s/$(echo ${PART_BOOT_ID} | sed -e 's/\//\\\//g')/$(echo ${PART_IOTBOX_ROOT} | sed -e 's/\//\\\//g')/g" /boot/cmdline.txt
+ sed -i 's| init=/usr/lib/raspi-config/init_resize.sh||' /boot/cmdline.txt
+
+ # Modify startup
+ mkdir -v odoo
+ mount -v "${PART_IOTBOX_ROOT}" odoo
+ cp -v /home/pi/upgrade.sh odoo/home/pi/
+ NBR_LIGNE=$(sed -n -e '$=' odoo/etc/rc.local)
+ sed -ie "${NBR_LIGNE}"'i\. /home/pi/upgrade.sh; clean_local' odoo/etc/rc.local
+ find /home/pi/config -maxdepth 1 -type f ! -name ".*" -exec cp {} odoo/home/pi/ \;
+
+ reboot
+}
+
+cleanup () {
+ # clean partitions
+ PART_RASPIOS_ROOT=$(fdisk -l | tail -n 1 | awk '{print $1}')
+ mkfs.ext4 -Fv "${PART_RASPIOS_ROOT}" # format file sytstem
+ wipefs -a "${PART_RASPIOS_ROOT}"
+
+ PARTITION=$(echo "${PART_RASPIOS_ROOT}" | sed 's/..$//')
+
+ (echo 'p'; # print
+ echo 'd'; # delete partition
+ echo '3'; # number 3
+ echo 'p'; # print
+ echo 'w') |fdisk "${PARTITION}" # write and quit
+
+ echo "end cleanup"
+}
+
+clean_local () {
+ mount -o remount,rw /
+ mount -o remount,rw /root_bypass_ramdisks/
+ cleanup
+ NBR_LIGNE=$(sed -n -e '$=' /root_bypass_ramdisks/etc/rc.local)
+ DEL_LIGNE=$((NBR_LIGNE - 1))
+ sed -i "${DEL_LIGNE}"'d' /root_bypass_ramdisks/etc/rc.local
+
+ rm /home/pi/upgrade.sh
+
+ mount -o remount,ro /
+ mount -o remount,ro /root_bypass_ramdisks/
+}
diff --git a/addons/point_of_sale/tools/posbox/configuration/wireless_ap.sh b/addons/point_of_sale/tools/posbox/configuration/wireless_ap.sh
new file mode 100755
index 00000000..00d9814f
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/configuration/wireless_ap.sh
@@ -0,0 +1,53 @@
+#!/usr/bin/env bash
+
+FORCE_HOST_AP="${1}"
+WIRED_IP=$(python3 -c "import netifaces as ni; print(ni.ifaddresses('eth0').get(ni.AF_INET) and ni.ifaddresses('eth0')[ni.AF_INET][0]['addr'] or '')")
+WIFI_NETWORK_FILE="/home/pi/wifi_network.txt"
+
+
+ifconfig wlan0 down
+ifconfig wlan0 up
+
+# wait for wlan0 to come up
+sleep 5
+
+# if there is no wired ip, attempt to start an AP through wireless interface
+if [ -z "${WIRED_IP}" ] ; then
+ logger -t posbox_wireless_ap "No wired IP"
+
+ if [ -f "${WIFI_NETWORK_FILE}" ] && [ -z "${FORCE_HOST_AP}" ] ; then
+ logger -t posbox_wireless_ap "Loading persistently saved setting"
+ /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/connect_to_wifi.sh &
+ else
+ logger -t posbox_wireless_ap "Starting AP"
+
+ SSID=$(grep -oP '(?<=ssid=).*' /etc/hostapd/hostapd.conf)
+
+ if [ "${SSID}" = "IoTBox" ]
+ then
+ # override SSID to get a unique SSID
+ MAC=$(ip link show wlan0 | tail -n 1 | awk '{print $2}' | sed 's/\://g')
+ NEWSSID="${SSID}-${MAC}"
+ sed -ie "s/$(echo ${SSID})/$(echo ${NEWSSID})/g" /etc/hostapd/hostapd.conf
+ fi
+
+ service hostapd restart
+
+ ip addr add 10.11.12.1/24 dev wlan0
+
+ service dnsmasq restart
+
+ service nginx stop
+ # We start nginx in another configuration than the default one with https
+ # as it needs to do redirect instead in case the IoT Box acts as an ap
+ nginx -c /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/nginx_ap.conf
+
+ service odoo restart
+ fi
+# wired
+else
+ killall nginx
+ service nginx restart
+ service dnsmasq stop
+ service odoo restart
+fi
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/X11/xorg.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/X11/xorg.conf
new file mode 100644
index 00000000..b525e583
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/X11/xorg.conf
@@ -0,0 +1,60 @@
+Section "Device"
+ Identifier "fbdev0"
+ Driver "fbdev"
+ Option "fbdev" "/dev/fb0"
+EndSection
+
+Section "Device"
+ Identifier "fbdev1"
+ Driver "fbdev"
+ Option "fbdev" "/dev/fb1"
+EndSection
+
+# Dummy device to use Xlib in KeyboardUSBDriver when no monitor is connected
+Section "Device"
+ Identifier "dummy"
+ Driver "dummy"
+EndSection
+
+Section "Monitor"
+ Identifier "Monitor0"
+EndSection
+
+Section "Monitor"
+ Identifier "Monitor1"
+EndSection
+
+Section "Monitor"
+ Identifier "DummyMonitor"
+EndSection
+
+Section "Screen"
+ Identifier "Screen0"
+ Monitor "Monitor0"
+ Device "fbdev0"
+ Subsection "Display"
+ EndSubSection
+EndSection
+
+Section "Screen"
+ Identifier "Screen1"
+ Monitor "Monitor1"
+ Device "fbdev1"
+ Subsection "Display"
+ EndSubSection
+EndSection
+
+Section "Screen"
+ Identifier "DummyScreen"
+ Monitor "DummyMonitor"
+ Device "dummy"
+ Subsection "Display"
+ EndSubSection
+EndSection
+
+Section "ServerLayout"
+ Identifier "Multihead"
+ Screen 0 "Screen0"
+ Screen 1 "Screen1" rightof "Screen0"
+ Screen 2 "DummyScreen" rightof "Screen1"
+EndSection
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/cron.daily/odoo b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/cron.daily/odoo
new file mode 100755
index 00000000..bba86a36
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/cron.daily/odoo
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+wget 'http://localhost:8069/hw_drivers/check_certificate' >/dev/null \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/cups/cups-files.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/cups/cups-files.conf
new file mode 100644
index 00000000..31864e16
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/cups/cups-files.conf
@@ -0,0 +1,93 @@
+#
+# File/directory/user/group configuration file for the CUPS scheduler.
+# See "man cups-files.conf" for a complete description of this file.
+#
+
+# List of events that are considered fatal errors for the scheduler...
+#FatalErrors config
+
+# Do we call fsync() after writing configuration or status files?
+#SyncOnClose Yes
+
+# Default user and group for filters/backends/helper programs; this cannot be
+# any user or group that resolves to ID 0 for security reasons...
+#User lp
+#Group lp
+
+# Administrator user group, used to match @SYSTEM in cupsd.conf policy rules...
+# This cannot contain the Group value for security reasons...
+SystemGroup lpadmin pi
+
+
+# User that is substituted for unauthenticated (remote) root accesses...
+#RemoteRoot remroot
+
+# Do we allow file: device URIs other than to /dev/null?
+#FileDevice No
+
+# Permissions for configuration and log files...
+#ConfigFilePerm 0640
+#LogFilePerm 00640
+
+# Location of the file logging all access to the scheduler; may be the name
+# "syslog". If not an absolute path, the value of ServerRoot is used as the
+# root directory. Also see the "AccessLogLevel" directive in cupsd.conf.
+AccessLog /var/log/cups/access_log
+
+# Location of cache files used by the scheduler...
+#CacheDir /var/cache/cups
+
+# Location of data files used by the scheduler...
+#DataDir /usr/share/cups
+
+# Location of the static web content served by the scheduler...
+#DocumentRoot /usr/share/cups/doc-root
+
+# Location of the file logging all messages produced by the scheduler and any
+# helper programs; may be the name "syslog". If not an absolute path, the value
+# of ServerRoot is used as the root directory. Also see the "LogLevel"
+# directive in cupsd.conf.
+ErrorLog /var/log/cups/error_log
+
+# Location of fonts used by older print filters...
+#FontPath /usr/share/cups/fonts
+
+# Location of LPD configuration
+#LPDConfigFile
+
+# Location of the file logging all pages printed by the scheduler and any
+# helper programs; may be the name "syslog". If not an absolute path, the value
+# of ServerRoot is used as the root directory. Also see the "PageLogFormat"
+# directive in cupsd.conf.
+PageLog /var/log/cups/page_log
+
+# Location of the file listing all of the local printers...
+#Printcap /run/cups/printcap
+
+# Format of the Printcap file...
+#PrintcapFormat bsd
+#PrintcapFormat plist
+#PrintcapFormat solaris
+
+# Location of all spool files...
+#RequestRoot /var/spool/cups
+
+# Location of helper programs...
+#ServerBin /usr/lib/cups
+
+# SSL/TLS keychain for the scheduler...
+#ServerKeychain ssl
+
+# Location of other configuration files...
+ServerRoot /root_bypass_ramdisks/etc/cups
+
+# Location of Samba configuration file...
+#SMBConfigFile
+
+# Location of scheduler state files...
+#StateDir /run/cups
+
+# Location of scheduler/helper temporary files. This directory is emptied on
+# scheduler startup and cannot be one of the standard (public) temporary
+# directory locations for security reasons...
+#TempDir /var/spool/cups/tmp
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/cups/cupsd.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/cups/cupsd.conf
new file mode 100644
index 00000000..14ca7120
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/cups/cupsd.conf
@@ -0,0 +1,186 @@
+#
+# Configuration file for the CUPS scheduler. See "man cupsd.conf" for a
+# complete description of this file.
+#
+
+# Log general information in error_log - change "warn" to "debug"
+# for troubleshooting...
+LogLevel warn
+PageLogFormat
+
+# Deactivate CUPS' internal logrotating, as we provide a better one, especially
+# LogLevel debug2 gets usable now
+MaxLogSize 0
+
+# Only listen for connections from the local machine.
+Listen 0.0.0.0:631
+Listen /run/cups/cups.sock
+
+# Show shared printers on the local network.
+Browsing On
+BrowseLocalProtocols dnssd
+
+# Local printers are not shared by default
+DefaultShared No
+
+# Default authentication type, when authentication is required...
+DefaultAuthType Basic
+
+# Web interface setting...
+WebInterface Yes
+
+# Default paper size depends on the printer
+DefaultPaperSize None
+
+# Restrict access to the server...
+<Location />
+ Order allow,deny
+ Allow all
+</Location>
+
+# Restrict access to the admin pages...
+<Location /admin>
+ Order allow,deny
+ Allow all
+</Location>
+
+# Restrict access to configuration files...
+<Location /admin/conf>
+ Order allow,deny
+ Allow all
+</Location>
+
+# Restrict access to log files...
+<Location /admin/log>
+ Order allow,deny
+ Allow all
+</Location>
+
+# Set the default printer/job policies...
+<Policy default>
+ # Job/subscription privacy...
+ JobPrivateAccess default
+ JobPrivateValues default
+ SubscriptionPrivateAccess default
+ SubscriptionPrivateValues default
+
+ # Job-related operations must be done by the owner or an administrator...
+ <Limit Create-Job Print-Job Print-URI Validate-Job>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ <Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job CUPS-Get-Document>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ # All administration operations require an administrator to authenticate...
+ <Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default CUPS-Get-Devices>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ # All printer operations require a printer operator to authenticate...
+ <Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After Cancel-Jobs CUPS-Accept-Jobs CUPS-Reject-Jobs>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ # Only the owner or an administrator can cancel or authenticate a job...
+ <Limit Cancel-Job CUPS-Authenticate-Job>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ <Limit All>
+ Order allow,deny
+ Allow all
+ </Limit>
+</Policy>
+
+# Set the authenticated printer/job policies...
+<Policy authenticated>
+ # Job/subscription privacy...
+ JobPrivateAccess default
+ JobPrivateValues default
+ SubscriptionPrivateAccess default
+ SubscriptionPrivateValues default
+
+ # Job-related operations must be done by the owner or an administrator...
+ <Limit Create-Job Print-Job Print-URI Validate-Job>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ <Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job CUPS-Get-Document>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ # All administration operations require an administrator to authenticate...
+ <Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ # All printer operations require a printer operator to authenticate...
+ <Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After Cancel-Jobs CUPS-Accept-Jobs CUPS-Reject-Jobs>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ # Only the owner or an administrator can cancel or authenticate a job...
+ <Limit Cancel-Job CUPS-Authenticate-Job>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ <Limit All>
+ Order allow,deny
+ Allow all
+ </Limit>
+</Policy>
+
+# Set the kerberized printer/job policies...
+<Policy kerberos>
+ # Job/subscription privacy...
+ JobPrivateAccess default
+ JobPrivateValues default
+ SubscriptionPrivateAccess default
+ SubscriptionPrivateValues default
+
+ # Job-related operations must be done by the owner or an administrator...
+ <Limit Create-Job Print-Job Print-URI Validate-Job>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ <Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job CUPS-Get-Document>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ # All administration operations require an administrator to authenticate...
+ <Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ # All printer operations require a printer operator to authenticate...
+ <Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After Cancel-Jobs CUPS-Accept-Jobs CUPS-Reject-Jobs>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ # Only the owner or an administrator can cancel or authenticate a job...
+ <Limit Cancel-Job CUPS-Authenticate-Job>
+ Order allow,deny
+ Allow all
+ </Limit>
+
+ <Limit All>
+ Order allow,deny
+ Allow all
+ </Limit>
+</Policy> \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/default/hostapd b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/default/hostapd
new file mode 100644
index 00000000..7e97ae99
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/default/hostapd
@@ -0,0 +1,20 @@
+# Defaults for hostapd initscript
+#
+# See /usr/share/doc/hostapd/README.Debian for information about alternative
+# methods of managing hostapd.
+#
+# Uncomment and set DAEMON_CONF to the absolute path of a hostapd configuration
+# file and hostapd will be started during system boot. An example configuration
+# file can be found at /usr/share/doc/hostapd/examples/hostapd.conf.gz
+#
+DAEMON_CONF="/etc/hostapd/hostapd.conf"
+
+# Additional daemon options to be appended to hostapd command:-
+# -d show more debug messages (-dd for even more)
+# -K include key data in debug messages
+# -t include timestamps in some debug messages
+#
+# Note that -B (daemon mode) and -P (pidfile) options are automatically
+# configured by the init.d script and must not be added to DAEMON_OPTS.
+#
+DAEMON_OPTS="-d"
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/default/ifplugd b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/default/ifplugd
new file mode 100644
index 00000000..cf433197
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/default/ifplugd
@@ -0,0 +1,17 @@
+# This file may be changed either manually or by running dpkg-reconfigure.
+#
+# N.B.: dpkg-reconfigure deletes everything from this file except for
+# the assignments to variables INTERFACES, HOTPLUG_INTERFACES, ARGS and
+# SUSPEND_ACTION. When run it uses the current values of those variables
+# as their default values, thus preserving the administrator's changes.
+#
+# This file is sourced by both the init script /etc/init.d/ifplugd and
+# the udev script /lib/udev/ifplugd.agent to give default values.
+# The init script starts ifplugd for all interfaces listed in
+# INTERFACES, and the udev script starts ifplugd for all interfaces
+# listed in HOTPLUG_INTERFACES. The special value all starts one
+# ifplugd for all interfaces being present.
+INTERFACES="eth0" # auto
+HOTPLUG_INTERFACES="eth0" # all
+ARGS="-q -f -u0 -d10 -w -I"
+SUSPEND_ACTION="stop"
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dhcp/dhcpd.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dhcp/dhcpd.conf
new file mode 100644
index 00000000..d13dbb9a
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dhcp/dhcpd.conf
@@ -0,0 +1,113 @@
+#
+# Sample configuration file for ISC dhcpd for Debian
+#
+#
+
+# The ddns-updates-style parameter controls whether or not the server will
+# attempt to do a DNS update when a lease is confirmed. We default to the
+# behavior of the version 2 packages ('none', since DHCP v2 didn't
+# have support for DDNS.)
+ddns-update-style none;
+
+# option definitions common to all supported networks...
+#option domain-name "example.org";
+#option domain-name-servers ns1.example.org, ns2.example.org;
+
+#default-lease-time 600;
+#max-lease-time 7200;
+
+# If this DHCP server is the official DHCP server for the local
+# network, the authoritative directive should be uncommented.
+#authoritative;
+
+# Use this to send dhcp log messages to a different log file (you also
+# have to hack syslog.conf to complete the redirection).
+# log-facility local7;
+
+# No service will be given on this subnet, but declaring it helps the
+# DHCP server to understand the network topology.
+
+#subnet 10.152.187.0 netmask 255.255.255.0 {
+#}
+
+# This is a very basic subnet declaration.
+
+#subnet 10.254.239.0 netmask 255.255.255.224 {
+# range 10.254.239.10 10.254.239.20;
+# option routers rtr-239-0-1.example.org, rtr-239-0-2.example.org;
+#}
+
+subnet 10.11.12.0 netmask 255.255.255.0 {
+ range 10.11.12.2 10.11.12.254;
+ option domain-name-servers 8.8.8.8, 208.67.222.222;
+ option routers 10.11.12.1;
+}
+
+# This declaration allows BOOTP clients to get dynamic addresses,
+# which we don't really recommend.
+
+#subnet 10.254.239.32 netmask 255.255.255.224 {
+# range dynamic-bootp 10.254.239.40 10.254.239.60;
+# option broadcast-address 10.254.239.31;
+# option routers rtr-239-32-1.example.org;
+#}
+
+# A slightly different configuration for an internal subnet.
+#subnet 10.5.5.0 netmask 255.255.255.224 {
+# range 10.5.5.26 10.5.5.30;
+# option domain-name-servers ns1.internal.example.org;
+# option domain-name "internal.example.org";
+# option routers 10.5.5.1;
+# option broadcast-address 10.5.5.31;
+# default-lease-time 600;
+# max-lease-time 7200;
+#}
+
+# Hosts which require special configuration options can be listed in
+# host statements. If no address is specified, the address will be
+# allocated dynamically (if possible), but the host-specific information
+# will still come from the host declaration.
+
+#host passacaglia {
+# hardware ethernet 0:0:c0:5d:bd:95;
+# filename "vmunix.passacaglia";
+# server-name "toccata.fugue.com";
+#}
+
+# Fixed IP addresses can also be specified for hosts. These addresses
+# should not also be listed as being available for dynamic assignment.
+# Hosts for which fixed IP addresses have been specified can boot using
+# BOOTP or DHCP. Hosts for which no fixed address is specified can only
+# be booted with DHCP, unless there is an address range on the subnet
+# to which a BOOTP client is connected which has the dynamic-bootp flag
+# set.
+#host fantasia {
+# hardware ethernet 08:00:07:26:c0:a5;
+# fixed-address fantasia.fugue.com;
+#}
+
+# You can declare a class of clients and then do address allocation
+# based on that. The example below shows a case where all clients
+# in a certain class get addresses on the 10.17.224/24 subnet, and all
+# other clients get addresses on the 10.0.29/24 subnet.
+
+#class "foo" {
+# match if substring (option vendor-class-identifier, 0, 4) = "SUNW";
+#}
+
+#shared-network 224-29 {
+# subnet 10.17.224.0 netmask 255.255.255.0 {
+# option routers rtr-224.example.org;
+# }
+# subnet 10.0.29.0 netmask 255.255.255.0 {
+# option routers rtr-29.example.org;
+# }
+# pool {
+# allow members of "foo";
+# range 10.17.224.10 10.17.224.250;
+# }
+# pool {
+# deny members of "foo";
+# range 10.0.29.10 10.0.29.230;
+# }
+#}
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dhcpcd.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dhcpcd.conf
new file mode 100644
index 00000000..7b693ddc
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dhcpcd.conf
@@ -0,0 +1,47 @@
+# A sample configuration for dhcpcd.
+# See dhcpcd.conf(5) for details.
+
+# Allow users of this group to interact with dhcpcd via the control socket.
+#controlgroup wheel
+
+# Inform the DHCP server of our hostname for DDNS.
+hostname
+
+# Use the hardware address of the interface for the Client ID.
+#clientid
+# or
+# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361.
+clientid
+
+# Persist interface configuration when dhcpcd exits.
+persistent
+
+# Rapid commit support.
+# Safe to enable by default because it requires the equivalent option set
+# on the server to actually work.
+option rapid_commit
+
+# A list of options to request from the DHCP server.
+option domain_name_servers, domain_name, domain_search, host_name
+option classless_static_routes
+# Most distributions have NTP support.
+option ntp_servers
+# Respect the network MTU.
+# Some interface drivers reset when changing the MTU so disabled by default.
+#option interface_mtu
+
+# A ServerID is required by RFC2131.
+require dhcp_server_identifier
+
+# Generate Stable Private IPv6 Addresses instead of hardware based ones
+slaac private
+
+# A hook script is provided to lookup the hostname if not set by the DHCP
+# server, but it should not be run by default.
+nohook lookup-hostname
+# stretch: we do not want to start wpa_supplicant as our script starts wpa_supplicant itself
+nohook wpa_supplicant
+
+# dhcpcd will assign zeroconf 169.254.*.* addresses when
+# it can't connect, which we don't want
+noipv4ll
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dnsmasq.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dnsmasq.conf
new file mode 100644
index 00000000..3d0d0531
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dnsmasq.conf
@@ -0,0 +1,669 @@
+# Configuration file for dnsmasq.
+#
+# Format is one option per line, legal options are the same
+# as the long options legal on the command line. See
+# "/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details.
+
+# Listen on this specific port instead of the standard DNS port
+# (53). Setting this to zero completely disables DNS function,
+# leaving only DHCP and/or TFTP.
+#port=5353
+
+# The following two options make you a better netizen, since they
+# tell dnsmasq to filter out queries which the public DNS cannot
+# answer, and which load the servers (especially the root servers)
+# unnecessarily. If you have a dial-on-demand link they also stop
+# these requests from bringing up the link unnecessarily.
+
+# Never forward plain names (without a dot or domain part)
+#domain-needed
+# Never forward addresses in the non-routed address spaces.
+bogus-priv
+
+# Uncomment these to enable DNSSEC validation and caching:
+# (Requires dnsmasq to be built with DNSSEC option.)
+#conf-file=%%PREFIX%%/share/dnsmasq/trust-anchors.conf
+#dnssec
+
+# Replies which are not DNSSEC signed may be legitimate, because the domain
+# is unsigned, or may be forgeries. Setting this option tells dnsmasq to
+# check that an unsigned reply is OK, by finding a secure proof that a DS
+# record somewhere between the root and the domain does not exist.
+# The cost of setting this is that even queries in unsigned domains will need
+# one or more extra DNS queries to verify.
+#dnssec-check-unsigned
+
+# Uncomment this to filter useless windows-originated DNS requests
+# which can trigger dial-on-demand links needlessly.
+# Note that (amongst other things) this blocks all SRV requests,
+# so don't use it if you use eg Kerberos, SIP, XMMP or Google-talk.
+# This option only affects forwarding, SRV records originating for
+# dnsmasq (via srv-host= lines) are not suppressed by it.
+#filterwin2k
+
+# Change this line if you want dns to get its upstream servers from
+# somewhere other that /etc/resolv.conf
+#resolv-file=
+
+# By default, dnsmasq will send queries to any of the upstream
+# servers it knows about and tries to favour servers to are known
+# to be up. Uncommenting this forces dnsmasq to try each query
+# with each server strictly in the order they appear in
+# /etc/resolv.conf
+#strict-order
+
+# If you don't want dnsmasq to read /etc/resolv.conf or any other
+# file, getting its servers from this file instead (see below), then
+# uncomment this.
+#no-resolv
+
+# If you don't want dnsmasq to poll /etc/resolv.conf or other resolv
+# files for changes and re-read them then uncomment this.
+#no-poll
+
+# Add other name servers here, with domain specs if they are for
+# non-public domains.
+server=/localnet/10.11.12.1
+
+# Example of routing PTR queries to nameservers: this will send all
+# address->name queries for 192.168.3/24 to nameserver 10.1.2.3
+#server=/3.168.192.in-addr.arpa/10.1.2.3
+
+# Add local-only domains here, queries in these domains are answered
+# from /etc/hosts or DHCP only.
+local=/localnet/
+
+# Add domains which you want to force to an IP address here.
+# The example below send any host in double-click.net to a local
+# web-server.
+#address=/double-click.net/127.0.0.1
+address=/#/10.11.12.1
+
+# --address (and --server) work with IPv6 addresses too.
+#address=/www.thekelleys.org.uk/fe80::20d:60ff:fe36:f83
+
+# Add the IPs of all queries to yahoo.com, google.com, and their
+# subdomains to the vpn and search ipsets:
+#ipset=/yahoo.com/google.com/vpn,search
+
+# You can control how dnsmasq talks to a server: this forces
+# queries to 10.1.2.3 to be routed via eth1
+# server=10.1.2.3@eth1
+
+# and this sets the source (ie local) address used to talk to
+# 10.1.2.3 to 192.168.1.1 port 55 (there must be a interface with that
+# IP on the machine, obviously).
+# server=10.1.2.3@192.168.1.1#55
+
+# If you want dnsmasq to change uid and gid to something other
+# than the default, edit the following lines.
+#user=
+#group=
+
+# If you want dnsmasq to listen for DHCP and DNS requests only on
+# specified interfaces (and the loopback) give the name of the
+# interface (eg eth0) here.
+# Repeat the line for more than one interface.
+interface=wlan0
+# Or you can specify which interface _not_ to listen on
+#except-interface=
+# Or which to listen on by address (remember to include 127.0.0.1 if
+# you use this.)
+#listen-address=
+# If you want dnsmasq to provide only DNS service on an interface,
+# configure it as shown above, and then use the following line to
+# disable DHCP and TFTP on it.
+#no-dhcp-interface=
+
+# On systems which support it, dnsmasq binds the wildcard address,
+# even when it is listening on only some interfaces. It then discards
+# requests that it shouldn't reply to. This has the advantage of
+# working even when interfaces come and go and change address. If you
+# want dnsmasq to really bind only the interfaces it is listening on,
+# uncomment this option. About the only time you may need this is when
+# running another nameserver on the same machine.
+#bind-interfaces
+
+# If you don't want dnsmasq to read /etc/hosts, uncomment the
+# following line.
+#no-hosts
+# or if you want it to read another file, as well as /etc/hosts, use
+# this.
+#addn-hosts=/etc/banner_add_hosts
+
+# Set this (and domain: see below) if you want to have a domain
+# automatically added to simple names in a hosts-file.
+#expand-hosts
+
+# Set the domain for dnsmasq. this is optional, but if it is set, it
+# does the following things.
+# 1) Allows DHCP hosts to have fully qualified domain names, as long
+# as the domain part matches this setting.
+# 2) Sets the "domain" DHCP option thereby potentially setting the
+# domain of all systems configured by DHCP
+# 3) Provides the domain part for "expand-hosts"
+#domain=thekelleys.org.uk
+
+# Set a different domain for a particular subnet
+#domain=wireless.thekelleys.org.uk,192.168.2.0/24
+
+# Same idea, but range rather then subnet
+#domain=reserved.thekelleys.org.uk,192.68.3.100,192.168.3.200
+
+# Uncomment this to enable the integrated DHCP server, you need
+# to supply the range of addresses available for lease and optionally
+# a lease time. If you have more than one network, you will need to
+# repeat this for each network on which you want to supply DHCP
+# service.
+domain=localnet
+dhcp-range=10.11.12.2,10.11.12.254
+
+# This is an example of a DHCP range where the netmask is given. This
+# is needed for networks we reach the dnsmasq DHCP server via a relay
+# agent. If you don't know what a DHCP relay agent is, you probably
+# don't need to worry about this.
+#dhcp-range=192.168.0.50,192.168.0.150,255.255.255.0,12h
+
+# This is an example of a DHCP range which sets a tag, so that
+# some DHCP options may be set only for this network.
+#dhcp-range=set:red,192.168.0.50,192.168.0.150
+
+# Use this DHCP range only when the tag "green" is set.
+#dhcp-range=tag:green,192.168.0.50,192.168.0.150,12h
+
+# Specify a subnet which can't be used for dynamic address allocation,
+# is available for hosts with matching --dhcp-host lines. Note that
+# dhcp-host declarations will be ignored unless there is a dhcp-range
+# of some type for the subnet in question.
+# In this case the netmask is implied (it comes from the network
+# configuration on the machine running dnsmasq) it is possible to give
+# an explicit netmask instead.
+#dhcp-range=192.168.0.0,static
+
+# Enable DHCPv6. Note that the prefix-length does not need to be specified
+# and defaults to 64 if missing/
+#dhcp-range=1234::2, 1234::500, 64, 12h
+
+# Do Router Advertisements, BUT NOT DHCP for this subnet.
+#dhcp-range=1234::, ra-only
+
+# Do Router Advertisements, BUT NOT DHCP for this subnet, also try and
+# add names to the DNS for the IPv6 address of SLAAC-configured dual-stack
+# hosts. Use the DHCPv4 lease to derive the name, network segment and
+# MAC address and assume that the host will also have an
+# IPv6 address calculated using the SLAAC algorithm.
+#dhcp-range=1234::, ra-names
+
+# Do Router Advertisements, BUT NOT DHCP for this subnet.
+# Set the lifetime to 46 hours. (Note: minimum lifetime is 2 hours.)
+#dhcp-range=1234::, ra-only, 48h
+
+# Do DHCP and Router Advertisements for this subnet. Set the A bit in the RA
+# so that clients can use SLAAC addresses as well as DHCP ones.
+#dhcp-range=1234::2, 1234::500, slaac
+
+# Do Router Advertisements and stateless DHCP for this subnet. Clients will
+# not get addresses from DHCP, but they will get other configuration information.
+# They will use SLAAC for addresses.
+#dhcp-range=1234::, ra-stateless
+
+# Do stateless DHCP, SLAAC, and generate DNS names for SLAAC addresses
+# from DHCPv4 leases.
+#dhcp-range=1234::, ra-stateless, ra-names
+
+# Do router advertisements for all subnets where we're doing DHCPv6
+# Unless overridden by ra-stateless, ra-names, et al, the router
+# advertisements will have the M and O bits set, so that the clients
+# get addresses and configuration from DHCPv6, and the A bit reset, so the
+# clients don't use SLAAC addresses.
+#enable-ra
+
+# Supply parameters for specified hosts using DHCP. There are lots
+# of valid alternatives, so we will give examples of each. Note that
+# IP addresses DO NOT have to be in the range given above, they just
+# need to be on the same network. The order of the parameters in these
+# do not matter, it's permissible to give name, address and MAC in any
+# order.
+
+# Always allocate the host with Ethernet address 11:22:33:44:55:66
+# The IP address 192.168.0.60
+#dhcp-host=11:22:33:44:55:66,192.168.0.60
+
+# Always set the name of the host with hardware address
+# 11:22:33:44:55:66 to be "fred"
+#dhcp-host=11:22:33:44:55:66,fred
+
+# Always give the host with Ethernet address 11:22:33:44:55:66
+# the name fred and IP address 192.168.0.60 and lease time 45 minutes
+#dhcp-host=11:22:33:44:55:66,fred,192.168.0.60,45m
+
+# Give a host with Ethernet address 11:22:33:44:55:66 or
+# 12:34:56:78:90:12 the IP address 192.168.0.60. Dnsmasq will assume
+# that these two Ethernet interfaces will never be in use at the same
+# time, and give the IP address to the second, even if it is already
+# in use by the first. Useful for laptops with wired and wireless
+# addresses.
+#dhcp-host=11:22:33:44:55:66,12:34:56:78:90:12,192.168.0.60
+
+# Give the machine which says its name is "bert" IP address
+# 192.168.0.70 and an infinite lease
+#dhcp-host=bert,192.168.0.70,infinite
+
+# Always give the host with client identifier 01:02:02:04
+# the IP address 192.168.0.60
+#dhcp-host=id:01:02:02:04,192.168.0.60
+
+# Always give the InfiniBand interface with hardware address
+# 80:00:00:48:fe:80:00:00:00:00:00:00:f4:52:14:03:00:28:05:81 the
+# ip address 192.168.0.61. The client id is derived from the prefix
+# ff:00:00:00:00:00:02:00:00:02:c9:00 and the last 8 pairs of
+# hex digits of the hardware address.
+#dhcp-host=id:ff:00:00:00:00:00:02:00:00:02:c9:00:f4:52:14:03:00:28:05:81,192.168.0.61
+
+# Always give the host with client identifier "marjorie"
+# the IP address 192.168.0.60
+#dhcp-host=id:marjorie,192.168.0.60
+
+# Enable the address given for "judge" in /etc/hosts
+# to be given to a machine presenting the name "judge" when
+# it asks for a DHCP lease.
+#dhcp-host=judge
+
+# Never offer DHCP service to a machine whose Ethernet
+# address is 11:22:33:44:55:66
+#dhcp-host=11:22:33:44:55:66,ignore
+
+# Ignore any client-id presented by the machine with Ethernet
+# address 11:22:33:44:55:66. This is useful to prevent a machine
+# being treated differently when running under different OS's or
+# between PXE boot and OS boot.
+#dhcp-host=11:22:33:44:55:66,id:*
+
+# Send extra options which are tagged as "red" to
+# the machine with Ethernet address 11:22:33:44:55:66
+#dhcp-host=11:22:33:44:55:66,set:red
+
+# Send extra options which are tagged as "red" to
+# any machine with Ethernet address starting 11:22:33:
+#dhcp-host=11:22:33:*:*:*,set:red
+
+# Give a fixed IPv6 address and name to client with
+# DUID 00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2
+# Note the MAC addresses CANNOT be used to identify DHCPv6 clients.
+# Note also the they [] around the IPv6 address are obligatory.
+#dhcp-host=id:00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2, fred, [1234::5]
+
+# Ignore any clients which are not specified in dhcp-host lines
+# or /etc/ethers. Equivalent to ISC "deny unknown-clients".
+# This relies on the special "known" tag which is set when
+# a host is matched.
+#dhcp-ignore=tag:!known
+
+# Send extra options which are tagged as "red" to any machine whose
+# DHCP vendorclass string includes the substring "Linux"
+#dhcp-vendorclass=set:red,Linux
+
+# Send extra options which are tagged as "red" to any machine one
+# of whose DHCP userclass strings includes the substring "accounts"
+#dhcp-userclass=set:red,accounts
+
+# Send extra options which are tagged as "red" to any machine whose
+# MAC address matches the pattern.
+#dhcp-mac=set:red,00:60:8C:*:*:*
+
+# If this line is uncommented, dnsmasq will read /etc/ethers and act
+# on the ethernet-address/IP pairs found there just as if they had
+# been given as --dhcp-host options. Useful if you keep
+# MAC-address/host mappings there for other purposes.
+#read-ethers
+
+# Send options to hosts which ask for a DHCP lease.
+# See RFC 2132 for details of available options.
+# Common options can be given to dnsmasq by name:
+# run "dnsmasq --help dhcp" to get a list.
+# Note that all the common settings, such as netmask and
+# broadcast address, DNS server and default route, are given
+# sane defaults by dnsmasq. You very likely will not need
+# any dhcp-options. If you use Windows clients and Samba, there
+# are some options which are recommended, they are detailed at the
+# end of this section.
+
+# Override the default route supplied by dnsmasq, which assumes the
+# router is the same machine as the one running dnsmasq.
+#dhcp-option=3,1.2.3.4
+dhcp-option=3,10.11.12.1
+dhcp-option=6,10.11.12.1
+
+# Do the same thing, but using the option name
+#dhcp-option=option:router,1.2.3.4
+
+# Override the default route supplied by dnsmasq and send no default
+# route at all. Note that this only works for the options sent by
+# default (1, 3, 6, 12, 28) the same line will send a zero-length option
+# for all other option numbers.
+#dhcp-option=3
+
+# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5
+#dhcp-option=option:ntp-server,192.168.0.4,10.10.0.5
+
+# Send DHCPv6 option. Note [] around IPv6 addresses.
+#dhcp-option=option6:dns-server,[1234::77],[1234::88]
+
+# Send DHCPv6 option for namservers as the machine running
+# dnsmasq and another.
+#dhcp-option=option6:dns-server,[::],[1234::88]
+
+# Ask client to poll for option changes every six hours. (RFC4242)
+#dhcp-option=option6:information-refresh-time,6h
+
+# Set option 58 client renewal time (T1). Defaults to half of the
+# lease time if not specified. (RFC2132)
+#dhcp-option=option:T1:1m
+
+# Set option 59 rebinding time (T2). Defaults to 7/8 of the
+# lease time if not specified. (RFC2132)
+#dhcp-option=option:T2:2m
+
+# Set the NTP time server address to be the same machine as
+# is running dnsmasq
+#dhcp-option=42,0.0.0.0
+
+# Set the NIS domain name to "welly"
+#dhcp-option=40,welly
+
+# Set the default time-to-live to 50
+#dhcp-option=23,50
+
+# Set the "all subnets are local" flag
+#dhcp-option=27,1
+
+# Send the etherboot magic flag and then etherboot options (a string).
+#dhcp-option=128,e4:45:74:68:00:00
+#dhcp-option=129,NIC=eepro100
+
+# Specify an option which will only be sent to the "red" network
+# (see dhcp-range for the declaration of the "red" network)
+# Note that the tag: part must precede the option: part.
+#dhcp-option = tag:red, option:ntp-server, 192.168.1.1
+
+# The following DHCP options set up dnsmasq in the same way as is specified
+# for the ISC dhcpcd in
+# http://www.samba.org/samba/ftp/docs/textdocs/DHCP-Server-Configuration.txt
+# adapted for a typical dnsmasq installation where the host running
+# dnsmasq is also the host running samba.
+# you may want to uncomment some or all of them if you use
+# Windows clients and Samba.
+#dhcp-option=19,0 # option ip-forwarding off
+#dhcp-option=44,0.0.0.0 # set netbios-over-TCP/IP nameserver(s) aka WINS server(s)
+#dhcp-option=45,0.0.0.0 # netbios datagram distribution server
+#dhcp-option=46,8 # netbios node type
+
+# Send an empty WPAD option. This may be REQUIRED to get windows 7 to behave.
+#dhcp-option=252,"\n"
+
+# Send RFC-3397 DNS domain search DHCP option. WARNING: Your DHCP client
+# probably doesn't support this......
+#dhcp-option=option:domain-search,eng.apple.com,marketing.apple.com
+
+# Send RFC-3442 classless static routes (note the netmask encoding)
+#dhcp-option=121,192.168.1.0/24,1.2.3.4,10.0.0.0/8,5.6.7.8
+
+# Send vendor-class specific options encapsulated in DHCP option 43.
+# The meaning of the options is defined by the vendor-class so
+# options are sent only when the client supplied vendor class
+# matches the class given here. (A substring match is OK, so "MSFT"
+# matches "MSFT" and "MSFT 5.0"). This example sets the
+# mtftp address to 0.0.0.0 for PXEClients.
+#dhcp-option=vendor:PXEClient,1,0.0.0.0
+
+# Send microsoft-specific option to tell windows to release the DHCP lease
+# when it shuts down. Note the "i" flag, to tell dnsmasq to send the
+# value as a four-byte integer - that's what microsoft wants. See
+# http://technet2.microsoft.com/WindowsServer/en/library/a70f1bb7-d2d4-49f0-96d6-4b7414ecfaae1033.mspx?mfr=true
+#dhcp-option=vendor:MSFT,2,1i
+
+# Send the Encapsulated-vendor-class ID needed by some configurations of
+# Etherboot to allow is to recognise the DHCP server.
+#dhcp-option=vendor:Etherboot,60,"Etherboot"
+
+# Send options to PXELinux. Note that we need to send the options even
+# though they don't appear in the parameter request list, so we need
+# to use dhcp-option-force here.
+# See http://syslinux.zytor.com/pxe.php#special for details.
+# Magic number - needed before anything else is recognised
+#dhcp-option-force=208,f1:00:74:7e
+# Configuration file name
+#dhcp-option-force=209,configs/common
+# Path prefix
+#dhcp-option-force=210,/tftpboot/pxelinux/files/
+# Reboot time. (Note 'i' to send 32-bit value)
+#dhcp-option-force=211,30i
+
+# Set the boot filename for netboot/PXE. You will only need
+# this is you want to boot machines over the network and you will need
+# a TFTP server; either dnsmasq's built in TFTP server or an
+# external one. (See below for how to enable the TFTP server.)
+#dhcp-boot=pxelinux.0
+
+# The same as above, but use custom tftp-server instead machine running dnsmasq
+#dhcp-boot=pxelinux,server.name,192.168.1.100
+
+# Boot for Etherboot gPXE. The idea is to send two different
+# filenames, the first loads gPXE, and the second tells gPXE what to
+# load. The dhcp-match sets the gpxe tag for requests from gPXE.
+#dhcp-match=set:gpxe,175 # gPXE sends a 175 option.
+#dhcp-boot=tag:!gpxe,undionly.kpxe
+#dhcp-boot=mybootimage
+
+# Encapsulated options for Etherboot gPXE. All the options are
+# encapsulated within option 175
+#dhcp-option=encap:175, 1, 5b # priority code
+#dhcp-option=encap:175, 176, 1b # no-proxydhcp
+#dhcp-option=encap:175, 177, string # bus-id
+#dhcp-option=encap:175, 189, 1b # BIOS drive code
+#dhcp-option=encap:175, 190, user # iSCSI username
+#dhcp-option=encap:175, 191, pass # iSCSI password
+
+# Test for the architecture of a netboot client. PXE clients are
+# supposed to send their architecture as option 93. (See RFC 4578)
+#dhcp-match=peecees, option:client-arch, 0 #x86-32
+#dhcp-match=itanics, option:client-arch, 2 #IA64
+#dhcp-match=hammers, option:client-arch, 6 #x86-64
+#dhcp-match=mactels, option:client-arch, 7 #EFI x86-64
+
+# Do real PXE, rather than just booting a single file, this is an
+# alternative to dhcp-boot.
+#pxe-prompt="What system shall I netboot?"
+# or with timeout before first available action is taken:
+#pxe-prompt="Press F8 for menu.", 60
+
+# Available boot services. for PXE.
+#pxe-service=x86PC, "Boot from local disk"
+
+# Loads <tftp-root>/pxelinux.0 from dnsmasq TFTP server.
+#pxe-service=x86PC, "Install Linux", pxelinux
+
+# Loads <tftp-root>/pxelinux.0 from TFTP server at 1.2.3.4.
+# Beware this fails on old PXE ROMS.
+#pxe-service=x86PC, "Install Linux", pxelinux, 1.2.3.4
+
+# Use bootserver on network, found my multicast or broadcast.
+#pxe-service=x86PC, "Install windows from RIS server", 1
+
+# Use bootserver at a known IP address.
+#pxe-service=x86PC, "Install windows from RIS server", 1, 1.2.3.4
+
+# If you have multicast-FTP available,
+# information for that can be passed in a similar way using options 1
+# to 5. See page 19 of
+# http://download.intel.com/design/archives/wfm/downloads/pxespec.pdf
+
+
+# Enable dnsmasq's built-in TFTP server
+#enable-tftp
+
+# Set the root directory for files available via FTP.
+#tftp-root=/var/ftpd
+
+# Do not abort if the tftp-root is unavailable
+#tftp-no-fail
+
+# Make the TFTP server more secure: with this set, only files owned by
+# the user dnsmasq is running as will be send over the net.
+#tftp-secure
+
+# This option stops dnsmasq from negotiating a larger blocksize for TFTP
+# transfers. It will slow things down, but may rescue some broken TFTP
+# clients.
+#tftp-no-blocksize
+
+# Set the boot file name only when the "red" tag is set.
+#dhcp-boot=tag:red,pxelinux.red-net
+
+# An example of dhcp-boot with an external TFTP server: the name and IP
+# address of the server are given after the filename.
+# Can fail with old PXE ROMS. Overridden by --pxe-service.
+#dhcp-boot=/var/ftpd/pxelinux.0,boothost,192.168.0.3
+
+# If there are multiple external tftp servers having a same name
+# (using /etc/hosts) then that name can be specified as the
+# tftp_servername (the third option to dhcp-boot) and in that
+# case dnsmasq resolves this name and returns the resultant IP
+# addresses in round robin fashion. This facility can be used to
+# load balance the tftp load among a set of servers.
+#dhcp-boot=/var/ftpd/pxelinux.0,boothost,tftp_server_name
+
+# Set the limit on DHCP leases, the default is 150
+#dhcp-lease-max=150
+
+# The DHCP server needs somewhere on disk to keep its lease database.
+# This defaults to a sane location, but if you want to change it, use
+# the line below.
+#dhcp-leasefile=/var/lib/misc/dnsmasq.leases
+
+# Set the DHCP server to authoritative mode. In this mode it will barge in
+# and take over the lease for any client which broadcasts on the network,
+# whether it has a record of the lease or not. This avoids long timeouts
+# when a machine wakes up on a new network. DO NOT enable this if there's
+# the slightest chance that you might end up accidentally configuring a DHCP
+# server for your campus/company accidentally. The ISC server uses
+# the same option, and this URL provides more information:
+# http://www.isc.org/files/auth.html
+dhcp-authoritative
+
+# Run an executable when a DHCP lease is created or destroyed.
+# The arguments sent to the script are "add" or "del",
+# then the MAC address, the IP address and finally the hostname
+# if there is one.
+#dhcp-script=/bin/echo
+
+# Set the cachesize here.
+#cache-size=150
+
+# If you want to disable negative caching, uncomment this.
+#no-negcache
+
+# Normally responses which come from /etc/hosts and the DHCP lease
+# file have Time-To-Live set as zero, which conventionally means
+# do not cache further. If you are happy to trade lower load on the
+# server for potentially stale date, you can set a time-to-live (in
+# seconds) here.
+#local-ttl=
+
+# If you want dnsmasq to detect attempts by Verisign to send queries
+# to unregistered .com and .net hosts to its sitefinder service and
+# have dnsmasq instead return the correct NXDOMAIN response, uncomment
+# this line. You can add similar lines to do the same for other
+# registries which have implemented wildcard A records.
+#bogus-nxdomain=64.94.110.11
+
+# If you want to fix up DNS results from upstream servers, use the
+# alias option. This only works for IPv4.
+# This alias makes a result of 1.2.3.4 appear as 5.6.7.8
+#alias=1.2.3.4,5.6.7.8
+# and this maps 1.2.3.x to 5.6.7.x
+#alias=1.2.3.0,5.6.7.0,255.255.255.0
+# and this maps 192.168.0.10->192.168.0.40 to 10.0.0.10->10.0.0.40
+#alias=192.168.0.10-192.168.0.40,10.0.0.0,255.255.255.0
+
+# Change these lines if you want dnsmasq to serve MX records.
+
+# Return an MX record named "maildomain.com" with target
+# servermachine.com and preference 50
+#mx-host=maildomain.com,servermachine.com,50
+
+# Set the default target for MX records created using the localmx option.
+#mx-target=servermachine.com
+
+# Return an MX record pointing to the mx-target for all local
+# machines.
+#localmx
+
+# Return an MX record pointing to itself for all local machines.
+#selfmx
+
+# Change the following lines if you want dnsmasq to serve SRV
+# records. These are useful if you want to serve ldap requests for
+# Active Directory and other windows-originated DNS requests.
+# See RFC 2782.
+# You may add multiple srv-host lines.
+# The fields are <name>,<target>,<port>,<priority>,<weight>
+# If the domain part if missing from the name (so that is just has the
+# service and protocol sections) then the domain given by the domain=
+# config option is used. (Note that expand-hosts does not need to be
+# set for this to work.)
+
+# A SRV record sending LDAP for the example.com domain to
+# ldapserver.example.com port 389
+#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389
+
+# A SRV record sending LDAP for the example.com domain to
+# ldapserver.example.com port 389 (using domain=)
+#srv-host=_ldap._tcp,ldapserver.example.com,389
+
+# Two SRV records for LDAP, each with different priorities
+#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,1
+#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,2
+
+# A SRV record indicating that there is no LDAP server for the domain
+# example.com
+#srv-host=_ldap._tcp.example.com
+
+# The following line shows how to make dnsmasq serve an arbitrary PTR
+# record. This is useful for DNS-SD. (Note that the
+# domain-name expansion done for SRV records _does_not
+# occur for PTR records.)
+#ptr-record=_http._tcp.dns-sd-services,"New Employee Page._http._tcp.dns-sd-services"
+
+# Change the following lines to enable dnsmasq to serve TXT records.
+# These are used for things like SPF and zeroconf. (Note that the
+# domain-name expansion done for SRV records _does_not
+# occur for TXT records.)
+
+#Example SPF.
+#txt-record=example.com,"v=spf1 a -all"
+
+#Example zeroconf
+#txt-record=_http._tcp.example.com,name=value,paper=A4
+
+# Provide an alias for a "local" DNS name. Note that this _only_ works
+# for targets which are names from DHCP or /etc/hosts. Give host
+# "bert" another name, bertrand
+#cname=bertand,bert
+
+# For debugging purposes, log each DNS query as it passes through
+# dnsmasq.
+#log-queries
+
+# Log lots of extra information about DHCP transactions.
+#log-dhcp
+
+# Include another lot of configuration options.
+#conf-file=/etc/dnsmasq.more.conf
+#conf-dir=/etc/dnsmasq.d
+
+# Include all the files in a directory except those ending in .bak
+#conf-dir=/etc/dnsmasq.d,.bak
+
+# Include all files in a directory which end in .conf
+#conf-dir=/etc/dnsmasq.d/,*.conf \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/fstab b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/fstab
new file mode 100644
index 00000000..28898fc8
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/fstab
@@ -0,0 +1,4 @@
+proc /proc proc defaults 0 0
+/dev/mmcblk0p1 /boot vfat defaults 0 2
+/dev/mmcblk0p2 / ext4 defaults,noatime,ro 0 1
+# a swapfile is not a swap partition, so no using swapon|off from here on, use dphys-swapfile swap[on|off] for that
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/hostapd/hostapd.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/hostapd/hostapd.conf
new file mode 100644
index 00000000..953be3c8
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/hostapd/hostapd.conf
@@ -0,0 +1,3 @@
+interface=wlan0
+ssid=IoTBox
+channel=1
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ld.so.preload b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ld.so.preload
new file mode 100644
index 00000000..457060ea
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ld.so.preload
@@ -0,0 +1 @@
+/usr/lib/arm-linux-gnueabihf/libarmmem-v8l.so
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf
new file mode 100644
index 00000000..7b487b33
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf
@@ -0,0 +1,8 @@
+
+[LightDM]
+user-authority-in-system-dir=true
+
+[SeatDefaults]
+xserver-command=/usr/bin/X -s 0 -layout Multihead dpms -nolisten tcp
+greeter-hide-users=false
+autologin-user=pi
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/network/interfaces b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/network/interfaces
new file mode 100644
index 00000000..95b6f075
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/network/interfaces
@@ -0,0 +1,3 @@
+# needed for postgresql
+auto lo
+iface lo inet loopback \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/nginx/sites-enabled/default b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/nginx/sites-enabled/default
new file mode 100644
index 00000000..c421a186
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/nginx/sites-enabled/default
@@ -0,0 +1,92 @@
+##
+# You should look at the following URL's in order to grasp a solid understanding
+# of Nginx configuration files in order to fully unleash the power of Nginx.
+# http://wiki.nginx.org/Pitfalls
+# http://wiki.nginx.org/QuickStart
+# http://wiki.nginx.org/Configuration
+#
+# Generally, you will want to move this file somewhere, and start with a clean
+# file but keep this around for reference. Or just disable in sites-enabled.
+#
+# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
+##
+
+# Default server configuration
+#
+server {
+ listen 443 ssl http2 default_server;
+ listen [::]:443 ssl http2 default_server;
+
+ server_name localhost;
+ ssl_certificate /etc/ssl/certs/nginx-cert.crt;
+ ssl_certificate_key /etc/ssl/private/nginx-cert.key;
+ ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
+ ssl_ciphers HIGH:!aNULL:!MD5;
+
+ location / {
+ proxy_read_timeout 600s;
+ proxy_pass http://127.0.0.1:8069;
+ }
+
+
+ # SSL configuration
+ #
+ # listen 443 ssl default_server;
+ # listen [::]:443 ssl default_server;
+ #
+ # Note: You should disable gzip for SSL traffic.
+ # See: https://bugs.debian.org/773332
+ #
+ # Read up on ssl_ciphers to ensure a secure configuration.
+ # See: https://bugs.debian.org/765782
+ #
+ # Self signed certs generated by the ssl-cert package
+ # Don't use them in a production server!
+ #
+ # include snippets/snakeoil.conf;
+
+ #root /var/www/html;
+
+ # Add index.php to the list if you are using PHP
+ #index index.html index.htm index.nginx-debian.html;
+
+ #server_name _;
+
+ # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
+ #
+ #location ~ \.php$ {
+ # include snippets/fastcgi-php.conf;
+ #
+ # # With php7.0-cgi alone:
+ # fastcgi_pass 127.0.0.1:9000;
+ # # With php7.0-fpm:
+ # fastcgi_pass unix:/run/php/php7.0-fpm.sock;
+ #}
+
+ # deny access to .htaccess files, if Apache's document root
+ # concurs with nginx's one
+ #
+ #location ~ /\.ht {
+ # deny all;
+ #}
+}
+
+
+# Virtual Host configuration for example.com
+#
+# You can move that to a different file under sites-available/ and symlink that
+# to sites-enabled/ to enable it.
+#
+server {
+ listen 80;
+# listen [::]:80;
+#
+# server_name example.com;
+#
+ root /var/www/;
+ index index.html;
+#
+ location /hw_drivers/ {
+ proxy_pass http://127.0.0.1:8069;
+ }
+}
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/rc.local b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/rc.local
new file mode 100755
index 00000000..ea965b19
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/rc.local
@@ -0,0 +1,25 @@
+#!/bin/sh -e
+#
+# rc.local
+#
+# This script is executed at the end of each multiuser runlevel.
+# Make sure that the script will "exit 0" on success or any other
+# value on error.
+#
+# In order to enable or disable this script just change the execution
+# bits.
+#
+# By default this script does nothing.
+
+# Print the IP address
+_IP=$(hostname -I) || true
+if [ "$_IP" ]; then
+ printf "My IP address is %s\n" "$_IP"
+fi
+
+mkdir -p /var/run/odoo
+chown pi:pi /var/run/odoo
+
+/home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/wireless_ap.sh &
+
+exit 0
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/resolv.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/resolv.conf
new file mode 100644
index 00000000..eb934916
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/resolv.conf
@@ -0,0 +1,5 @@
+# Edited by Odoo
+domain localdomain
+nameserver 8.8.8.8
+nameserver 8.8.4.4
+nameserver 1.1.1.1
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ssl/certs/nginx-cert.crt b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ssl/certs/nginx-cert.crt
new file mode 100644
index 00000000..6181845e
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ssl/certs/nginx-cert.crt
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID4TCCAsmgAwIBAgIJAMCws64aK3IlMA0GCSqGSIb3DQEBCwUAMIGFMQswCQYD
+VQQGEwJCRTEXMBUGA1UECAwOQnJhYmFudC1XYWxsb24xGTAXBgNVBAcMEEdyYW5k
+LVJvc2nDg8KocmUxEDAOBgNVBAoMB09kb29Jb1QxDDAKBgNVBAsMA0lvVDEiMCAG
+A1UEAwwZT2Rvb1RlbXBJb1RCb3hDZXJ0aWZpY2F0ZTAgFw0xODA5MjgxNjIzNDNa
+GA8yMTE4MDkwNDE2MjM0M1owgYUxCzAJBgNVBAYTAkJFMRcwFQYDVQQIDA5CcmFi
+YW50LVdhbGxvbjEZMBcGA1UEBwwQR3JhbmQtUm9zacODwqhyZTEQMA4GA1UECgwH
+T2Rvb0lvVDEMMAoGA1UECwwDSW9UMSIwIAYDVQQDDBlPZG9vVGVtcElvVEJveENl
+cnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8O2dZJO
+Pj9QJ2bIDthDNfDK4gm4jthIpwFpJFQmrWfZyQy2IiECnGwHlb8T2pZAw6LhyMbK
+EPeaiyNAxztkJQavyW/tyRzWJiVI5/gPkWn3PFSWiJc7tpN2dgYlOzhEa209SJvC
+qCS/ncraUt8o/KjW8F155mqYZ9qwD52tJyKjbtzIwG3KO5+ErcWGiMs77pGkimb1
+f9gNQ+JclGyVJ2WUhXeFU6C8hdz1JlsDqYabaZzS0ESvXhGhstcRUU/KzdNYe/7d
+Xw4vmxyQvzbyJaj+T5ILCMkgU6OPeEfswEF1qXyEIdIXlD4pSMlGzQ3MDku564e1
+ebR51BwkfHwtewIDAQABo1AwTjAdBgNVHQ4EFgQU5Zyb7DuZFqb96okkP1yfDV2Q
+Gv8wHwYDVR0jBBgwFoAU5Zyb7DuZFqb96okkP1yfDV2QGv8wDAYDVR0TBAUwAwEB
+/zANBgkqhkiG9w0BAQsFAAOCAQEALkon2ZHMBW9t+8oig/C5I+edCniSgs+2Loh9
+ufIG5G7KD8MuKjg55a9cCH1Ra5GSVZTj4krBPab21lN+8rb2mAeIEbIwyivx6dlP
+2x9Xf3ifvdB4Lav7zSjX3TNB+1OxLCYtxlCLDPdIHgSX5bz00KRsRPQn2o/hSBtK
+4BzZckiz7ZzUFZUQb1lzqccAPLMM28JCEgWFJPHRXQHIq6cMLNm/z6JlkGzNwl6m
+vdVieTlZ9dwwwGvgMk3lmGUYUO8NUyEi5n2sY72xAs3+2Tep2T4VHn0i9CYOsA2A
+k5/8BMbjf0ghkzhf2MkLBhIwHuaI6TKClvRtoRdTwceJhnkyPQ==
+-----END CERTIFICATE-----
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ssl/private/nginx-cert.key b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ssl/private/nginx-cert.key
new file mode 100644
index 00000000..b210484b
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ssl/private/nginx-cert.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrw7Z1kk4+P1An
+ZsgO2EM18MriCbiO2EinAWkkVCatZ9nJDLYiIQKcbAeVvxPalkDDouHIxsoQ95qL
+I0DHO2QlBq/Jb+3JHNYmJUjn+A+Rafc8VJaIlzu2k3Z2BiU7OERrbT1Im8KoJL+d
+ytpS3yj8qNbwXXnmaphn2rAPna0nIqNu3MjAbco7n4StxYaIyzvukaSKZvV/2A1D
+4lyUbJUnZZSFd4VToLyF3PUmWwOphptpnNLQRK9eEaGy1xFRT8rN01h7/t1fDi+b
+HJC/NvIlqP5PkgsIySBTo494R+zAQXWpfIQh0heUPilIyUbNDcwOS7nrh7V5tHnU
+HCR8fC17AgMBAAECggEAeYkN/br8Kgdai8aqH/bd97jdlXsTX9+h6KmS3+W7SE+H
+Rj78UMHSuyOlaku9nJlcUhFaeVpPeBn6/CCBoXdgsOI+V+Ye9oK09GDFaX2YZmf4
+THP938BCvDkzROesSG7T2r988XdlENyPyPLT8Hd+5OgCzikWK/eYx0Nx+Fq1Pk6W
+U7TSap7YFlXlP7vAxogOng1eIXQfWLWnS4ZYQALLWYlJbSwvnA2caEqM68df9M1z
+X974ZAVKYKftzc506s6Mrjaw0RBM/fXKUGAUsip5Aw/4QCzICqU71taolnwVl3dL
+tHFib7HX55ge5N0IBYIKzjj496ceUegnLNSaYmnPQQKBgQDj+5qjsBXkPuS0FABS
+yEHLf1xIrr2pVRnctlCmN7s/PIAL/depRBcRST2ZRQeek4LIgbDZ++nBSCPc2fMj
+TrVYq/b7VK7aCs0uDuvJT2ScVm6QHkoc780XNoAo5QgwARksW53N7ysbXkG/YaSj
+xDlcQ2dmjZNq1frEJBr3bXkMqQKBgQDA33dfm2khNJZFXOJIHxaxeilNBndowknF
+lHMm1hWXvjh66dwS3hxhj03pqF+33xxP6BA6y32sn30dFBduw9kvN/2gCsxTMDNE
+8/EncC31i1eEQH1vK/fe02nvR8SbI9NcyD53emsOWsZi/FevrHK+LudgopA/ddMk
+fbPN0rn7gwKBgGz9pQEqNl0G4Eli4oCw8ht6SMEKoOtqHtIQat/79s2Ve9W/xjFK
+twhxjjxO7wSVmsmGjui3cRoRBewYWg+AGlxI4etnoavlzA9/3KNCDGRdQcAuatoI
+nnDBgmWKkO56J/G33upLs70Cw8XdxVrxfUaphq5Vcqt5nsfURvwQ3vT5AoGAJ4qo
+8pTuDLy3Qik0ywx0npYo+X2l5XhPn447vW6Oprl84tYnJEcdEnNKyeiXFx9Ksqcl
+DKjDbyyTfe6sjyzfzepwuOr90OBE4pIQksFQ6tJScu61yKD/BFPbmA7io9vIbXEw
+PVZ/tEWv/oM1hvKX453CGfG6GQiS7RxITJ4zOvkCgYEAgaMK2j02vmWHuDWvCsJC
+XS8PMuVsc3cqwyhqyal4s9XGMHqsbeura3OI/LObg7inoSlSyD3Eax0MdlbwywmE
+Qq8FzCgw9gNu3BQPZgfKSfc/zvdAjlaVtLhW6ztoK1kWgmcnRXr5YNorNK99HHTL
+a4T40G2WVNTtlTOarEvYrP0=
+-----END PRIVATE KEY-----
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/home/pi/odoo/addons/point_of_sale/__manifest__.py b/addons/point_of_sale/tools/posbox/overwrite_after_init/home/pi/odoo/addons/point_of_sale/__manifest__.py
new file mode 100644
index 00000000..a9239cda
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/home/pi/odoo/addons/point_of_sale/__manifest__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+{}
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/local/lib/python3.7/dist-packages/v4l2.py.iotpatch b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/local/lib/python3.7/dist-packages/v4l2.py.iotpatch
new file mode 100644
index 00000000..5cc87a78
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/local/lib/python3.7/dist-packages/v4l2.py.iotpatch
@@ -0,0 +1,20 @@
+--- v4l2_old.py 2019-01-23 12:49:01.081564000 +0100
++++ v4l2_new.py 2019-01-23 12:50:32.369730171 +0100
+@@ -194,7 +194,7 @@
+ V4L2_BUF_TYPE_SLICED_VBI_OUTPUT,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY,
+ V4L2_BUF_TYPE_PRIVATE,
+-) = range(1, 9) + [0x80]
++) = list(range(1, 9)) + [0x80]
+
+
+ v4l2_ctrl_type = enum
+@@ -245,7 +245,7 @@
+ V4L2_PRIORITY_INTERACTIVE,
+ V4L2_PRIORITY_RECORD,
+ V4L2_PRIORITY_DEFAULT,
+-) = range(0, 4) + [2]
++) = list(range(0, 4)) + [2]
+
+
+ class v4l2_rect(ctypes.Structure):
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/share/eftdvs/eftdvs.cfg b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/share/eftdvs/eftdvs.cfg
new file mode 100644
index 00000000..66d6c56e
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/share/eftdvs/eftdvs.cfg
@@ -0,0 +1 @@
+/Trace logstd /TraceDir /var/log/eftdvs \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/share/firefox-esr/browser/defaults/preferences/all-posbox.js b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/share/firefox-esr/browser/defaults/preferences/all-posbox.js
new file mode 100644
index 00000000..d9101e38
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/share/firefox-esr/browser/defaults/preferences/all-posbox.js
@@ -0,0 +1,12 @@
+// Preferences to allow unattended install of R-Kiosk extension
+// Needed for Odoo IoT Box Client display
+pref("app.update.checkInstallTime", false);
+pref("devtools.webide.widget.autoinstall", false);
+pref("xpinstall.customConfirmationUI", false);
+pref("xpinstall.signatures.required", false);
+pref("browser.shell.checkDefaultBrowser", false);
+// Open all links in the same tab
+// Needed to change URL without having multiple tabs running
+pref("browser.link.open_newwindow", 1);
+pref("browser.shell.checkDefaultBrowser",false);
+pref("dom.max_chrome_script_run_time", 0);
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/var/www/iot.jpg b/addons/point_of_sale/tools/posbox/overwrite_after_init/var/www/iot.jpg
new file mode 100644
index 00000000..863710d5
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/var/www/iot.jpg
Binary files differ
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/default/keyboard b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/default/keyboard
new file mode 100644
index 00000000..2609b092
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/default/keyboard
@@ -0,0 +1,10 @@
+# KEYBOARD CONFIGURATION FILE
+
+# Consult the keyboard(5) manual page.
+
+XKBMODEL="pc105"
+XKBLAYOUT="us"
+XKBVARIANT=""
+XKBOPTIONS=""
+
+BACKSPACE="guess" \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/fstab b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/fstab
new file mode 100644
index 00000000..d8e448c0
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/fstab
@@ -0,0 +1,5 @@
+proc /proc proc defaults 0 0
+#/dev/mmcblk0p1 /boot vfat defaults 0 2
+#/dev/mmcblk0p2 / ext4 defaults,noatime 0 1
+# a swapfile is not a swap partition, no line here
+# use dphys-swapfile swap[on|off] for that
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init.d/odoo b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init.d/odoo
new file mode 100755
index 00000000..1b4de3ce
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init.d/odoo
@@ -0,0 +1,78 @@
+#!/bin/bash
+### BEGIN INIT INFO
+# Provides: odoo.py
+# Required-Start: $remote_fs $syslog
+# Required-Stop: $remote_fs $syslog
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: Start odoo daemon at boot time
+# Description: Enable service provided by daemon.
+# X-Interactive: true
+### END INIT INFO
+## more info: http://wiki.debian.org/LSBInitScripts
+
+. /lib/lsb/init-functions
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
+DAEMON=/home/pi/odoo/odoo-bin
+NAME=odoo
+DESC=odoo
+CONFIG=/home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/odoo.conf
+LOGFILE=/var/log/odoo/odoo-server.log
+PIDFILE=/var/run/${NAME}.pid
+MODULES=$(ls /home/pi/odoo/addons/ -m -w0 | tr -d ' ')
+USER=pi
+
+test -x $DAEMON || exit 0
+set -e
+
+function _start() {
+ # Wait for time to be synced or AP to start or max 30 seconds
+ cnt=30
+ while ! test -a /run/systemd/timesync/synchronized && ! ip route | grep 10.11.12.1 && ((cnt--)); do
+ sleep 1
+ done
+ start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USER:$USER --background --make-pidfile --exec $DAEMON -- --config $CONFIG --logfile $LOGFILE --load=$MODULES
+}
+
+function _stop() {
+ start-stop-daemon --stop --quiet --pidfile $PIDFILE --oknodo --retry 3
+ rm -f $PIDFILE
+}
+
+function _status() {
+ start-stop-daemon --status --quiet --pidfile $PIDFILE
+ return $?
+}
+
+
+case "$1" in
+ start)
+ echo -n "Starting $DESC: "
+ _start
+ echo "ok"
+ ;;
+ stop)
+ echo -n "Stopping $DESC: "
+ _stop
+ echo "ok"
+ ;;
+ restart|force-reload)
+ echo -n "Restarting $DESC: "
+ _stop
+ sleep 1
+ _start
+ echo "ok"
+ ;;
+ status)
+ echo -n "Status of $DESC: "
+ _status && echo "running" || echo "stopped"
+ ;;
+ *)
+ N=/etc/init.d/$NAME
+ echo "Usage: $N {start|stop|restart|force-reload|status}" >&2
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init.d/timesyncd b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init.d/timesyncd
new file mode 100755
index 00000000..eb5ccf94
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init.d/timesyncd
@@ -0,0 +1,41 @@
+#!/bin/bash
+### BEGIN INIT INFO
+# Provides: timesyncd
+# Required-Start: $remote_fs $network
+# Required-Stop: $remote_fs
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: Start systemd-timesyncd daemon at boot time
+# Description: Enable service provided by daemon.
+### END INIT INFO
+
+start()
+{
+ echo "start timesyncd"
+ service systemd-timesyncd start
+}
+
+stop()
+{
+ echo "stop timesyncd"
+ service systemd-timesyncd stop
+}
+
+restart()
+{
+ stop;
+ sleep 1;
+ start;
+}
+case $1 in
+start)
+ start;;
+stop)
+ stop;;
+restart)
+ restart;;
+*)
+ start;;
+esac
+
+exit 0
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh
new file mode 100755
index 00000000..9f580af4
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh
@@ -0,0 +1,171 @@
+#!/usr/bin/env bash
+set -o errexit
+set -o nounset
+set -o pipefail
+# set -o xtrace
+
+__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
+__base="$(basename ${__file} .sh)"
+
+# Recommends: antiword, graphviz, ghostscript, python-gevent, poppler-utils
+export DEBIAN_FRONTEND=noninteractive
+echo "nameserver 8.8.8.8" >> /etc/resolv.conf
+
+# set locale to en_US
+echo "set locale to en_US"
+echo "export LANGUAGE=en_US.UTF-8" >> ~/.bashrc
+echo "export LANG=en_US.UTF-8" >> ~/.bashrc
+echo "export LC_ALL=en_US.UTF-8" >> ~/.bashrc
+locale-gen
+source ~/.bashrc
+
+apt-get update && apt-get -y upgrade
+# Do not be too fast to upgrade to more recent firmware and kernel than 4.38
+# Firmware 4.44 seems to prevent the LED mechanism from working
+
+PKGS_TO_INSTALL="
+ console-data \
+ cups \
+ cups-ipp-utils \
+ dbus \
+ dbus-x11 \
+ dnsmasq \
+ firefox-esr \
+ fswebcam \
+ git \
+ hostapd \
+ iw \
+ kpartx \
+ libcups2-dev \
+ libpq-dev \
+ lightdm \
+ localepurge \
+ nginx-full \
+ openbox \
+ printer-driver-all \
+ python-cups \
+ python3 \
+ python3-babel \
+ python3-dateutil \
+ python3-decorator \
+ python3-dev \
+ python3-docutils \
+ python3-feedparser \
+ python3-html2text \
+ python3-jinja2 \
+ python3-ldap \
+ python3-libsass \
+ python3-lxml \
+ python3-mako \
+ python3-mock \
+ python3-netifaces \
+ python3-passlib \
+ python3-pil \
+ python3-pip \
+ python3-psutil \
+ python3-psycopg2 \
+ python3-pydot \
+ python3-pypdf2 \
+ python3-qrcode \
+ python3-reportlab \
+ python3-requests \
+ python3-serial \
+ python3-tz \
+ python3-urllib3 \
+ python3-werkzeug \
+ rsync \
+ screen \
+ unclutter \
+ vim \
+ x11-utils \
+ xdotool \
+ xserver-xorg-input-evdev \
+ xserver-xorg-video-dummy \
+ xserver-xorg-video-fbdev"
+
+echo "Acquire::Retries "16";" > /etc/apt/apt.conf.d/99acquire-retries
+# KEEP OWN CONFIG FILES DURING PACKAGE CONFIGURATION
+# http://serverfault.com/questions/259226/automatically-keep-current-version-of-config-files-when-apt-get-install
+apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install ${PKGS_TO_INSTALL}
+
+apt-get clean
+localepurge
+rm -rfv /usr/share/doc
+
+# python-usb in wheezy is too old
+# the latest pyusb from pip does not work either, usb.core.find() never returns
+# this may be fixed with libusb>2:1.0.11-1, but that's the most recent one in raspios
+# so we install the latest pyusb that works with this libusb.
+# Even in stretch, we had an error with langid (but worked otherwise)
+# We fixe the version of evdev to 1.2.0 because in 1.3.0 we have a RuntimeError in 'get_event_loop()'
+PIP_TO_INSTALL="
+ evdev==1.2.0 \
+ gatt \
+ polib \
+ pycups \
+ pyusb \
+ v4l2"
+
+pip3 install ${PIP_TO_INSTALL}
+
+# Dowload MPD server and library for Six terminals
+wget 'https://nightly.odoo.com/master/iotbox/eftdvs' -P /usr/local/bin/
+chmod +x /usr/local/bin/eftdvs
+wget 'https://nightly.odoo.com/master/iotbox/eftapi.so' -P /usr/lib/
+
+groupadd usbusers
+usermod -a -G usbusers pi
+usermod -a -G lp pi
+usermod -a -G input lightdm
+mkdir -v /var/log/odoo
+chown pi:pi /var/log/odoo
+chown pi:pi -R /home/pi/odoo/
+
+# logrotate is very picky when it comes to file permissions
+chown -R root:root /etc/logrotate.d/
+chmod -R 644 /etc/logrotate.d/
+chown root:root /etc/logrotate.conf
+chmod 644 /etc/logrotate.conf
+
+echo "* * * * * rm /var/run/odoo/sessions/*" | crontab -
+
+update-rc.d -f hostapd remove
+update-rc.d -f nginx remove
+update-rc.d -f dnsmasq remove
+update-rc.d timesyncd defaults
+
+systemctl enable ramdisks.service
+systemctl enable led-status.service
+systemctl disable dphys-swapfile.service
+systemctl enable ssh
+systemctl set-default graphical.target
+systemctl disable getty@tty1.service
+systemctl enable autologin@.service
+systemctl disable systemd-timesyncd.service
+systemctl unmask hostapd.service
+systemctl disable hostapd.service
+systemctl disable cups-browsed.service
+
+# disable overscan in /boot/config.txt, we can't use
+# overwrite_after_init because it's on a different device
+# (/dev/mmcblk0p1) and we don't mount that afterwards.
+# This option disables any black strips around the screen
+# cf: https://www.raspberrypi.org/documentation/configuration/raspi-config.md
+echo "disable_overscan=1" >> /boot/config.txt
+
+# Separate framebuffers for both screens on RPI4
+sed -i '/dtoverlay/d' /boot/config.txt
+
+# exclude /drivers folder from git info to be able to load specific drivers
+echo "addons/hw_drivers/iot_devices/" > /home/pi/odoo/.git/info/exclude
+
+# create dirs for ramdisks
+create_ramdisk_dir () {
+ mkdir -v "${1}_ram"
+}
+
+create_ramdisk_dir "/var"
+create_ramdisk_dir "/etc"
+create_ramdisk_dir "/tmp"
+mkdir -v /root_bypass_ramdisks
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/ld.so.preload b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/ld.so.preload
new file mode 100644
index 00000000..817eaf08
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/ld.so.preload
@@ -0,0 +1 @@
+#/usr/lib/arm-linux-gnueabihf/libarmmem-v8l.so
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/locale.gen b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/locale.gen
new file mode 100644
index 00000000..0f163ebe
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/locale.gen
@@ -0,0 +1,7 @@
+# This file lists locales that you wish to have built. You can find a list
+# of valid supported locales at /usr/share/i18n/SUPPORTED, and you can add
+# user defined locales to /usr/local/share/i18n/SUPPORTED. If you change
+# this file, you need to rerun locale-gen.
+#
+
+en_US.UTF-8 UTF-8
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/logrotate.conf b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/logrotate.conf
new file mode 100644
index 00000000..1ac409b2
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/logrotate.conf
@@ -0,0 +1,32 @@
+# see "man logrotate" for details
+# rotate log files daily
+daily
+
+# keep 2 days worth of backlogs
+rotate 2
+
+# create new (empty) log files after rotating old ones
+create
+
+# uncomment this if you want your log files compressed
+#compress
+
+# packages drop log rotation information into this directory
+include /etc/logrotate.d
+
+# no packages own wtmp, or btmp -- we'll rotate them here
+/var/log/wtmp {
+ missingok
+ monthly
+ create 0664 root utmp
+ rotate 1
+}
+
+/var/log/btmp {
+ missingok
+ monthly
+ create 0660 root utmp
+ rotate 1
+}
+
+# system-specific logs may be configured here
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/logrotate.d/odoo b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/logrotate.d/odoo
new file mode 100644
index 00000000..060ec54d
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/logrotate.d/odoo
@@ -0,0 +1,5 @@
+/var/log/odoo/*.log {
+ copytruncate
+ missingok
+ notifempty
+}
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/logrotate.d/rsyslog b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/logrotate.d/rsyslog
new file mode 100644
index 00000000..3c4ad130
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/logrotate.d/rsyslog
@@ -0,0 +1,37 @@
+/var/log/syslog
+{
+ rotate 3
+ daily
+ missingok
+ notifempty
+ delaycompress
+ compress
+ postrotate
+ invoke-rc.d rsyslog rotate > /dev/null
+ endscript
+}
+
+/var/log/mail.info
+/var/log/mail.warn
+/var/log/mail.err
+/var/log/mail.log
+/var/log/daemon.log
+/var/log/kern.log
+/var/log/auth.log
+/var/log/user.log
+/var/log/lpr.log
+/var/log/cron.log
+/var/log/debug
+/var/log/messages
+{
+ rotate 3
+ daily
+ missingok
+ notifempty
+ compress
+ delaycompress
+ sharedscripts
+ postrotate
+ invoke-rc.d rsyslog rotate > /dev/null
+ endscript
+}
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/nginx/sites-enabled/default b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/nginx/sites-enabled/default
new file mode 100644
index 00000000..353ac34d
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/nginx/sites-enabled/default
@@ -0,0 +1,87 @@
+##
+# You should look at the following URL's in order to grasp a solid understanding
+# of Nginx configuration files in order to fully unleash the power of Nginx.
+# http://wiki.nginx.org/Pitfalls
+# http://wiki.nginx.org/QuickStart
+# http://wiki.nginx.org/Configuration
+#
+# Generally, you will want to move this file somewhere, and start with a clean
+# file but keep this around for reference. Or just disable in sites-enabled.
+#
+# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
+##
+
+# Default server configuration
+#
+server {
+ listen 80 default_server;
+ #listen [::]:80 default_server;
+
+ # SSL configuration
+ #
+ # listen 443 ssl default_server;
+ # listen [::]:443 ssl default_server;
+ #
+ # Note: You should disable gzip for SSL traffic.
+ # See: https://bugs.debian.org/773332
+ #
+ # Read up on ssl_ciphers to ensure a secure configuration.
+ # See: https://bugs.debian.org/765782
+ #
+ # Self signed certs generated by the ssl-cert package
+ # Don't use them in a production server!
+ #
+ # include snippets/snakeoil.conf;
+
+ #root /var/www/html;
+
+ # Add index.php to the list if you are using PHP
+ #index index.html index.htm index.nginx-debian.html;
+
+ #server_name _;
+
+ location / {
+ # Every OS request specific address and .txt file to test if hotspot are connected to internet however login splash page don't display
+ # this line respond true for every request and send a login splash page to client
+ # it work for every OS
+ return 301 $scheme://10.11.12.1:8069;
+ }
+
+ # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
+ #
+ #location ~ \.php$ {
+ # include snippets/fastcgi-php.conf;
+ #
+ # # With php7.0-cgi alone:
+ # fastcgi_pass 127.0.0.1:9000;
+ # # With php7.0-fpm:
+ # fastcgi_pass unix:/run/php/php7.0-fpm.sock;
+ #}
+
+ # deny access to .htaccess files, if Apache's document root
+ # concurs with nginx's one
+ #
+ #location ~ /\.ht {
+ # deny all;
+ #}
+}
+
+
+# Virtual Host configuration for example.com
+#
+# You can move that to a different file under sites-available/ and symlink that
+# to sites-enabled/ to enable it.
+#
+#server {
+# listen 80;
+# listen [::]:80;
+#
+# server_name example.com;
+#
+# root /var/www/example.com;
+# index index.html;
+#
+# location / {
+# try_files $uri $uri/ =404;
+# }
+#} \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/rc.local b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/rc.local
new file mode 100755
index 00000000..22b8b8a5
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/rc.local
@@ -0,0 +1,22 @@
+#!/bin/sh -e
+#
+# rc.local
+#
+# This script is executed at the end of each multiuser runlevel.
+# Make sure that the script will "exit 0" on success or any other
+# value on error.
+#
+# In order to enable or disable this script just change the execution
+# bits.
+#
+# By default this script does nothing.
+
+# Print the IP address
+_IP=$(hostname -I) || true
+if [ "$_IP" ]; then
+ printf "My IP address is %s\n" "$_IP"
+fi
+
+/etc/init_posbox_image.sh 2>&1 | tee /home/pi/init_posbox_image.log
+
+exit 0
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/systemd/system/led-status.service b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/systemd/system/led-status.service
new file mode 100644
index 00000000..24e5637d
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/systemd/system/led-status.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Led Status
+After=sysinit.target local-fs.target
+
+[Service]
+Type=simple
+ExecStart=/home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/led_status.sh
+
+[Install]
+WantedBy=basic.target
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/systemd/system/ramdisks.service b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/systemd/system/ramdisks.service
new file mode 100644
index 00000000..48c75daa
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/systemd/system/ramdisks.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=ramdisks
+DefaultDependencies=no
+After=sysinit.target local-fs.target
+Before=basic.target
+
+[Service]
+Type=oneshot
+ExecStart=/home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/setup_ramdisks.sh
+
+[Install]
+WantedBy=basic.target
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/90-qemu.rules b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/90-qemu.rules
new file mode 100644
index 00000000..fadedd20
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/90-qemu.rules
@@ -0,0 +1,3 @@
+KERNEL=="sda", SYMLINK+="mmcblk0"
+KERNEL=="sda?", SYMLINK+="mmcblk0p%n"
+KERNEL=="sda2", SYMLINK+="root" \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/99-usb.rules b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/99-usb.rules
new file mode 100644
index 00000000..7a282a8e
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/99-usb.rules
@@ -0,0 +1,2 @@
+SUBSYSTEM=="usb", GROUP="usbusers", MODE="0660"
+SUBSYSTEMS=="usb", GROUP="usbusers", MODE="0660" \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/99-z-input.rules b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/99-z-input.rules
new file mode 100644
index 00000000..aab19f2d
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/99-z-input.rules
@@ -0,0 +1,2 @@
+SUBSYSTEM=="input", GROUP="input", MODE="0660"
+KERNEL=="tty[0-9]*", GROUP="tty", MODE="0660" \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.inputrc b/addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.inputrc
new file mode 100644
index 00000000..131b2414
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.inputrc
@@ -0,0 +1,53 @@
+#
+set meta-flag on
+set convert-meta off
+set input-meta on
+set output-meta on
+set show-all-if-ambiguous on
+set visible-stats on
+set bell-style none
+# set bell-style visible
+#"\M-k": kill-whole-line
+#----------------------------------------------------------
+# arrows left/right/up/down
+"\e[C": forward-char
+"\e[D": backward-char
+"\e[A": previous-history
+"\e[B": next-history
+# ---------------------------------------------------------
+# pgup/pgdn
+"\e[6~": history-search-forward
+"\e[5~": history-search-backward
+#----------------------------------------------------------
+# insert,delete
+#"\e[2~": quoted-insert
+"\e[3~": delete-char
+# esc+delete, esc+backspace
+"\e\e[3~": kill-word
+"\e\C-h": backward-kill-word
+#----------------------------------------------------------
+# ctrl left/right (rxvt)
+"\eOc": forward-word
+"\eOd": backward-word
+# ctrl left/right (xterm)
+"\e[1;5C": forward-word
+"\e[1;5D": backward-word
+# ctrl left/right (unknown)
+#"\e[5C": forward-word
+#"\e[5D": backward-word
+#"\e\e[C": forward-word
+#"\e\e[D": backward-word
+# ---------------------------------------------------------
+# home/end (linux console)
+"\e[1~": beginning-of-line
+"\e[4~": end-of-line
+# home/end (rxvt)
+"\e[7~": beginning-of-line
+"\e[8~": end-of-line
+# home/end (xterm, freebsd console)
+"\e[H": beginning-of-line
+"\e[F": end-of-line
+# home/end (non RH/Debian xterm, unknown)
+"\eOH": beginning-of-line
+"\eOF": end-of-line
+"\eOw": end-of-line
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.vimrc b/addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.vimrc
new file mode 100644
index 00000000..9e65af33
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.vimrc
@@ -0,0 +1,27 @@
+set all&
+set autoindent
+set backspace=2
+set nobackup
+set nocompatible
+set noerrorbells
+set noexpandtab
+set expandtab
+set number
+set hidden
+set history=500
+set hlsearch
+set ignorecase
+set modeline
+set ruler
+set shiftwidth=4
+set scrolloff=5
+set showcmd
+set showmode
+set tabstop=4
+set textwidth=0
+set visualbell
+set t_vb=
+set wrap
+set list
+set listchars=tab:~.,trail:.,extends:>,precedes:<
+set viminfo="NONE"
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.xsession b/addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.xsession
new file mode 100644
index 00000000..ddbeae99
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.xsession
@@ -0,0 +1,5 @@
+# Start Openbox on the second display as described in
+# http://openbox.org/wiki/Help:FAQ > "How do I run Openbox across multiple X screens?"
+
+XAUTHORITY=/run/lightdm/pi/xauthority DISPLAY=:0.1 openbox &
+exec openbox-session
diff --git a/addons/point_of_sale/tools/posbox/posbox_create_image.sh b/addons/point_of_sale/tools/posbox/posbox_create_image.sh
new file mode 100755
index 00000000..3808d727
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/posbox_create_image.sh
@@ -0,0 +1,162 @@
+#!/usr/bin/env bash
+set -o errexit
+set -o nounset
+set -o pipefail
+# set -o xtrace
+
+if [[ $EUID -ne 0 ]]; then
+ echo "This script must be run as root"
+ exit 1
+fi
+
+file_exists() {
+ [[ -f $1 ]];
+}
+
+require_command () {
+ type "$1" &> /dev/null || { echo "Command $1 is missing. Install it e.g. with 'apt-get install $1'. Aborting." >&2; exit 1; }
+}
+
+require_command kpartx
+require_command qemu-arm-static
+require_command zerofree
+
+__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
+__base="$(basename ${__file} .sh)"
+
+MOUNT_POINT="${__dir}/root_mount"
+OVERWRITE_FILES_BEFORE_INIT_DIR="${__dir}/overwrite_before_init"
+OVERWRITE_FILES_AFTER_INIT_DIR="${__dir}/overwrite_after_init"
+VERSION=14.0
+VERSION_IOTBOX=21.04
+REPO=https://github.com/odoo/odoo.git
+
+if ! file_exists *raspios*.img ; then
+ wget 'http://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2021-03-25/2021-03-04-raspios-buster-armhf-lite.zip' -O raspios.img.zip
+ unzip raspios.img.zip
+fi
+
+RASPIOS=$(echo *raspios*.img)
+rsync -avh --progress "${RASPIOS}" iotbox.img
+
+CLONE_DIR="${OVERWRITE_FILES_BEFORE_INIT_DIR}/home/pi/odoo"
+
+rm -rfv "${CLONE_DIR}"
+
+if [ ! -d $CLONE_DIR ]; then
+ echo "Clone Github repo"
+ mkdir -pv "${CLONE_DIR}"
+ git clone -b ${VERSION} --no-local --no-checkout --depth 1 ${REPO} "${CLONE_DIR}"
+ cd "${CLONE_DIR}"
+ git config core.sparsecheckout true
+ echo "addons/web
+addons/hw_*
+addons/point_of_sale/tools/posbox/configuration
+odoo/
+odoo-bin" | tee --append .git/info/sparse-checkout > /dev/null
+ git read-tree -mu HEAD
+fi
+
+cd "${__dir}"
+USR_BIN="${OVERWRITE_FILES_BEFORE_INIT_DIR}/usr/bin/"
+mkdir -pv "${USR_BIN}"
+cd "/tmp"
+curl 'https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-arm.zip' > ngrok.zip
+unzip ngrok.zip
+rm -v ngrok.zip
+cd "${__dir}"
+mv -v /tmp/ngrok "${USR_BIN}"
+
+# zero pad the image to be around 4.4 GiB, by default the image is only ~2.2 GiB
+echo "Enlarging the image..."
+dd if=/dev/zero bs=1M count=2048 status=progress >> iotbox.img
+
+# resize partition table
+echo "Fdisking"
+
+SECTORS_BOOT_START=$(sudo fdisk -l iotbox.img | tail -n 2 | awk 'NR==1 {print $2}')
+SECTORS_BOOT_END=$((SECTORS_BOOT_START + 1048576)) # sectors to have a partition of ~512Mo
+SECTORS_ROOT_START=$((SECTORS_BOOT_END + 1))
+
+START_OF_ROOT_PARTITION=$(fdisk -l iotbox.img | tail -n 1 | awk '{print $2}')
+(echo 'p'; # print
+ echo 'd'; # delete
+ echo '2'; # number 2
+ echo 'd'; # delete number 1 by default
+ echo 'n'; # create new partition
+ echo 'p'; # primary
+ echo '1'; # number 1
+ echo "${SECTORS_BOOT_START}"; # first sector
+ echo "${SECTORS_BOOT_END}"; # partition size
+ echo 't'; # change type of partition. 1 selected by default
+ echo 'c'; # change to W95 FAT32 (LBA)
+ echo 'n'; # create new partition
+ echo 'p'; # primary
+ echo '2'; # number 2
+ echo "${SECTORS_ROOT_START}"; # starting at previous offset
+ echo ''; # ending at default (fdisk should propose max)
+ echo 'p'; # print
+ echo 'w') | fdisk iotbox.img # write and quit
+
+LOOP_RASPIOS=$(kpartx -avs "${RASPIOS}")
+LOOP_RASPIOS_ROOT=$(echo "${LOOP_RASPIOS}" | tail -n 1 | awk '{print $3}')
+LOOP_RASPIOS_PATH="/dev/${LOOP_RASPIOS_ROOT::-2}"
+LOOP_RASPIOS_ROOT="/dev/mapper/${LOOP_RASPIOS_ROOT}"
+
+LOOP_IOT=$(kpartx -avs iotbox.img)
+LOOP_IOT_ROOT=$(echo "${LOOP_IOT}" | tail -n 1 | awk '{print $3}')
+LOOP_IOT_PATH="/dev/${LOOP_IOT_ROOT::-2}"
+LOOP_IOT_ROOT="/dev/mapper/${LOOP_IOT_ROOT}"
+LOOP_IOT_BOOT=$(echo "${LOOP_IOT}" | tail -n 2 | awk 'NR==1 {print $3}')
+LOOP_IOT_BOOT="/dev/mapper/${LOOP_IOT_BOOT}"
+
+mkfs.ext4 -v "${LOOP_IOT_ROOT}"
+
+dd if="${LOOP_RASPIOS_ROOT}" of="${LOOP_IOT_ROOT}" bs=4M status=progress
+
+# resize filesystem
+e2fsck -fv "${LOOP_IOT_ROOT}" # resize2fs requires clean fs
+resize2fs "${LOOP_IOT_ROOT}"
+
+mkdir -pv "${MOUNT_POINT}" #-p: no error if existing
+mount -v "${LOOP_IOT_ROOT}" "${MOUNT_POINT}"
+mount -v "${LOOP_IOT_BOOT}" "${MOUNT_POINT}/boot/"
+
+QEMU_ARM_STATIC="/usr/bin/qemu-arm-static"
+cp -v "${QEMU_ARM_STATIC}" "${MOUNT_POINT}/usr/bin/"
+
+# 'overlay' the overwrite directory onto the mounted image filesystem
+cp -av "${OVERWRITE_FILES_BEFORE_INIT_DIR}"/* "${MOUNT_POINT}"
+chroot "${MOUNT_POINT}" /bin/bash -c "sudo /etc/init_posbox_image.sh"
+
+# copy iotbox version
+mkdir -pv "${MOUNT_POINT}"/var/odoo
+echo "${VERSION_IOTBOX}" | tee "${MOUNT_POINT}"/var/odoo/iotbox_version "${MOUNT_POINT}"/home/pi/iotbox_version
+
+# get rid of the git clone
+rm -rfv "${CLONE_DIR}"
+# and the ngrok usr/bin
+rm -rfv "${OVERWRITE_FILES_BEFORE_INIT_DIR}/usr"
+cp -av "${OVERWRITE_FILES_AFTER_INIT_DIR}"/* "${MOUNT_POINT}"
+
+find "${MOUNT_POINT}"/ -type f -name "*.iotpatch"|while read iotpatch; do
+ DIR=$(dirname "${iotpatch}")
+ BASE=$(basename "${iotpatch%.iotpatch}")
+ find "${DIR}" -type f -name "${BASE}" ! -name "*.iotpatch"|while read file; do
+ patch -f --verbose "${file}" < "${iotpatch}"
+ done
+done
+
+# cleanup
+umount -fv "${MOUNT_POINT}"/boot/
+umount -fv "${MOUNT_POINT}"/
+rm -rfv "${MOUNT_POINT}"
+
+echo "Running zerofree..."
+zerofree -v "${LOOP_IOT_ROOT}" || true
+
+sleep 10
+
+kpartx -dv "${LOOP_IOT_PATH}"
+kpartx -dv "${LOOP_RASPIOS_PATH}"