@@ -28,102 +28,130 @@ 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 /usr/sbin/crond
93- echo " "
94124}
95125
96126install_logrotate () {
97127 # Install the logrotate config file - this is done already in Dockerfile
98128 # but if a user has mounted a volume over /etc/pihole, it will have been lost
99129 # pihole-FTL-prestart.sh will set the ownership of the file to root:root
100- echo " [i] Ensuring logrotate script exists in /etc/pihole"
130+ __log " INFO " " pihole-docker " " Ensuring logrotate script exists in /etc/pihole"
101131 install -Dm644 -t /etc/pihole /etc/.pihole/advanced/Templates/logrotate
102- echo " "
103132}
104133
105134migrate_gravity () {
106- echo " [i] Gravity migration checks"
135+ __log " INFO " " pihole-docker " " Gravity migration checks"
107136 gravityDBfile=$( getFTLConfigValue files.gravity)
108137
109138 if [[ ! -f /etc/pihole/adlists.list ]]; then
110- echo " [i] No adlist file found, creating one with a default blocklist"
139+ __log " INFO " " pihole-docker " " No adlist file found, creating one with a default blocklist"
111140 echo " https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" > /etc/pihole/adlists.list
112141 fi
113142
114143 if [ ! -f " ${gravityDBfile} " ]; then
115- echo " [i] ${gravityDBfile} does not exist (Likely due to a fresh volume). This is a required file for Pi-hole to operate."
116- echo " [i] Gravity will now be run to create the database"
144+ __log " INFO " " pihole-docker " " ${gravityDBfile} does not exist (Likely due to a fresh volume). This is a required file for Pi-hole to operate."
145+ __log " INFO " " pihole-docker " " Gravity will now be run to create the database"
117146 pihole -g
118147 else
119- echo " [i] Existing gravity database found - schema will be upgraded if necessary"
148+ __log " INFO " " pihole-docker " " Existing gravity database found - schema will be upgraded if necessary"
120149 # source the migration script and run the upgrade function
121150 source /etc/.pihole/advanced/Scripts/database_migration/gravity-db.sh
122151 local upgradeOutput
123152 upgradeOutput=$( upgrade_gravityDB " ${gravityDBfile} " " /etc/pihole" )
124- printf " %b " " ${upgradeOutput} \\ n " | sed ' s/^/ / '
153+ __log " INFO " " pihole-docker " " Gravity DB migration output: ${upgradeOutput} "
125154 fi
126- echo " "
127155}
128156
129157# shellcheck disable=SC2034
@@ -142,7 +170,7 @@ ftl_config() {
142170
143171 # If getFTLConfigValue "dns.upstreams" returns [], default to Google's DNS server
144172 if [[ $( getFTLConfigValue " dns.upstreams" ) == " []" ]]; then
145- echo " [i] No DNS upstream set in environment or config file, defaulting to Google DNS"
173+ __log " INFO " " pihole-docker " " No DNS upstream set in environment or config file, defaulting to Google DNS"
146174 setFTLConfigValue " dns.upstreams" " [\" 8.8.8.8\" , \" 8.8.4.4\" ]"
147175 fi
148176
@@ -154,7 +182,7 @@ migrate_v5_configs() {
154182 # During migration, their content is copied into the new single source of
155183 # truth file /etc/pihole/pihole.toml and the old files are moved away to
156184 # avoid conflicts with other services on this system
157- echo " [i] Migrating dnsmasq configuration files"
185+ __log " INFO " " pihole-docker " " Migrating dnsmasq configuration files"
158186 V6_CONF_MIGRATION_DIR=" /etc/pihole/migration_backup_v6"
159187 # Create target directory and make it owned by pihole:pihole
160188 mkdir -p " ${V6_CONF_MIGRATION_DIR} "
@@ -169,7 +197,6 @@ migrate_v5_configs() {
169197
170198 mv /etc/dnsmasq.d/0{1,2,4,5}-pihole* .conf " ${V6_CONF_MIGRATION_DIR} /" 2> /dev/null || true
171199 mv /etc/dnsmasq.d/06-rfc6761.conf " ${V6_CONF_MIGRATION_DIR} /" 2> /dev/null || true
172- echo " "
173200
174201 # Finally, after everything is in place, we can create the new config file
175202 # /etc/pihole/pihole.toml
@@ -184,27 +211,25 @@ migrate_v5_configs() {
184211 # We suppress the message about environment variables as these will be set on FTL's first real start
185212 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//'
186213
187- # Print a blank line for separation
188- echo " "
189214}
190215
191216setup_web_password () {
192217 if [ -z " ${FTLCONF_webserver_api_password+x} " ] && [ -n " ${WEBPASSWORD_FILE} " ] && [ -r " /run/secrets/${WEBPASSWORD_FILE} " ]; then
193- echo " [i] Setting FTLCONF_webserver_api_password from file"
218+ __log " INFO " " pihole-docker " " Setting FTLCONF_webserver_api_password from file"
194219 export FTLCONF_webserver_api_password=$( < " /run/secrets/${WEBPASSWORD_FILE} " )
195220 fi
196221
197222 # If FTLCONF_webserver_api_password is not set
198223 if [ -z " ${FTLCONF_webserver_api_password+x} " ]; then
199224 # Is this already set to something other than blank (default) in FTL's config file? (maybe in a volume mount)
200225 if [[ $( pihole-FTL --config webserver.api.pwhash) ]]; then
201- echo " [i] Password already set in config file"
226+ __log " INFO " " pihole-docker " " Password already set in config file"
202227 return
203228 else
204229 # If we are here, the password is set in neither the environment nor the config file
205230 # We will generate a random password.
206231 RANDOMPASSWORD=$( tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
207- echo " [i] No password set in environment or config file, assigning random password: $RANDOMPASSWORD "
232+ __log " INFO " " pihole-docker " " No password set in environment or config file, assigning random password: $RANDOMPASSWORD "
208233
209234 # Explicitly turn off bash printing when working with secrets
210235 { set +x; } 2> /dev/null
@@ -218,15 +243,15 @@ setup_web_password() {
218243 fi
219244 fi
220245 else
221- echo " [i] Assigning password defined by Environment Variable"
246+ __log " INFO " " pihole-docker " " Assigning password defined by Environment Variable"
222247 fi
223248}
224249
225250fix_capabilities () {
226251 # Testing on Docker 20.10.14 with no caps set shows the following caps available to the container:
227252 # 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
228253 # 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:
229- echo " [i] Setting capabilities on pihole-FTL where possible"
254+ __log " INFO " " pihole-docker " " Setting capabilities on pihole-FTL where possible"
230255 capsh --has-p=cap_chown 2> /dev/null && CAP_STR+=' ,CAP_CHOWN'
231256 capsh --has-p=cap_net_bind_service 2> /dev/null && CAP_STR+=' ,CAP_NET_BIND_SERVICE'
232257 capsh --has-p=cap_net_raw 2> /dev/null && CAP_STR+=' ,CAP_NET_RAW'
@@ -236,30 +261,28 @@ fix_capabilities() {
236261
237262 if [[ ${CAP_STR} ]]; then
238263 # We have the (some of) the above caps available to us - apply them to pihole-FTL
239- echo " [i] Applying the following caps to pihole-FTL:"
240264 IFS=' ,' read -ra CAPS <<< " ${CAP_STR:1}"
241- for i in " ${CAPS[@]} " ; do
242- echo " * ${i} "
243- done
265+ # Build JSON array from capabilities
266+ CAPS_JSON= $( printf ' %s\n ' " ${CAPS[@]} " | jq -R . | jq -s ' {"applied_capabilities": .} ' )
267+ __log " INFO " " pihole-docker " " $CAPS_JSON "
244268
245269 setcap " ${CAP_STR: 1} " +ep " $( which pihole-FTL) " || ret=$?
246270
247271 if [[ $DHCP_READY == false ]] && [[ $FTLCONF_dhcp_active == true ]]; then
248272 # DHCP is requested but NET_ADMIN is not available.
249- echo " ERROR: DHCP requested but NET_ADMIN is not available. DHCP will not be started."
250- echo " Please add cap_net_admin to the container's capabilities or disable DHCP."
273+ __log " ERROR" " pihole-docker " " DHCP requested but NET_ADMIN is not available. DHCP will not be started."
274+ __log " INFO " " pihole-docker " " Please add cap_net_admin to the container's capabilities or disable DHCP."
251275 setFTLConfigValue dhcp.active false
252276 fi
253277
254278 if [[ $ret -ne 0 && " ${DNSMASQ_USER:- pihole} " != " root" ]]; then
255- echo " [!] ERROR: Unable to set capabilities for pihole-FTL. Cannot run as non-root."
256- echo " If you are seeing this error, please set the environment variable 'DNSMASQ_USER' to the value 'root'"
279+ __log " ERROR" " pihole-docker " " Unable to set capabilities for pihole-FTL. Cannot run as non-root."
280+ __log " ERROR " " pihole-docker " " If you are seeing this error, please set the environment variable 'DNSMASQ_USER' to the value 'root'"
257281 exit 1
258282 fi
259283 else
260- echo " [!] ERROR: Unable to set capabilities for pihole-FTL."
261- echo " Please ensure that the container has the required capabilities."
284+ __log " ERROR" " pihole-docker " " Unable to set capabilities for pihole-FTL."
285+ __log " ERROR " " pihole-docker " " Please ensure that the container has the required capabilities."
262286 exit 1
263287 fi
264- echo " "
265288}
0 commit comments