Initial commit: Sale packages

This commit is contained in:
Ernad Husremovic 2025-08-29 15:20:49 +02:00
commit 14e3d26998
6469 changed files with 2479670 additions and 0 deletions

View file

@ -0,0 +1,2 @@
from . import pos_order_data

View file

@ -0,0 +1,16 @@
class PoSOrderData:
"""
Convenience class which allow to easily compare 2 "orders datas" received from PoS ui
"""
def __init__(self, order_data: dict):
self.order_payment_value_sorted = tuple(sorted([(p[2]['amount'], p[2]['payment_method_id']) for p in order_data['statement_ids']]))
self.order_received_lines_sorted = tuple(sorted([(l[2]['product_id'], l[2]['qty'], l[2]['price_unit']) for l in order_data['lines']]))
def __hash__(self):
return hash((
self.order_received_lines_sorted,
self.order_payment_value_sorted,
))

View file

@ -0,0 +1,3 @@
kernel-qemu
posbox.img
raspbian.img

View file

@ -0,0 +1,152 @@
#!/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_server_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_server_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_server_wifi "Connecting to ${ESSID}"
sudo service hostapd stop
sudo killall nginx
current_iotbox_version=$(cat "/var/odoo/iotbox_version")
# Above this version we need the NetworkManager
required_version="23.09"
if [[ "$current_iotbox_version" > "$required_version" ]]; then
logger -t posbox_connect_to_server_wifi "USING NETWORK MANAGER"
# Necessary when comming from the access point
sudo ip address del 10.11.12.1/24 dev wlan0
sudo nmcli g reload
if [ -z "${PASSWORD}" ] ; then
sudo nmcli d wifi connect "${ESSID}"
else
sudo nmcli d wifi connect "${ESSID}" password "${PASSWORD}"
fi
sudo service nginx restart
else
logger -t posbox_connect_to_server_wifi "USING WPA_SUPPLICANT"
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
fi
# 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_server_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_server_wifi "Restarting odoo"
fi
if [ ${WIFI_WAS_LOST} -eq 0 ] ; then
touch "${LOST_WIFI_FILE}"
fi
logger -t posbox_connect_to_server_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}" &

View file

@ -0,0 +1,109 @@
#!/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
current_iotbox_version=$(cat "/var/odoo/iotbox_version")
# Above this version we need the NetworkManager
required_version="23.09"
if [[ "$current_iotbox_version" > "$required_version" ]]; then
logger -t posbox_connect_to_wifi "USING NETWORK MANAGER"
# Necessary when comming from the access point
sudo ip address del 10.11.12.1/24 dev wlan0
sudo nmcli g reload
if [ -z "${PASSWORD}" ] ; then
sudo nmcli d wifi connect "${ESSID}"
else
sudo nmcli d wifi connect "${ESSID}" password "${PASSWORD}"
fi
sudo service nginx restart
else
logger -t posbox_connect_to_wifi "USING WPA_SUPPLICANT"
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
fi
# 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}" &

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,36 @@
#!/usr/bin/env bash
ODOO_CONF=$(</home/pi/odoo.conf)
migrate_setting() {
TARGET_FILE="$1"
CONF_KEY="$2"
APPEND="$3"
if [ ! -f "$TARGET_FILE" ] || [ -n "$APPEND" ]
then
REGEX="$CONF_KEY = ([^[:space:]]+)"
if [[ "$ODOO_CONF" =~ $REGEX ]]
then
VALUE=${BASH_REMATCH[1]}
echo "$VALUE" >> "$TARGET_FILE"
SETTINGS_MIGRATED='true'
fi
fi
}
migrate_setting '/home/pi/odoo-remote-server.conf' 'remote_server'
migrate_setting '/home/pi/token' 'token'
migrate_setting '/home/pi/odoo-db-uuid.conf' 'db_uuid'
migrate_setting '/home/pi/odoo-enterprise-code.conf' 'enterprise_code'
migrate_setting '/home/pi/odoo-subject.conf' 'subject'
if [ ! -f '/home/pi/wifi_network.txt' ]
then
migrate_setting '/home/pi/wifi_network.txt' 'wifi_ssid'
migrate_setting '/home/pi/wifi_network.txt' 'wifi_password' 'true'
fi
if [ -n "$SETTINGS_MIGRATED" ]
then
cp '/home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/odoo.conf' '/home/pi/odoo.conf'
fi

View file

@ -0,0 +1,10 @@
[options]
data_dir = /var/run/odoo
log_handler = :WARNING
log_level = warn
logfile = /var/log/odoo/odoo-server.log
pidfile = /var/run/odoo/odoo.pid
limit_time_cpu = 600
limit_time_real = 1200
max_cron_threads = 0
server_wide_modules=hw_drivers,hw_escpos,hw_posbox_homepage,web

View file

