BloodHound.py
BloodHound.py copied to clipboard
cohabitation of bloodhound-ce-python with bloodhound-python
As bloodhound-ce-python and bloodhound-python targets different softwares (BH v5 and BH v4), it is useful to have both installed at the same time.
However, from the package structure, files deployed conflicts prevent to get both installed simultaneously. Changing the 2 following lines by adding the -ce suffix in setup.py is not enough.
https://github.com/dirkjanm/BloodHound.py/blob/3def775fd2df9a4eefe916f42f41440d51e89279/setup.py#L3 https://github.com/dirkjanm/BloodHound.py/blob/3def775fd2df9a4eefe916f42f41440d51e89279/setup.py#L28
The conflict happens under usr/lib/python3.13/site-packages/bloodhound/*, the CE version should propably be deployed under usr/lib/python3.13/sote-packages/bloodhound-ce/* instead.
All those files are conflicting:
➜ comm -1 -2 <(tar tvf packages/bloodhound-python/bloodhound-python-v1.0.1.r163.g44bd5c2-1-any.pkg.tar.zst | awk '{print $6}' | sort ) <(tar tvf packages/bloodhound-python-ce/bloodhound-python-ce-v1.0.1.r182.g3def775-1-any.pkg.tar.zst | awk '{print $6}' | sort )
[…]
usr/lib/python3.13/site-packages/bloodhound/
usr/lib/python3.13/site-packages/bloodhound/ad/
usr/lib/python3.13/site-packages/bloodhound/ad/authentication.py
usr/lib/python3.13/site-packages/bloodhound/ad/computer.py
usr/lib/python3.13/site-packages/bloodhound/ad/domain.py
usr/lib/python3.13/site-packages/bloodhound/ad/dumpntlm.py
usr/lib/python3.13/site-packages/bloodhound/ad/__init__.py
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/authentication.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/authentication.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/computer.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/computer.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/domain.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/domain.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/dumpntlm.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/dumpntlm.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/__init__.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/__init__.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/structures.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/structures.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/trusts.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/trusts.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/utils.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/utils.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/structures.py
usr/lib/python3.13/site-packages/bloodhound/ad/trusts.py
usr/lib/python3.13/site-packages/bloodhound/ad/utils.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/
usr/lib/python3.13/site-packages/bloodhound/enumeration/acls.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/computers.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/domains.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/__init__.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/memberships.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/objectresolver.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/outputworker.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/acls.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/acls.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/computers.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/computers.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/domains.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/domains.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/__init__.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/__init__.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/memberships.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/memberships.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/objectresolver.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/objectresolver.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/outputworker.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/outputworker.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/__init__.py
usr/lib/python3.13/site-packages/bloodhound/lib/
usr/lib/python3.13/site-packages/bloodhound/lib/cstruct.py
usr/lib/python3.13/site-packages/bloodhound/lib/__init__.py
usr/lib/python3.13/site-packages/bloodhound/lib/__pycache__/
usr/lib/python3.13/site-packages/bloodhound/lib/__pycache__/cstruct.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/lib/__pycache__/cstruct.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/lib/__pycache__/__init__.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/lib/__pycache__/__init__.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/__main__.py
usr/lib/python3.13/site-packages/bloodhound/__pycache__/
usr/lib/python3.13/site-packages/bloodhound/__pycache__/__init__.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/__pycache__/__init__.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/__pycache__/__main__.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/__pycache__/__main__.cpython-313.pyc
[…]
As a workaround patch, I used what is probably the easiest way: rename the source folder to and all imports to bloodhound_ce.
Here's my package patch:
prepare() {
cd "$_pkgname"
# prevent conflicts with bloodhound-python package
mv bloodhound/ bloodhound_ce/
sed -i -E "s/'(bloodhound)(|\..+)'/'\1_ce\2'/g" setup.py # for the 4 packages=[] lines
sed -i "s/=bloodhound:/=bloodhound_ce:/g" setup.py # for the console_scripts line
# rename all import
find bloodhound_ce/ -type f -name '*.py' -exec sed -i 's/import bloodhound/import bloodhound_ce/g' {} \+ \
-exec sed -i 's/from bloodhound/from bloodhound_ce/g' {} \+
}
I found no way to just rename the folder and play with package_dir that doesn't imply to change the imports AND that change the name deployed under site-package.
hey Noraj, thanks for creating an issue on this. I am aware of the (big) drawback that the current structure has. The reason for keeping the same namespace is mostly for maintenance reasons. I maintain the legacy version and the CE version as separate branches, and merge bugfixes from the master branch into the CE branch. Moving the CE source into its own namespace means renaming the directories and imports like your script does. I'm afraid this would either break or hugely complicate the maintenance of the two versions simultaneously.
As a result there are currently a few options that do not break if you want to have both tools:
- Have both in a separate manually managed virtual environment
- Use a package manager like pipx which automatically isolates different tools in their own venvs
And you just added a third way, which is changing the naming convention at build time. I'll have to think about whether this is something that I'll also add in my own build process for pypi since it would make things easier to install for users. Permanently changing the package name in the source repository is not an option for the moment, maybe that would change when support for the legacy version is fully dropped.