@@ -28,65 +28,96 @@ setFTLConfigValue() {
2828 pihole-FTL --config " ${1} " " ${2} " > /dev/null
2929}
3030
31+ __timestamp (){
32+ date " +%Y%m%dT%H%M%S"
33+ }
34+
35+ __log (){
36+ local level=" $1 "
37+ local service=" $2 "
38+ local msg=" $3 "
39+
40+ # Check if msg is valid JSON - if so, use --argjson to avoid escaping
41+ if echo " $msg " | jq empty 2> /dev/null; then
42+ echo ' {}' | \
43+ jq --monochrome-output \
44+ --compact-output \
45+ --raw-output \
46+ --arg timestamp " $( __timestamp) " \
47+ --arg level " $level " \
48+ --arg service " $service " \
49+ --argjson msg " $msg " \
50+ ' .timestamp=$timestamp|.log_level=$level|.service=$service|.message=$msg'
51+ else
52+ echo ' {}' | \
53+ jq --monochrome-output \
54+ --compact-output \
55+ --raw-output \
56+ --arg timestamp " $( __timestamp) " \
57+ --arg level " $level " \
58+ --arg service " $service " \
59+ --arg msg " $msg " \
60+ ' .timestamp=$timestamp|.log_level=$level|.service=$service|.message=$msg'
61+ fi
62+ }
63+
3164set_uid_gid () {
3265
33- echo " [i] Setting up user & group for the pihole user"
66+ __log " INFO " " pihole-docker " " Setting up user & group for the pihole user"
3467
3568 currentUid=$( id -u pihole)
3669
3770 # If PIHOLE_UID is set, modify the pihole group's id to match
3871 if [ -n " ${PIHOLE_UID} " ]; then
3972 if [[ ${currentUid} -ne ${PIHOLE_UID} ]]; then
40- echo " [i] Changing ID for user: pihole (${currentUid} => ${PIHOLE_UID} )"
73+ __log " INFO " " pihole-docker " " Changing ID for user: pihole (${currentUid} => ${PIHOLE_UID} )"
4174 usermod -o -u " ${PIHOLE_UID} " pihole
4275 else
43- echo " [i] ID for user pihole is already ${PIHOLE_UID} , no need to change"
76+ __log " INFO " " pihole-docker " " ID for user pihole is already ${PIHOLE_UID} , no need to change"
4477 fi
4578 else
46- echo " [i] PIHOLE_UID not set in environment, using default (${currentUid} )"
79+ __log " INFO " " pihole-docker " " PIHOLE_UID not set in environment, using default (${currentUid} )"
4780 fi
4881
4982 currentGid=$( id -g pihole)
5083
5184 # If PIHOLE_GID is set, modify the pihole group's id to match
5285 if [ -n " ${PIHOLE_GID} " ]; then
5386 if [[ ${currentGid} -ne ${PIHOLE_GID} ]]; then
54- echo " [i] Changing ID for group: pihole (${currentGid} => ${PIHOLE_GID} )"
87+ __log " INFO " " pihole-docker " " Changing ID for group: pihole (${currentGid} => ${PIHOLE_GID} )"
5588 groupmod -o -g " ${PIHOLE_GID} " pihole
5689 else
57- echo " [i] ID for group pihole is already ${PIHOLE_GID} , no need to change"
90+ __log " INFO " " pihole-docker " " ID for group pihole is already ${PIHOLE_GID} , no need to change"
5891 fi
5992 else
60- echo " [i] PIHOLE_GID not set in environment, using default (${currentGid} )"
93+ __log " INFO " " pihole-docker " " PIHOLE_GID not set in environment, using default (${currentGid} )"
6194 fi
62- echo " "
6395}
6496
6597install_additional_packages () {
6698 if [ -n " ${ADDITIONAL_PACKAGES} " ]; then
67- echo " [i] Additional packages requested: ${ADDITIONAL_PACKAGES} "
68- echo " [i] Fetching APK repository metadata."
99+ __log " INFO " " pihole-docker " " Additional packages requested: ${ADDITIONAL_PACKAGES} "
100+ __log " INFO " " pihole-docker " " Fetching APK repository metadata."
69101 if ! apk update; then
70- echo " [i] Failed to fetch APK repository metadata."
102+ __log " ERROR " " pihole-docker " " Failed to fetch APK repository metadata."
71103 else
72- echo " [i] Installing additional packages: ${ADDITIONAL_PACKAGES} ."
104+ __log " INFO " " pihole-docker " " Installing additional packages: ${ADDITIONAL_PACKAGES} ."
73105 # shellcheck disable=SC2086
74106 if ! apk add --no-cache ${ADDITIONAL_PACKAGES} ; then
75- echo " [i] Failed to install additional packages."
107+ __log " ERROR " " pihole-docker " " Failed to install additional packages."
76108 fi
77109 fi
78- echo " "
79110 fi
80111}
81112
82113start_cron () {
83- echo " [i] Starting crond for scheduled scripts. Randomizing times for gravity and update checker"
114+ __log " INFO " " pihole-docker " " Starting crond for scheduled scripts. Randomizing times for gravity and update checker"
84115 # Randomize gravity update time
85116 sed -i " s/59 1 /$(( 1 + RANDOM % 58 )) $(( 3 + RANDOM % 2 )) /" /crontab.txt
86117 # Randomize update checker time
87118 sed -i " s/59 17/$(( 1 + RANDOM % 58 )) $(( 12 + RANDOM % 8 )) /" /crontab.txt
88119 if ! /usr/bin/crontab /crontab.txt; then
89- echo " [!] Failed to install crontab - scheduled tasks (gravity, update checker) will not run"
120+ __log " ERROR " " pihole-docker " " Failed to install crontab - scheduled tasks (gravity, update checker) will not run"
90121 fi
91122
92123 # Run crond in foreground, prefix each line from STDIN/STDOUT with the current date/time/timezone and
@@ -99,33 +130,31 @@ install_logrotate() {
99130 # Install the logrotate config file - this is done already in Dockerfile
100131 # but if a user has mounted a volume over /etc/pihole, it will have been lost
101132 # pihole-FTL-prestart.sh will set the ownership of the file to root:root
102- echo " [i] Ensuring logrotate script exists in /etc/pihole"
133+ __log " INFO " " pihole-docker " " Ensuring logrotate script exists in /etc/pihole"
103134 install -Dm644 -t /etc/pihole /etc/.pihole/advanced/Templates/logrotate
104- echo " "
105135}
106136
107137migrate_gravity () {
108- echo " [i] Gravity migration checks"
138+ __log " INFO " " pihole-docker " " Gravity migration checks"
109139 gravityDBfile=$( getFTLConfigValue files.gravity)
110140
111141 if [[ ! -f /etc/pihole/adlists.list ]]; then
112- echo " [i] No adlist file found, creating one with a default blocklist"
142+ __log " INFO " " pihole-docker " " No adlist file found, creating one with a default blocklist"
113143 echo " https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" > /etc/pihole/adlists.list
114144 fi
115145
116146 if [ ! -f " ${gravityDBfile} " ]; then
117- echo " [i] ${gravityDBfile} does not exist (Likely due to a fresh volume). This is a required file for Pi-hole to operate."
118- echo " [i] Gravity will now be run to create the database"
147+ __log " INFO " " pihole-docker " " ${gravityDBfile} does not exist (Likely due to a fresh volume). This is a required file for Pi-hole to operate."
148+ __log " INFO " " pihole-docker " " Gravity will now be run to create the database"
119149 pihole -g
120150 else
121- echo " [i] Existing gravity database found - schema will be upgraded if necessary"
151+ __log " INFO " " pihole-docker " " Existing gravity database found - schema will be upgraded if necessary"
122152 # source the migration script and run the upgrade function
123153 source /etc/.pihole/advanced/Scripts/database_migration/gravity-db.sh
124154 local upgradeOutput
125155 upgradeOutput=$( upgrade_gravityDB " ${gravityDBfile} " " /etc/pihole" )
126- printf " %b " " ${upgradeOutput} \\ n " | sed ' s/^/ / '
156+ __log " INFO " " pihole-docker " " Gravity DB migration output: ${upgradeOutput} "
127157 fi
128- echo " "
129158}
130159
131160# shellcheck disable=SC2034
@@ -144,7 +173,7 @@ ftl_config() {
144173
145174 # If getFTLConfigValue "dns.upstreams" returns [], default to Google's DNS server
146175 if [[ $( getFTLConfigValue " dns.upstreams" ) == " []" ]]; then
147- echo " [i] No DNS upstream set in environment or config file, defaulting to Google DNS"
176+ __log " INFO " " pihole-docker " " No DNS upstream set in environment or config file, defaulting to Google DNS"
148177 setFTLConfigValue " dns.upstreams" " [\" 8.8.8.8\" , \" 8.8.4.4\" ]"
149178 fi
150179
@@ -156,7 +185,7 @@ migrate_v5_configs() {
156185 # During migration, their content is copied into the new single source of
157186 # truth file /etc/pihole/pihole.toml and the old files are moved away to
158187 # avoid conflicts with other services on this system
159- echo " [i] Migrating dnsmasq configuration files"
188+ __log " INFO " " pihole-docker " " Migrating dnsmasq configuration files"
160189 V6_CONF_MIGRATION_DIR=" /etc/pihole/migration_backup_v6"
161190 # Create target directory and make it owned by pihole:pihole
162191 mkdir -p " ${V6_CONF_MIGRATION_DIR} "
@@ -171,7 +200,6 @@ migrate_v5_configs() {
171200
172201 mv /etc/dnsmasq.d/0{1,2,4,5}-pihole* .conf " ${V6_CONF_MIGRATION_DIR} /" 2> /dev/null || true
173202 mv /etc/dnsmasq.d/06-rfc6761.conf " ${V6_CONF_MIGRATION_DIR} /" 2> /dev/null || true
174- echo " "
175203
176204 # Finally, after everything is in place, we can create the new config file
177205 # /etc/pihole/pihole.toml
@@ -186,13 +214,11 @@ migrate_v5_configs() {
186214 # We suppress the message about environment variables as these will be set on FTL's first real start
187215 printf " %b" " ${FTLoutput} \\ n" | sed ' s/^/ /' | sed ' s/ Migrating config to Pi-hole v6.0 format/ [i] Migrating config to Pi-hole v6.0 format/' | sed ' s/- 0 entries are forced through environment//'
188216
189- # Print a blank line for separation
190- echo " "
191217}
192218
193219setup_web_password () {
194220 if [ -z " ${FTLCONF_webserver_api_password+x} " ] && [ -n " ${WEBPASSWORD_FILE} " ] && [ -r " /run/secrets/${WEBPASSWORD_FILE} " ]; then
195- echo " [i] Setting FTLCONF_webserver_api_password from file"
221+ __log " INFO " " pihole-docker " " Setting FTLCONF_webserver_api_password from file"
196222 FTLCONF_webserver_api_password=$( < " /run/secrets/${WEBPASSWORD_FILE} " )
197223 export FTLCONF_webserver_api_password
198224 fi
@@ -201,13 +227,13 @@ setup_web_password() {
201227 if [ -z " ${FTLCONF_webserver_api_password+x} " ]; then
202228 # Is this already set to something other than blank (default) in FTL's config file? (maybe in a volume mount)
203229 if [[ $( pihole-FTL --config webserver.api.pwhash) ]]; then
204- echo " [i] Password already set in config file"
230+ __log " INFO " " pihole-docker " " Password already set in config file"
205231 return
206232 else
207233 # If we are here, the password is set in neither the environment nor the config file
208234 # We will generate a random password.
209235 RANDOMPASSWORD=$( tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
210- echo " [i] No password set in environment or config file, assigning random password: $RANDOMPASSWORD "
236+ __log " INFO " " pihole-docker " " No password set in environment or config file, assigning random password: $RANDOMPASSWORD "
211237
212238 # Explicitly turn off bash printing when working with secrets
213239 { set +x; } 2> /dev/null
@@ -221,15 +247,15 @@ setup_web_password() {
221247 fi
222248 fi
223249 else
224- echo " [i] Assigning password defined by Environment Variable"
250+ __log " INFO " " pihole-docker " " Assigning password defined by Environment Variable"
225251 fi
226252}
227253
228254fix_capabilities () {
229255 # Testing on Docker 20.10.14 with no caps set shows the following caps available to the container:
230256 # Current: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep
231257 # FTL can also use CAP_NET_ADMIN and CAP_SYS_NICE. If we try to set them when they haven't been explicitly enabled, FTL will not start. Test for them first:
232- echo " [i] Setting capabilities on pihole-FTL where possible"
258+ __log " INFO " " pihole-docker " " Setting capabilities on pihole-FTL where possible"
233259 capsh --has-p=cap_chown 2> /dev/null && CAP_STR+=' ,CAP_CHOWN'
234260 capsh --has-p=cap_net_bind_service 2> /dev/null && CAP_STR+=' ,CAP_NET_BIND_SERVICE'
235261 capsh --has-p=cap_net_raw 2> /dev/null && CAP_STR+=' ,CAP_NET_RAW'
@@ -239,30 +265,28 @@ fix_capabilities() {
239265
240266 if [[ ${CAP_STR} ]]; then
241267 # We have the (some of) the above caps available to us - apply them to pihole-FTL
242- echo " [i] Applying the following caps to pihole-FTL:"
243268 IFS=' ,' read -ra CAPS <<< " ${CAP_STR:1}"
244- for i in " ${CAPS[@]} " ; do
245- echo " * ${i} "
246- done
269+ # Build JSON array from capabilities
270+ CAPS_JSON= $( printf ' %s\n ' " ${CAPS[@]} " | jq -R . | jq -s ' {"applied_capabilities": .} ' )
271+ __log " INFO " " pihole-docker " " $CAPS_JSON "
247272
248273 setcap " ${CAP_STR: 1} " +ep " $( which pihole-FTL) " || ret=$?
249274
250275 if [[ $DHCP_READY == false ]] && [[ $FTLCONF_dhcp_active == true ]]; then
251276 # DHCP is requested but NET_ADMIN is not available.
252- echo " ERROR: DHCP requested but NET_ADMIN is not available. DHCP will not be started."
253- echo " Please add cap_net_admin to the container's capabilities or disable DHCP."
277+ __log " ERROR" " pihole-docker " " DHCP requested but NET_ADMIN is not available. DHCP will not be started."
278+ __log " INFO " " pihole-docker " " Please add cap_net_admin to the container's capabilities or disable DHCP."
254279 setFTLConfigValue dhcp.active false
255280 fi
256281
257282 if [[ $ret -ne 0 && " ${DNSMASQ_USER:- pihole} " != " root" ]]; then
258- echo " [!] ERROR: Unable to set capabilities for pihole-FTL. Cannot run as non-root."
259- echo " If you are seeing this error, please set the environment variable 'DNSMASQ_USER' to the value 'root'"
283+ __log " ERROR" " pihole-docker " " Unable to set capabilities for pihole-FTL. Cannot run as non-root."
284+ __log " ERROR " " pihole-docker " " If you are seeing this error, please set the environment variable 'DNSMASQ_USER' to the value 'root'"
260285 exit 1
261286 fi
262287 else
263- echo " [!] ERROR: Unable to set capabilities for pihole-FTL."
264- echo " Please ensure that the container has the required capabilities."
288+ __log " ERROR" " pihole-docker " " Unable to set capabilities for pihole-FTL."
289+ __log " ERROR " " pihole-docker " " Please ensure that the container has the required capabilities."
265290 exit 1
266291 fi
267- echo " "
268292}
0 commit comments