@ -0,0 +1,24 @@
#!/usr/bin/env bash
sudo mount -o remount,rw /
sudo service odoo 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
echo "addons/iot_base" >> .git/info/sparse-checkout
git fetch "${localremote}" "${localbranch}" --depth=1
git reset "${localremote}"/"${localbranch}" --hard
git clean -dfx
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 mount -o remount,ro /
sudo mount -o remount,rw /root_bypass_ramdisks/etc/cups
(sleep 5 && sudo service odoo restart) &

View file

@ -0,0 +1,34 @@
#!/usr/bin/env bash
# Write the server configuration
function connect () {
HOSTS=/root_bypass_ramdisks/etc/hosts
HOST_FILE=/root_bypass_ramdisks/etc/hostname
HOSTNAME="$(hostname)"
IOT_NAME="${1}"
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 [ "${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
}
connect "${1}"

View file

@ -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

View file

@ -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/
}

View file

@ -0,0 +1,70 @@
#!/usr/bin/env bash
FORCE_HOST_AP="${1}"
WIFI_NETWORK_FILE="/home/pi/wifi_network.txt"
COUNTER=0
# we need to wait to receive an ip address from the dhcp before enable the access point.
# only if only if no configuration file for the wifi networks is recorded
if ! [ -f "${WIFI_NETWORK_FILE}" ] && [ -z "${FORCE_HOST_AP}" ] ; then
while [ "$(hostname -I)" = '' ] && [ "$COUNTER" -le 10 ]; do sleep 2;((COUNTER++)); done
fi
# Do we have to use the NetworkManager ?
current_iotbox_version=$(cat "/var/odoo/iotbox_version")
required_version="23.11"
if [[ "$current_iotbox_version" < "$required_version" ]]; then
logger -t wireless_ap "USING WPA_SUPPLICANT REMOVING NETWORK MANAGER SERVICE"
sudo service NetworkManager stop
fi
WIRED_IP=$(hostname -I)
if [ "$WIRED_IP" ]; then
printf "My IP address is %s\n" "$WIRED_IP"
fi
# by default wlan0 is soft blocked.
# we need unblock all radio devices
rfkill unblock all
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 odoo restart
fi
# wired
else
killall nginx
service nginx restart
service dnsmasq stop
service odoo restart
fi

View file

@ -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

View file

@ -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

View file

@ -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>

View file

@ -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"

View file

@ -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"

View file

@ -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;
# }
#}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,3 @@
interface=wlan0
ssid=IoTBox
channel=1

View file

@ -0,0 +1 @@
/usr/lib/arm-linux-gnueabihf/libarmmem-v8l.so

View file

@ -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

View file

@ -0,0 +1,3 @@
# needed for postgresql
auto lo
iface lo inet loopback

View file

@ -0,0 +1,98 @@
##
# 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;
}
error_page 502 /502.html;
location /502.html {
root /var/www/html;
}
# 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;
root /var/www/;
index index.html;
location / {
proxy_pass http://127.0.0.1:8069;
}
error_page 502 /502.html;
location /502.html {
root /var/www/html;
}
}

View file

@ -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

View file

@ -0,0 +1,4 @@
# Edited by Odoo
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 1.1.1.1

View file

@ -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-----

View file

@ -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-----

View file

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{}

View file

@ -0,0 +1 @@
/Trace logstd /TraceDir /var/log/eftdvs

View file

@ -0,0 +1,12 @@
// Preferences to allow unattended install of R-Kiosk extension
// Needed for Odoo IoT Box Customer 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);

View file

@ -0,0 +1,89 @@
<!DOCTYPE html>
<html>
<head>
<style>
body {
width: 600px;
margin: 30px auto;
font-family: sans-serif;
text-align: justify;
color: #6B6B6B;
background-color: #f1f1f1;
}
a {
text-decoration: none;
color: #00a09d;
}
a:hover {
color: #006d6b;
}
.container {
padding: 10px 20px;
background: #ffffff;
border-radius: 8px;
box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.17);
}
input[type="text"], input[type="password"] {
padding: 6px 12px;
font-size: 1rem;
border: 1px solid #ccc;
border-radius: 3px;
color: inherit;
}
input::placeholder {
color: #ccc;
opacity: 1; /* Firefox */
}
select {
padding: 6px 12px;
font-size: 1rem;
border: 1px solid #ccc;
border-radius: 3px;
color: inherit;
background: #ffffff;
width: 100%;
}
.footer {
margin-top: 12px;
text-align: right;
}
.footer a {
margin-left: 8px;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<div class="container">
<h1 style="color: red">IoT Box is down</h1>
<h2>502 Bad Gateway</h2>
<p>The IoT Box received the request but was not able to handle it. You can try to refresh the page to see if the request can now be handled.</p>
<p>If the error persist for more than 5 minutes:</p>
<ol>
<li>Force restart the IoT box by plug off the IoT power supply then on again</li>
<li>Re-flash the SD card of the IoT box, see: <a
href="https://www.odoo.com/documentation/17.0/applications/general/iot/config/updating_iot.html#flashing-the-sd-card-on-iot-box" target="_blank">documentation</a></li>
</ol>
</div>
<div class="footer">
<a href='https://www.odoo.com/help'>Help</a>
<a href='https://www.odoo.com/documentation/17.0/applications/productivity/iot.html'>Documentation</a>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

@ -0,0 +1,10 @@
# KEYBOARD CONFIGURATION FILE
# Consult the keyboard(5) manual page.
XKBMODEL="pc105"
XKBLAYOUT="us"
XKBVARIANT=""
XKBOPTIONS=""
BACKSPACE="guess"

View file

@ -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

View file

@ -0,0 +1,76 @@
#!/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() {
start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USER:$USER --background --make-pidfile --exec $DAEMON -- --config $CONFIG --logfile $LOGFILE --load=$MODULES --max-cron-threads=0
# this enables and starts the first existing network synchronization service
timedatectl set-ntp true
}
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

