Open uncomfyhalomacro opened 1 year ago
Thanks @uncomfyhalomacro This is indeed a possible improvement, it has been brought up before, but hadn't the time/will to look into it
Open to suggestions :)
This should be quite straightforward to be done. We can source the file with . /etc/os-release
, then we have access to the variables declared there. ID
seems like a nice prospect because its short and lower case. ID_LIKE
looks interesting too, for example if all Debian based distros define it as debian
- like Ubuntu does -, that would make our lives easier.
Then we can use case
to choose the right package manager:
case "${ID_LIKE}" in
debian) package_manager=apt ;;
...
esac
The tough part is researching /etc/os-release
of the countless distros around, perhaps the community is willing to give a hand with that.
If no one takes a stab at this, in my next round of distrobox contributions I could add this task to my Todo list.
Yea the fact that we can simply source it is really nice
We need more info about which thing we can use to just infere the pkg manager
Latest batch of commits to init
now allows for more flexibility in packages, they are checked before installed, this allows to declare a dependency that is called differently between 2 OSes with the same package manager (see maybe ubuntu 23 vs debian 8)
The only thing that we might lose (i'm just guessing) is the ability to "just try and see if it works" Like now you just have to have a supported pkg manager With this other approach you need a supported distribution name, which is not a given sometimes
Here is a list of all the os-release in all the different distros in the compatibility list
os-release-ubi.txt os-release-sl-7.txt os-release-beige.txt os-release-mageia.txt os-release-toolbox.txt os-release-apricot.txt os-release-ubi-init.txt os-release-centos-7.txt os-release-8-init-8.txt os-release-8-base-8.txt os-release-fedora-39.txt os-release-fedora-38.txt os-release-fedora-37.txt os-release-fedora-36.txt os-release-debian-10.txt os-release-eol-wheezy.txt os-release-ubi-minimal.txt os-release-leap-latest.txt os-release-alpine-3-16.txt os-release-alpine-3-15.txt os-release-almalinux-9.txt os-release-almalinux-8.txt os-release-ubuntu-22-04.txt os-release-ubuntu-20-04.txt os-release-ubuntu-18-04.txt os-release-ubuntu-16-04.txt os-release-ubuntu-14-04.txt os-release-rockylinux-9.txt os-release-rockylinux-8.txt os-release-stage3-latest.txt os-release-oraclelinux-9.txt os-release-oraclelinux-8.txt os-release-oraclelinux-7.txt os-release-docker-latest.txt os-release-debian-stable.txt os-release-amazonlinux-2.txt os-release-amazonlinux-1.txt os-release-alpine-latest.txt os-release-toolbox-latest.txt os-release-slackware-14-2.txt os-release-debian-testing.txt os-release-centos-stream9.txt os-release-centos-stream8.txt os-release-debian-unstable.txt os-release-clearlinux-base.txt os-release-distrobox-latest.txt os-release-archlinux-latest.txt os-release-wolfi-base-latest.txt os-release-tumbleweed-latest.txt os-release-rockylinux-latest.txt os-release-neurodebian-nd100.txt os-release-fedora-toolbox-39.txt os-release-fedora-toolbox-38.txt os-release-fedora-toolbox-37.txt os-release-debian-toolbox-11.txt os-release-debian-toolbox-10.txt os-release-clearlinux-latest.txt os-release-archlinux-toolbox.txt os-release-oraclelinux-9-slim.txt os-release-oraclelinux-8-slim.txt os-release-oraclelinux-7-slim.txt os-release-kali-rolling-latest.txt os-release-alpine-toolbox-edge.txt os-release-alpine-toolbox-3-17.txt os-release-alpine-toolbox-3-16.txt os-release-almalinux-toolbox-9.txt os-release-almalinux-toolbox-8.txt os-release-almalinux-9-minimal.txt os-release-ubuntu-toolbox-22-04.txt os-release-ubuntu-toolbox-20-04.txt os-release-ubuntu-toolbox-18-04.txt os-release-ubuntu-toolbox-16-04.txt os-release-rockylinux-toolbox-9.txt os-release-rockylinux-toolbox-8.txt os-release-rockylinux-8-minimal.txt os-release-debian-toolbox-testing.txt os-release-centos-toolbox-stream9.txt os-release-centos-toolbox-stream8.txt os-release-opensuse-toolbox-latest.txt os-release-debian-toolbox-unstable.txt os-release-debian-stable-backports.txt os-release-debian-testing-backports.txt os-release-void-linux-latest-full-x86_64.txt os-release-amazonlinux-2022-0-20220531-0.txt os-release-void-linux-latest-full-x86_64-musl.txt
Yeah, we need to have a closer looking to see if there's really a pattern we can rely on rather than going with distroA|distroD|distroH|distroL|distroO) if command -v foo; then package_manager=foo; fi
.
The only thing that we might lose (i'm just guessing) is the ability to "just try and see if it works" Like now you just have to have a supported pkg manager With this other approach you need a supported distribution name, which is not a given sometimes
Yeah, I see the lines of code increasing a bit with this proposed approach. The "try and see" approach should work most of the time, because most of the time distros only have package manager. And if there's only one package, most likely there's only one canonical way of updating the system.
However, there could be corner cases where things could end up not so pretty, with the current approach. The more people use distrobox the more likely such a thing could happen.
Yeah, we need to have a closer looking to see if there's really a pattern we can rely on rather than going with distroA|distroD|distroH|distroL|distroO) if command -v foo; then package_manager=foo; fi.
Yea that's what I fear :/ (and definitely won't do)
And if there's only one package, most likely there's only one canonical way of updating the system.
However, there could be corner cases where things could end up not so pretty, with the current approach. The more people use distrobox the more likely such a thing could happen.
This in fact can be a problem if/when openSUSE migrates to dnf but maybe doing a mixed approach can be useful like:
if command -v package_manager; then
> we get from os-release the distro
> package_manager install list of packages for detected distro
> else we install the package list for the most associated distro (dnf-fedora/rh, apt-debian etc etc)
so we just add a little logic to the present approach this way
To be honest, I don't see openSUSE switching to DNF as its default package manager.
However, I had the same thought about some cases needing a mixed approach. I'm gonna think this over when I get some time to spare.
Thanks for the help!
To be honest, I don't see openSUSE switching to DNF as its default package manager.
However, I had the same thought about some cases needing a mixed approach. I'm gonna think this over when I get some time to spare.
Hey @luc14n0, did you manage to think about the issue?
I made a script to evaluate what fields can be used based on these samples. My experience with enterprise distros would suggest using CPE, which is guaranteed to be unique. However, I see that quite a few (40 out of 84 to be exact) do not have that field.
Also:
So, my proposal would be to use NAME to simplify things.
Further analyzing, we have 25 unique NAME tags:
erico@suselab-erico:~/Projetos/distrobox> egrep "NAME" summary.txt | sort | uniq
--> NAME=[AlmaLinux]
--> NAME=[Alpine Linux]
--> NAME=[Amazon Linux]
--> NAME=[Amazon Linux AMI]
--> NAME=[Arch Linux]
--> NAME=[CentOS Linux]
--> NAME=[CentOS Stream]
--> NAME=[Clear Linux OS]
--> NAME=[Crystal Linux]
--> NAME=[Debian GNU/Linux]
--> NAME=[Deepin]
--> NAME=[Fedora Linux]
--> NAME=[Gentoo]
--> NAME=[Kali GNU/Linux]
--> NAME=[Mageia]
--> NAME=[openSUSE Leap]
--> NAME=[openSUSE Tumbleweed]
--> NAME=[Oracle Linux Server]
--> NAME=[Red Hat Enterprise Linux]
--> NAME=[Rocky Linux]
--> NAME=[Scientific Linux]
--> NAME=[Slackware]
--> NAME=[Ubuntu]
--> NAME=[Void]
--> NAME=[Wolfi]
So, I guess we'd only need a "case" for these items only to define the corresponding package manager.
So, it would boil down to something like this:
#!/bin/bash
DISTRO_NAME=$(egrep "^NAME=.*" ${1}| cut -d\= -f2-)
if [[ ${DISTRO_NAME} =~ "Ubuntu" ]] || [[ ${DISTRO_NAME} =~ "Debian" ]]; then
echo "we should use apt-get!"
elif [[ ${DISTRO_NAME} =~ "Red Hat" ]] || [[ ${DISTRO_NAME} =~ "Oracle Linux" ]] || [[ ${DISTRO_NAME} =~ "CentOS" ]] || [[ ${DISTRO_NAME} =~ "AlmaLinux" ]]; then
echo "we should use dnf!"
elif [[ ${DISTRO_NAME} =~ "Arch" ]]; then
echo "we should use pacman!"
elif [[ ${DISTRO_NAME} =~ "SUSE" ]]; then
echo "we should use zypper!"
else
echo "I don't know! ¯\_(ツ)_/¯ "
fi
Testing:
erico@suselab-erico:~/Projetos/distrobox> ./guess_packager.sh samples/os-release-archlinux-latest.txt
we should use pacman!
erico@suselab-erico:~/Projetos/distrobox> ./guess_packager.sh samples/os-release-almalinux-9-minimal.txt
we should use dnf!
erico@suselab-erico:~/Projetos/distrobox> ./guess_packager.sh samples/os-release-centos-7.txt
we should use dnf!
erico@suselab-erico:~/Projetos/distrobox> ./guess_packager.sh samples/os-release-debian-stable.txt
we should use apt-get!
erico@suselab-erico:~/Projetos/distrobox> ./guess_packager.sh samples/os-release-ubuntu-14-04.txt
we should use apt-get!
erico@suselab-erico:~/Projetos/distrobox> ./guess_packager.sh samples/os-release-opensuse-toolbox-latest.txt
we should use zypper!
erico@suselab-erico:~/Projetos/distrobox> ./guess_packager.sh samples/os-release-wolfi-base-latest.txt
I don't know! ¯\_(ツ)_/¯
And of course, if there are exceptions, like suppose there 4 versions of CentOS and one of them doesn't support DNF... test the other fields, preferrably PRETTY_NAME and then VERSION, if it exists.
Checkihg the distrobox-upgrade script, where the checks if a package manager is installed, we could just call a function, like the one that @doccaz did, and then compare which package returned, instead of checking which package manager is installed. What do you think @89luca89 ?
Yeah my suggestion seems flaky after I read all suggestions here, especially from @doccaz
Thanks for thinking about this!
Only problem I see is supporting unknown distros
For example, wolfi
vs alpine
, both use apk
but different /etc/os-release
The proposed solution would make it "hardcoded" which family of distros we support, Not that this is wrong, but it's a paradigm shift that should be thought about
Thanks for thinking about this!
Only problem I see is supporting unknown distros
For example,
wolfi
vsalpine
, both useapk
but different /etc/os-releaseThe proposed solution would make it "hardcoded" which family of distros we support, Not that this is wrong, but it's a paradigm shift that should be thought about
In this case, you could resort to the other available fields, like PRETTY_NAME or VERSION, as I mentioned.
Thanks for thinking about this! Only problem I see is supporting unknown distros For example,
wolfi
vsalpine
, both useapk
but different /etc/os-release The proposed solution would make it "hardcoded" which family of distros we support, Not that this is wrong, but it's a paradigm shift that should be thought aboutIn this case, you could resort to the other available fields, like PRETTY_NAME or VERSION, as I mentioned.
That doesn't always work
Another thing would maybe do a pkg manager detection fallback
1 - ID 2 - NAME 3 - PRETTY_NAME 4 - we fallback to pkg manager detection like now
That doesn't always work
Another thing would maybe do a pkg manager detection fallback
1 - ID 2 - NAME 3 - PRETTY_NAME 4 - we fallback to pkg manager detection like now
Exactly. If everything else fails, test for the package manager binaries.
Im late to the discussion but this may be worth doing until proper solution is in place? Basically order package managers by niche-ness(?)
For example on openSUSE, if zypper is checked first then it will not look for dnf so quick order i thought of This still cannot deal with idk installing pacman on ubuntu but does it really have to handle that?
swupd
xbps-install
apk
emerge
slackpkg
pacman
zypper # must be before dnf because openSUSE
dnf
microdnf # dnf should probably be preferred
yum # must be after dnf
apt-get
Looking forward to your thoughts
mmh this would be a little stopgap, but that would do some damage on an opensuse with both dnf and zypper installed (I guess?? I do not know if installing dnf removes zypper and vice versa :man_shrugging: )
I believe that we can have both, as there are some packages that install dnf, IIRC. But either way, for such a tool like distrobox, I believe that preferring zypper is safe. I never saw anyone using dnf on openSUSE as by default zypper is the package manager.
According to opensuse wiki dnf is in the repos but also it is never mentioned that it is unsupported only thing i could find is the following
Specific functionality that is enabled by default with zypper can not be reproduced using DNF without the additional installation of plugins. Functionality such as "protected" packages and snapper integration require the use of plugins.
I do not know if installing dnf removes zypper and vice versa 🤷♂️
No, dnf is available to install but zypper is kept, i do not know if zypper can be uninstalled but would that really be something distrobox need to care about if zypper works and is the default?
EDIT: Also on archlinux you can install apt and dnf but i do not think we should care for such cases
IMHO, distrobox should first respect the default package manager for a distro. After this is done, well, some corner cases could be handled. (And yes, I understand that's kind of messed up to have two package managers, but what do I know?).
Detecting which package manager is available through
command
can be faulty. For example, I haveosc
installed in my system before and tried outdistrobox
-osc
also pullsdnf
as part of the recommends (?). And because of that this may have mess up mydistrobox
install causing it to look for dnf even after I removed it - related issue #706 .Wouldn't it be better to use
/etc/os-release
or/etc/lsb_release
to check which distro someone has at first and use the default package manager then usecommand
as a fallback later?Errata:
osc
does not havednf
installed as part of recommends. But I do believe it might be someobs-service-*
package that has dnf as part of its recommends since I used to runosc
on the host with those plugins.PS: This could be a good discussion to look out for. Not a high priority to be honest since all of us are busy with our lives at this moment.
CC: @luc14n0 @89luca89