In raising this issue, I confirm the following: {please fill the checkboxes, e.g: [X]}
How familiar are you with the the source code relevant to this issue?:
0
Expected behaviour:
I should be able to install pihole.
Actual behaviour:
Pihole fails to install.
Steps to reproduce:
1) Install debian 10
2) Set a static IP
3) Install pihole on user root
Troubleshooting undertaken, and/or other relevant information:
root@pihole:/home/nicolas# ./pihole.sh
[✓] Root user check
.;;,.
.ccccc:,.
:cccclll:. ..,,
:ccccclll. ;ooodc
'ccll:;ll .oooodc
.;cll.;;looo:.
.. ','.
.',,,,,,'.
.',,,,,,,,,,.
.',,,,,,,,,,,,....
....''',,,,,,,'.......
......... .... .........
.......... ..........
.......... ..........
......... .... .........
........,,,,,,,'......
....',,,,,,,,,,,,.
.',,,,,,,,,'.
.',,,,,,'.
..'''.
[i] Existing PHP installation detected : PHP version 7.3.14-1~deb10u1
[✓] Disk space check
[✓] Update local cache of available packages
[✓] Checking apt-get for upgraded packages... up to date!
[i] Installer Dependency checks...
[✓] Checking for apt-utils
[✓] Checking for dialog
[✓] Checking for debconf
[✓] Checking for dhcpcd5
[✓] Checking for git
[✓] Checking for iproute2
[✓] Checking for whiptail
[i] Using Cloudflare
[i] Static IP already configured
[i] Unable to find IPv6 ULA/GUA address, IPv6 adblocking will not be enabled
[i] IPv4 address: 192.168.1.100/24
[i] IPv6 address:
[i] Web Interface On
[i] Web Server On
[i] Logging On.
[✓] Check for existing repository in /etc/.pihole
[✓] Update repo in /etc/.pihole
[✓] Check for existing repository in /var/www/html/admin
[✓] Update repo in /var/www/html/admin
[i] Main Dependency checks...
[✓] Checking for cron
[✓] Checking for curl
[✓] Checking for dnsutils
[✓] Checking for iputils-ping
[✓] Checking for lsof
[✓] Checking for netcat
[✓] Checking for psmisc
[✓] Checking for sudo
[✓] Checking for unzip
[✓] Checking for wget
[✓] Checking for idn2
[✓] Checking for sqlite3
[✓] Checking for libcap2-bin
[✓] Checking for dns-root-data
[✓] Checking for resolvconf
[✓] Checking for libcap2
[✓] Checking for lighttpd
[✓] Checking for php7.3-common
[✓] Checking for php7.3-cgi
[✓] Checking for php7.3-sqlite3
[✓] Enabling lighttpd service to start on reboot...
[i] Creating user 'pihole'..../pihole.sh: riga 1741: useradd: command not found
[✗] Creating user 'pihole'
[i] FTL Checks...
[✓] Detected x86_64 architecture
[i] Checking for existing FTL binary...
[i] Latest FTL Binary already installed (v4.3.1). Confirming Checksum...
[i] Checksum correct. No need to download!
[i] Creating user 'pihole'..../pihole.sh: row 1741: useradd: command not found
[✗] Creating user 'pihole'
./pihole.sh: row 1896: usermod: command not found
grep: /etc/pihole/setupVars.conf: File or directory not found
[i] Testing if systemd-resolved is enabled
[i] Systemd-resolved is not enabled
[✓] Restarting lighttpd service...
[✓] Enabling lighttpd service to start on reboot...
[i] Restarting services...
[✓] Enabling pihole-FTL service to start on reboot...
[✓] Restarting pihole-FTL service...
./pihole.sh: row 1724: /opt/pihole/gravity.sh: File or directory not found
useradd: command not found
That's a stock utility that should be installed as part of the Debian 10 base. Is this a VPS or a cut down image that is not the stock ISO from Debian?
Hi. Thank you for you response.
No, it is the debian 10.0.0 amd64-net installer.
Right now there is the 10.3.0 available if u wanna try download it and spin up a VM.
https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-10.3.0-amd64-netinst.iso
Note: i used the graphical installer, with SSH server and basic system utility selected as packages to be installed.
Can you run which useradd? And what is the path of the user you are installing as? Looks like you are using root, my guess is that the useradd utility is not in your path.
This is the $PATH:
root@pihole:/home/nicolas# echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
root@pihole:/home/nicolas# which useradd
simply returns no response
You were right. Doing "su" instead of "su -" didnt add the right directories to $PATH. Now the script works.
----- Suggestion:
Is there a check that could be implemented at the start of the script that checks for basic commands using which ?
So the script wont even start if it doesnt find all the basic commands that it needs. This has caused me some problems because it was editing /etc/resolv.conf and already applying "nameserver 127.0.0.1" without actually installing pihole, causing the server to loose DNS resolve.
Is there a check that could be implemented at the start of the script that checks for basic commands using which ?
The tools are there, as you've found. It's the path that is not fully completed. It gets to be an issue of how much "user assistance" we end up having to do. We could which useradd but that assumes that which is available. which which or type -a which and you can see how that ends up being turtles all the way down.
Yeah i get it.
Instead, we could specify that those are required commands in the readme installation / documentation (useful to know for those who run non-standard Linux distros) and to check the user $PATH before installing.
We had a very similar report once. I suggest to simply specify the PATH variable at the top of the script:
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
This is bash default.
The above could also be added to an existing PATH, to not override custom entries (being failsafe), but not sure if doubled entries could lead to any issues?
canceling the installation and telling the user to set his path variable correctly may helps to avoid subsequent problems and prevents some bug reports.
@Sunsheep
It is not too trivial what to check and what to tell the user. The installer simply calls a command which is present in 99.9% of the cases, and either exits or runs into an error if it is not present. It could check for every single external (non shell-internal) command it uses, but it could be missing for several reasons. It could check the PATH and compare with known defaults, but some systems by design might come with non-default binary locations, which not necessarily implies an issue at all. Also e.g. sudo resets the PATH, reverting to bash default, while su preserves the PATH of the current session, which might be limited for non-root users. We run into hell when attempting to check all this 😄.
Setting the PATH to a reasonable default is at least a method that I see quite often, hence that seems to work quite reliable.
@MichaIng Stupid question:
Wouldn't it be straightforward to make a query before calling system programs or third-party components, checking whether the call is possible and no error is returned?
In my case (#3345 ), the update from 4.x to 5.0 was still done without the error being apparent (only one line between the regular output of the installer). This resulted in the backend being installed, but the new database was not created. The error became obvious only by the missing statistics in the web-fronted.
@Sunsheep
Actually strange that the installer continued. It has the set -e flag and the usermod commands are not error handled, hence the installer should exit exactly when calling this command 🤔. Actually the expected behaviour would be also better here, so the user sees the error message as last output and knows where to start debugging. As said of course it could check the existence of every external command it calls and print an error message to exit with if it could not be found, but the coding effort is quite large, probably an error handler function would be a solution.
Actually there is an open pull request which implements such an error handler with very nice stack trace, beautiful for debugging, but you see the amount of code lines and the additional complexity it adds: #2288
Lots of installers go to the trouble of checking assertions and dependencies before scribbling on system files. I think that's just basic politeness these days.
As such, I suggest that while it's not trivial to add, having the installer do a pre-check that includes validating that it can find all of the relevant commands it will need is also not all that difficult and should be treated as a solvable problem rather than being dismissed out of hand.
As to what to tell the user, lots of installers simply say something like this:
checking for useradd... NOT FOUND!! -- Either useradd is not present on your system or not in your PATH.
This not mutually exclusive with first adding reasonable defaults to the PATH environment variable within the script if that is deemed desirable. I suggest adding them at the end of the existing PATH variable so as to avoid conflicting with any intended local overrides. Duplication of directories within the PATH variable can cause suboptimal performance as a directory not containing a command may be searched multiple times, but that's pretty much the worst of it, and with modern caching, that is a pretty low penalty.
As always, PRs are happily accepted for this free open source project.
I never saw an installer/script which checks for such basic commands like usermod, which is part of very essential core packages like passwd on Debian, which is required for any UNIX user management. And there is exactly this error message 😃:
useradd: command not found
Before adding a lot of code to check for such basic commands, which would even not fix the installer failure in OP case, I suggest to set PATH to the default that matches as well what one gets when using sudo.
PR up: #3527
As I said, not mutually exclusive with setting PATH. I've see installers that check for awk, chmod, chown, grep, sed, etc. I'd consider all of those pretty basic core tools much moreso than useradd.
Further, the difficulty would be identifying all of the dependencies. Once you have the dependency list, checking for them is pretty straight forward (Uncomment the commented lines for verbose output):
MISSINGDEPENDENCY=0;
for f in $DEPENDENCIES; do
# echo -n "Checking for $f: "
$LOCATION = `which $f >/dev/null 2>&1`
if [ $? ne 0 ]; then
echo "Error: $f not found in path ($PATH)" >&2
MISSINGDEPENDENCY = `expr $MISSINGDEPENDENCY + 1`
elif [ ~ -x $LOCATION ]; then
echo "$LOCATION found for $f but not executable." >&2
MISSINGDEPENDENCY = `expr $MISSINGDEPENDENCY + 1`
else
# echo $LOCATION
fi
done
if [ $MISSINGDEPENDENCY ne 0 ]; then
echo "Installer failed due to $MISSINGDEPENDENCY missing dependencies." >&2
exit 1
fi
I suppose if you wanted to get fancy, a couple more lines could be required to use the correct singular or plural form of "dependency" at the end.
The problem is that the command exists, so a dependency check will find it. It's just not in the PATH when you do use su or another user with a path that is missing the bin directories.
An output of "useradd missing" and then exit 1 would be incorrect. Users would find useradd since it's actually there and still complain.
On Jul 2, 2020, at 16:37 , Dan Schaper notifications@github.com wrote:
The problem is that the command exists, so a dependency check will find it. It's just not in the PATH when you do use su or another user with a path that is missing the bin directories.
An output of "useradd missing" and then exit 1 would be incorrect. Users would find useradd since it's actually there and still complain.
Presumably the installer is run after you su or whatever, so I would expect the environment in the beginning of the installer where I would put the dependency check to be identical
to the environment where it’s executing the program in question.
Right, and when we tell users to fix this by running apt install useradd and that fails because the package exists, and they further run useradd at the terminal and it succeeds then the response is "The installer is broken, useradd is there." And that's correct, useradd is there.
Do we add useradd as a dependency to check for? Do we then add which since that's the command used to find the binaries, and echo because that's used to output the results of which looking for useradd...
I would add which. echo is a shell builtin, so if the installer is executing in th shell, I think it’s safe to take it as a given.
As to user experience… We shouldn’t be telling the user to install it. We should be telling them “dependency X wasn’t found in your path (Y)”
(See error messages in example code provided earlier in ticket).
In this way, we have given the user a 100% accurate error message that tells them exactly what was discovered. They can troubleshoot further.
Yeah, that's not going to work, we don't just cut users off and tell them to go fix it themselves. Spend more than 3 minutes on Discourse and read the support topics, read through the issues and help requests here, see some of our other support offerings. We actually know our userbase.
I would add which.
And how do we check for that? which which? (We covered this earlier in this thread, have a look at https://github.com/pi-hole/pi-hole/issues/3209#issuecomment-598540453)
which sh would work…
It will return $? == 127 for which not being found and $? == 1 for sh not found.
Since the installer wouldn’t be executing at all without sh, this should be pretty safe.
I wasn’t suggesting that you abandon your user base and refuse to support them further with the error message. I was suggesting that the vast majority
of users should be able to examine their PATH (displayed in the error message) and identify the missing directory.
Owen
command -v which
But instead of which use command -v which is a shell built-in and much closer to what the shell itself does on command call.
That works if bash is considered a dependency. If you intend to run on any systems with an honest to god bourne shell implementation
(does such a thing still exist?), this won’t work.
On Jul 2, 2020, at 17:03 , MichaIng notifications@github.com wrote:
command -v which
But instead of which use command -v which is a shell built-in and much closer to what the shell itself does on command call.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub https://github.com/pi-hole/pi-hole/issues/3209#issuecomment-653266348, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAK6GTUXV3ONWHCJ5XGH4L3RZUN4XANCNFSM4LGWD5HQ.
Pi-hole scripts are all bash, see shebang and syntax and how the installer is expected to be called. They are not bourne shell compatible.
I guess the point that I'm unsuccessfully trying to get across is that while there is a technically correct way to know that useradd is not in the path the real issue is that information doesn't mean anything. We still have to walk users through how to solve this. And the solution is "Don't run with su."
I'm going to close this issue since this topic is moving far from the original topic. Pi-hole does install on Debian 10 without issue.
It would still be better if the installer didn’t scribble on system files like /etc/resolv.conf _BEFORE_ it figured this out and quit.
On Jul 2, 2020, at 17:17 , Dan Schaper notifications@github.com wrote:
I guess the point that I'm unsuccessfully trying to get across is that while there is a technically correct way to know that useradd is not in the path the real issue is that information doesn't mean anything. We still have to walk users through how to solve this. And the solution is "Don't run with su."
I'm going to close this issue since this topic is moving far from the original topic. Pi-hole does install on Debian 10 without issue.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub https://github.com/pi-hole/pi-hole/issues/3209#issuecomment-653269339, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAK6GTX7RPOY4YYLLAV2Z6TRZUPR5ANCNFSM4LGWD5HQ.
It doesn't.
Pi-hole V5 makes no changes to /etc/resolv.conf.
IMO there are two kind of commands that simply need to be expected as present:
All other required commands/packages are AFAIK separately installed as installer deps or Pi-hole deps already.
There is an argument to exit the installer before starting with any actual install steps, however IF this is really wanted, I don't see a point in doing all which/command -v checks and printing some custom message over what bash already prints. So then one could print one line to say that command existence checks are done and then loop through them and do something like
echo '[i] We are checking for required basic commands now:'
doomedtofail -h > /dev/null || exit 1
bash: doomedtofail: command not found
which gives the same info but easier (?) compared to https://github.com/pi-hole/pi-hole/issues/3209#issuecomment-653260218 if I didn't oversee something?
But as stated by dschaper this does not fix anything but inexperienced user would still open a bug report while experienced users do already see the same error message in the output now and will be able to fix it.
I am not aware of any case where those critical/essential system commands were really missing, but only this (and saw in forum as well) where PATH was wrong due to su. So to really help/prevent users from running into this, especially since there is no way to control how (su/sudo/root) the user calls the script, is assuring that all default executable locations are in PATH: https://github.com/pi-hole/pi-hole/pull/3527
But since this case is now known to all team members and to look for su as culprit, probably it is even good to have users running into this and teach them that way to use sudo instead 😜.
Only alternative I can think of would be to call those non-builtin commands with sudo to assure a clean PATH per-call 🙄.
The originating issue will be fixed with next version: #3527
This implies all cases where due to (non-recommended) su usage a limited PATH is passed to the installer environment.
Most helpful comment
canceling the installation and telling the user to set his path variable correctly may helps to avoid subsequent problems and prevents some bug reports.