View file

@ -0,0 +1,191 @@
#!/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
# 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
# upgrade firmware-brcm80211 broke access point on rpi4
apt-mark hold firmware-brcm80211
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
# At the first start it is necessary to configure a password
# This will be modified by a unique password on the first start of Odoo
password="$(openssl rand -base64 12)"
echo "pi:${password}" | chpasswd
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 \
python3 \
python3-cups \
python3-babel \
python3-dateutil \
python3-dbus \
python3-decorator \
python3-dev \
python3-docutils \
python3-geoip2 \
python3-jinja2 \
python3-ldap \
python3-libsass \
python3-libcamera \
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 \
python3-venv \
rsync \
screen \
swig \
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.6.0 \
gatt \
polib \
pycups \
pyusb \
v4l2 \
pysmb==1.2.9.1 \
cryptocode==0.1 \
PyKCS11 \
vcgencmd \
RPi.GPIO \
rjsmin==1.1.0 \
schedule==1.2.1"
mkdir venv
python3 -m venv venv
venv/bin/pip3 install ${PIP_TO_INSTALL}
rsync -avrhp venv/lib/python3.11/site-packages/* /usr/lib/python3/dist-packages/
# 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
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 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
echo "password"
echo ${password}

View file

@ -0,0 +1 @@
#/usr/lib/arm-linux-gnueabihf/libarmmem-v8l.so

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,5 @@
/var/log/odoo/*.log {
copytruncate
missingok
notifempty
}

View file

@ -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
}

View file

@ -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;
# }
#}

View file

@ -0,0 +1,16 @@
#!/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.
/etc/init_posbox_image.sh 2>&1 | tee /home/pi/init_posbox_image.log
exit 0

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,3 @@
KERNEL=="sda", SYMLINK+="mmcblk0"
KERNEL=="sda?", SYMLINK+="mmcblk0p%n"
KERNEL=="sda2", SYMLINK+="root"

View file

@ -0,0 +1,2 @@
SUBSYSTEM=="usb", GROUP="usbusers", MODE="0660"
SUBSYSTEMS=="usb", GROUP="usbusers", MODE="0660"

View file

@ -0,0 +1,2 @@
SUBSYSTEM=="input", GROUP="input", MODE="0660"
KERNEL=="tty[0-9]*", GROUP="tty", MODE="0660"

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -0,0 +1,154 @@
#!/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=16.0
VERSION_IOTBOX=23.11
REPO=https://github.com/odoo/odoo.git
if ! file_exists *raspios*.img ; then
wget 'https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2023-10-10/2023-10-10-raspios-bookworm-armhf-lite.img.xz' -O raspios.img.xz
unxz --verbose raspios.img.xz
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/bNyj1mQVY4c/ngrok-v3-stable-linux-arm.tgz' > ngrok.tgz
tar xvzf ngrok.tgz -C "${USR_BIN}"
rm -v ngrok.tgz
cd "${__dir}"
# 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 + 1056767)) # sectors to have a partition of ~512Mo
SECTORS_ROOT_START=$((SECTORS_BOOT_END + 1))
(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_RASPIOS_BOOT=$(echo "${LOOP_RASPIOS}" | head -n 1 | awk '{print $3}')
LOOP_RASPIOS_BOOT="/dev/mapper/${LOOP_RASPIOS_BOOT}"
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}" | head -n 1 | 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 "/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 -rf "${CLONE_DIR}"
# and the ngrok usr/bin
rm -rf "${OVERWRITE_FILES_BEFORE_INIT_DIR}/usr"
cp -a "${OVERWRITE_FILES_AFTER_INIT_DIR}"/* "${MOUNT_POINT}"
# cleanup
umount -fv "${MOUNT_POINT}"/boot/
umount -lv "${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}"