Handling transition from python3-docker-compose v1 to docker-compose v2
TL;DR: Which package should get Obsoletes and Requires? Hi all, I have packaged the latest updates for the python-based python-docker-compose as well as the newer v2 that is written in golang. https://build.opensuse.org/request/show/986041 https://build.opensuse.org/request/show/986039 I also prepared the docker-compose-switch package that upstream created to ease the transition from v1 to v2, as the latter is only a cli-plugin for docker and does not longer have a docker-compose binary. https://github.com/docker/compose-switch
Compose Switch is a replacement to the Compose V1 docker-compose (python) executable. It translates the command line into Compose V2 docker compose then run the latter.
The python package already used update-alternatives to manage packages built for different python versions being installed simultaneously. I am not sure if anybody is still relying on features from v1, I do not think so. So I would put a "Obsoletes: ... <2.0.0" into one of the new golang-based packages. This would hopefully lead to the deinstallation of the python-based v1 package. The question is, which package should get this "Obsoletes"? I think it should go into the docker-compose-switch one, which has a Requires for docker-compose v2. This way I can only install docker-compose v2 and use "docker compose ..." (space instead of hyphen!), i.e. if I do not need the compatibility docker-compose binary. If I rely on a binary called docker-compose, I can install the docker-compose-switch package. Or I would get it automatically together with the v2 golang package, if I have the python-based one installed. Would that work? Any flaws that I missed? Better ideas? Thanks for your input. Kind Regards, Johannes -- Johannes Kastl Linux Consultant & Trainer Tel.: +49 (0) 151 2372 5802 Mail: kastl@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg http://www.b1-systems.de GF: Ralph Dehner Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
Hmmm, On 01.07.22 at 13:29 Johannes Kastl wrote:
The question is, which package should get this "Obsoletes"? I think it should go into the docker-compose-switch one, which has a Requires for docker-compose v2.
Putting only a "Obsoletes" into the docker-compose-switch package without a "Provides" (because docker-compose provides "docker-compose" in >2.0.0), I get a warning:
[ 6s] docker-compose-switch.x86_64: W: obsolete-not-provided python3-docker-compose [ 6s] If a package is obsoleted by a compatible replacement, the obsoleted package [ 6s] should also be provided in order to not cause unnecessary dependency breakage. [ 6s] If the obsoleting package is not a compatible replacement for the old one, [ 6s] leave out the Provides.
Can I safely ignore that in my case? The updated package is currently installing, I will of course test the update before submitting. Kind Regards, Johannes -- Johannes Kastl Linux Consultant & Trainer Tel.: +49 (0) 151 2372 5802 Mail: kastl@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg http://www.b1-systems.de GF: Ralph Dehner Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
Hi again, On 01.07.22 at 13:52 Johannes Kastl wrote:
Putting only a "Obsoletes" into the docker-compose-switch package without a "Provides" (because docker-compose provides "docker-compose" in >2.0.0), I get a warning:
The tests showed that this does not work, as docker-compose (the golang v2 package) automatically has an Obsoletes with a higher version, so this gets installed, and docker-compose-switch is being left out. I will now add a Recommends for docker-compose-switch to the docker-compose package, so unless people explicitly disabled recommends they would get both docker-compose and docker-compose-switch. Kind Regards, Johannes -- Johannes Kastl Linux Consultant & Trainer Tel.: +49 (0) 151 2372 5802 Mail: kastl@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg http://www.b1-systems.de GF: Ralph Dehner Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
On 01.07.22 at 16:24 Johannes Kastl wrote:
I will now add a Recommends for docker-compose-switch to the docker-compose package, so unless people explicitly disabled recommends they would get both docker-compose and docker-compose-switch.
Hmm, when explicitly installing the docker-compose package the recommends is being respected. But not during a zypper up where python-docker-compose is being replaced by docker-compose... Kind Regards, Johannes -- Johannes Kastl Linux Consultant & Trainer Tel.: +49 (0) 151 2372 5802 Mail: kastl@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg http://www.b1-systems.de GF: Ralph Dehner Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
Good morning everyone, On 01.07.22 at 16:54 Johannes Kastl wrote:
Hmm, when explicitly installing the docker-compose package the recommends is being respected. But not during a zypper up where python-docker-compose is being replaced by docker-compose...
OK, as it seems solver.onlyRequires is set to true on most installations, the only solution without big fallout would be to have docker-compose "Require" docker-compose-switch. As docker-compose providers a higher version of docker-compose than python3-docker-dompose, it will get pulled in automatically on updates. And as "Recommends" might not get respected, users will lose the docker-compose binary. Only downside that I found was that python-docker-compose can be used with podman instead of docker. But as the newer v2 version is docker-only, this cannot be respected. But there is python-podman-compose as a replacement, that was already submitted. Any thoughts or objections? Kind Regards, Johannes -- Johannes Kastl Linux Consultant & Trainer Tel.: +49 (0) 151 2372 5802 Mail: kastl@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg http://www.b1-systems.de GF: Ralph Dehner Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
Hi all, On 04.07.22 at 08:26 Johannes Kastl wrote:
OK, as it seems solver.onlyRequires is set to true on most installations, the only solution without big fallout would be to have docker-compose "Require" docker-compose-switch. As docker-compose providers a higher version of docker-compose than python3-docker-dompose, it will get pulled in automatically on updates. And as "Recommends" might not get respected, users will lose the docker-compose binary.
Unfortunately this far I do not get docker-compose installed during zypper dup on Tumbleweed, while everything works on Leap 15.x. If I manually install docker-compose I correctly get docker-compose-switch, and the python3-docker-compose is removed. What am I missing? And can I somehow create all those python3* things per macro? Kind Regards, Johannes
https://build.opensuse.org/package/view_file/home:ojkastl_buildservice:docke...
... Requires: docker # Docker Compose V2 is a major version bump release of Docker Compose. # It has been completely rewritten from scratch in Golang (V1 was in Python). Obsoletes: python2-docker-compose < 2.0.0 Obsoletes: python3-docker-compose < 2.0.0 Obsoletes: python38-docker-compose < 2.0.0 Obsoletes: python39-docker-compose < 2.0.0 Obsoletes: python310-docker-compose < 2.0.0 Provides: python2-docker-compose = %{version} Provides: python3-docker-compose = %{version} Provides: python38-docker-compose = %{version} Provides: python39-docker-compose = %{version} Provides: python310-docker-compose = %{version} # docker-compose-switch is intended to ease the transition from v1 to v2 # as it provides the docker-compose binary that was dropped in v2 # As Recommends are not working on many systems, use Requires to make sure # we do not break existing setups Requires: docker-compose-switch ... I thought that should be enough. -- Johannes Kastl Linux Consultant & Trainer Tel.: +49 (0) 151 2372 5802 Mail: kastl@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg http://www.b1-systems.de GF: Ralph Dehner Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
Am 06.07.22 um 17:43 schrieb Johannes Kastl:
And can I somehow create all those python3* things per macro?
Obsoletes: %{python_module docker-compose < 2.0.0} would expand to all *currently active* python3 flavors in Tumbleweed, but not python2-..., or python3-..., or the formerly existing python36-... which still might exist in some upgrade path with a long gap since the last Tumbleweed update.
https://build.opensuse.org/package/view_file/home:ojkastl_buildservice:docke...
... Requires: docker # Docker Compose V2 is a major version bump release of Docker Compose. # It has been completely rewritten from scratch in Golang (V1 was in Python). Obsoletes: python2-docker-compose < 2.0.0 Obsoletes: python3-docker-compose < 2.0.0 Obsoletes: python38-docker-compose < 2.0.0 Obsoletes: python39-docker-compose < 2.0.0 Obsoletes: python310-docker-compose < 2.0.0 Provides: python2-docker-compose = %{version} Provides: python3-docker-compose = %{version} Provides: python38-docker-compose = %{version} Provides: python39-docker-compose = %{version} Provides: python310-docker-compose = %{version}
You don't really provide any python*- module, so you should not state in the specfile that you do. IMHO this is a case where the obsolete-not-provided rpmlintrc warning is justifiable to be ignored. (https://github.com/rpm-software-management/rpmlint/blob/main/rpmlint/descrip...)
# docker-compose-switch is intended to ease the transition from v1 to v2 # as it provides the docker-compose binary that was dropped in v2 # As Recommends are not working on many systems, use Requires to make sure # we do not break existing setups Requires: docker-compose-switch ...
IMHO it would be much more logical to put the obsoletes tag into that package instead of the docker-compose package.
Hi Ben, On 06.07.22 at 18:09 Ben Greiner wrote:
Am 06.07.22 um 17:43 schrieb Johannes Kastl:
And can I somehow create all those python3* things per macro?
Obsoletes: %{python_module docker-compose < 2.0.0} would expand to all *currently active* python3 flavors in Tumbleweed, but not python2-..., or python3-..., or the formerly existing python36-... which still might exist in some upgrade path with a long gap since the last Tumbleweed update.
I'll give that a try, thanks!
You don't really provide any python*- module, so you should not state in the specfile that you do. IMHO this is a case where the obsolete-not-provided rpmlintrc warning is justifiable to be ignored. (https://github.com/rpm-software-management/rpmlint/blob/main/rpmlint/descrip...)
I have added a rpmlintrc to ignore that error for now, let's see.
# docker-compose-switch is intended to ease the transition from v1 to v2 # as it provides the docker-compose binary that was dropped in v2 # As Recommends are not working on many systems, use Requires to make sure # we do not break existing setups Requires: docker-compose-switch ...
IMHO it would be much more logical to put the obsoletes tag into that package instead of the docker-compose package.
That was my first try, but I got the obsolete-not-provided warning, so I tried to do it in docker-compose. As it does not fully work on Tumbleweed, I could of course change that again. I'll give it a try. Kind Regards, Johannes -- Johannes Kastl Linux Consultant & Trainer Tel.: +49 (0) 151 2372 5802 Mail: kastl@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg http://www.b1-systems.de GF: Ralph Dehner Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
On 06.07.22 at 19:57 Johannes Kastl wrote:
On 06.07.22 at 18:09 Ben Greiner wrote:
Am 06.07.22 um 17:43 schrieb Johannes Kastl:
And can I somehow create all those python3* things per macro?
Obsoletes: %{python_module docker-compose < 2.0.0} would expand to all *currently active* python3 flavors in Tumbleweed, but not python2-..., or python3-..., or the formerly existing python36-... which still might exist in some upgrade path with a long gap since the last Tumbleweed update.
I'll give that a try, thanks!
That did not work in OBS, while locally it builds fine for Tumbleweed:
[ 39s] + exec rpmbuild -ba --define '_srcdefattr (-,root,root)' --nosignature --undefine _enable_debug_packages --define 'disturl obs://build.opensuse.org/home:ojkastl_buildservice:docker_compose_etc/openSUSE_Tumbleweed/3287f6f4a59403182bded7b2ef95349c-docker-compose-switch' /home/abuild/rpmbuild/SOURCES/docker-compose-switch.spec [ 39s] error: line 39: No rich dependencies allowed for this type: Obsoletes: ( python38-docker-compose < 2.0.0 ) ( python39-docker-compose < 2.0.0 ) ( python310-docker-compose < 2.0.0 ) [ 39s] ### VM INTERACTION START ###
Johannes -- Johannes Kastl Linux Consultant & Trainer Tel.: +49 (0) 151 2372 5802 Mail: kastl@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg http://www.b1-systems.de GF: Ralph Dehner Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
Am 06.07.22 um 20:16 schrieb Johannes Kastl:
On 06.07.22 at 19:57 Johannes Kastl wrote:
On 06.07.22 at 18:09 Ben Greiner wrote:
Am 06.07.22 um 17:43 schrieb Johannes Kastl:
And can I somehow create all those python3* things per macro?
Obsoletes: %{python_module docker-compose < 2.0.0} would expand to all *currently active* python3 flavors in Tumbleweed, but not python2-..., or python3-..., or the formerly existing python36-... which still might exist in some upgrade path with a long gap since the last Tumbleweed update.
I'll give that a try, thanks!
That did not work in OBS, while locally it builds fine for Tumbleweed:
[ 39s] + exec rpmbuild -ba --define '_srcdefattr (-,root,root)' --nosignature --undefine _enable_debug_packages --define 'disturl obs://build.opensuse.org/home:ojkastl_buildservice:docker_compose_etc/openSUSE_Tumbleweed/3287f6f4a59403182bded7b2ef95349c-docker-compose-switch' /home/abuild/rpmbuild/SOURCES/docker-compose-switch.spec [ 39s] error: line 39: No rich dependencies allowed for this type: Obsoletes: ( python38-docker-compose < 2.0.0 ) ( python39-docker-compose < 2.0.0 ) ( python310-docker-compose < 2.0.0 ) [ 39s] ### VM INTERACTION START ###
This only works if one package obsoletespac*only*. If there are more
Dang, I did not think of that. The %python_module macro now creates rich dependencies. Sorry you have to spell it out explicitly then. (I was thinking of https://en.opensuse.org/openSUSE:Packaging_Python#%python_module_in_Provides which is apparently not correct anymore. Surprised that this regression did not come up since the introduction of boolean dependencies for %python_module.) Have you seen https://en.opensuse.org/openSUSE:Package_dependencies#Replace_a_package_by_a... ? packages, the solver will not do this update. Not sure, but I might be the reason for your failure to automatically update.
Am 06.07.22 um 21:35 schrieb Ben Greiner:
Am 06.07.22 um 20:16 schrieb Johannes Kastl:
On 06.07.22 at 19:57 Johannes Kastl wrote:
On 06.07.22 at 18:09 Ben Greiner wrote:
Am 06.07.22 um 17:43 schrieb Johannes Kastl:
And can I somehow create all those python3* things per macro?
Obsoletes: %{python_module docker-compose < 2.0.0} would expand to all *currently active* python3 flavors in Tumbleweed, but not python2-..., or python3-..., or the formerly existing python36-... which still might exist in some upgrade path with a long gap since the last Tumbleweed update.
I'll give that a try, thanks!
That did not work in OBS, while locally it builds fine for Tumbleweed:
[ 39s] + exec rpmbuild -ba --define '_srcdefattr (-,root,root)' --nosignature --undefine _enable_debug_packages --define 'disturl obs://build.opensuse.org/home:ojkastl_buildservice:docker_compose_etc/openSUSE_Tumbleweed/3287f6f4a59403182bded7b2ef95349c-docker-compose-switch' /home/abuild/rpmbuild/SOURCES/docker-compose-switch.spec [ 39s] error: line 39: No rich dependencies allowed for this type: Obsoletes: ( python38-docker-compose < 2.0.0 ) ( python39-docker-compose < 2.0.0 ) ( python310-docker-compose < 2.0.0 ) [ 39s] ### VM INTERACTION START ###
Dang, I did not think of that. The %python_module macro now creates rich dependencies. Sorry you have to spell it out explicitly then. (I was thinking of https://en.opensuse.org/openSUSE:Packaging_Python#%python_module_in_Provides which is apparently not correct anymore. Surprised that this regression did not come up since the introduction of boolean dependencies for %python_module.)
I retract my previous statement: This should actually be handled correctly by python-rpm-macros since python-rpm-macros-20210131: https://github.com/openSUSE/python-rpm-macros/pull/99. What's the python-rpm-macros version, you are using or do you have a special prjconf redefinition differing from Factory? - Ben
Hi Ben, On 06.07.22 at 21:51 Ben Greiner wrote:
Am 06.07.22 um 21:35 schrieb Ben Greiner:
I retract my previous statement: This should actually be handled correctly by python-rpm-macros since python-rpm-macros-20210131: https://github.com/openSUSE/python-rpm-macros/pull/99. What's the python-rpm-macros version, you are using or do you have a special prjconf redefinition differing from Factory?
No, nothing special:
https://build.opensuse.org/projects/home:ojkastl_buildservice:docker_compose...
And I just built against Tumbleweed which failed, while Leap 15.x worked and were succeeded. I have already changed back the package to hardcode the Obsoletes, but if desired I can create a debug project. As it is golang, it does not have a lot of dependencies... :-) Kind Regards, Johannes -- Johannes Kastl Linux Consultant & Trainer Tel.: +49 (0) 151 2372 5802 Mail: kastl@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg http://www.b1-systems.de GF: Ralph Dehner Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
Am 07.07.22 um 08:21 schrieb Johannes Kastl:
Hi Ben,
On 06.07.22 at 21:51 Ben Greiner wrote:
Am 06.07.22 um 21:35 schrieb Ben Greiner:
I retract my previous statement: This should actually be handled correctly by python-rpm-macros since python-rpm-macros-20210131: https://github.com/openSUSE/python-rpm-macros/pull/99. What's the python-rpm-macros version, you are using or do you have a special prjconf redefinition differing from Factory?
No, nothing special:
https://build.opensuse.org/projects/home:ojkastl_buildservice:docker_compose...
I checked it. Because python-rpm-macros is not pulled in at all (no requirement on rpm-build-python), the rpmbuild used the prjconf definition from Factory without honoring the switch from python_module_iter to python_modules_lua. A BuildRequires: python-rpm-macros would have resolved it: https://build.opensuse.org/projects/openSUSE:Factory/prjconf # prjconf definitions for python-rpm-macros # This method for generating python_modules gets too deep to expand for rpm at about 5 python flavors. # Hence, python_module_iter is replaced by python_module_lua in macros.lua. # However, OBS cannot expand lua, but has a much higher expansion depth, so this works fine for the server side resolver. %python_module_iter(a:) %{expand:%%define python %{-a*}} ( %python-%args ) %{expand:%%{?!python_module_iter_%1:%%{python_module_iter -a%*}}%%{?python_module_iter_%1}} # pseudo-undefine for obs: reset for the next expansion within the next call of python_module %python_module_iter_STOP %global python %%%%python %python_module() %{?!python_module_lua:%{expand:%%define args %{**}} %{expand:%%{python_module_iter -a %{pythons} STOP}}}%{?python_module_lua:%python_module_lua %{**}}
And I just built against Tumbleweed which failed, while Leap 15.x worked and were succeeded.
I have already changed back the package to hardcode the Obsoletes, but if desired I can create a debug project. As it is golang, it does not have a lot of dependencies... :-)
I think hardcoding is the right choice here, as it guarantees to obsolete all versions which ever existed until now. Using the macro, you will eventually lose the python38-... obsoletion, once we disable that flavor.
Kind Regards, Johannes
- Ben
Hi Ben, On 07.07.22 at 13:20 Ben Greiner wrote:
Am 07.07.22 um 08:21 schrieb Johannes Kastl:
No, nothing special:
https://build.opensuse.org/projects/home:ojkastl_buildservice:docker_compose...
I checked it. Because python-rpm-macros is not pulled in at all (no requirement on rpm-build-python), the rpmbuild used the prjconf definition from Factory without honoring the switch from python_module_iter to python_modules_lua. A BuildRequires: python-rpm-macros would have resolved it:
https://build.opensuse.org/projects/openSUSE:Factory/prjconf # prjconf definitions for python-rpm-macros # This method for generating python_modules gets too deep to expand for rpm at about 5 python flavors. # Hence, python_module_iter is replaced by python_module_lua in macros.lua. # However, OBS cannot expand lua, but has a much higher expansion depth, so this works fine for the server side resolver. %python_module_iter(a:) %{expand:%%define python %{-a*}} ( %python-%args ) %{expand:%%{?!python_module_iter_%1:%%{python_module_iter -a%*}}%%{?python_module_iter_%1}} # pseudo-undefine for obs: reset for the next expansion within the next call of python_module %python_module_iter_STOP %global python %%%%python %python_module() %{?!python_module_lua:%{expand:%%define args %{**}} %{expand:%%{python_module_iter -a %{pythons} STOP}}}%{?python_module_lua:%python_module_lua %{**}}
Thanks for digging into this and the explanation. Nice to learn something new everyday... :-) Johannes -- Johannes Kastl Linux Consultant & Trainer Tel.: +49 (0) 151 2372 5802 Mail: kastl@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg http://www.b1-systems.de GF: Ralph Dehner Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
Good Morning Ben, On 06.07.22 at 21:35 Ben Greiner wrote:
Have you seen https://en.opensuse.org/openSUSE:Package_dependencies#Replace_a_package_by_a... ?
This only works if one package obsoletespac*only*. If there are more packages, the solver will not do this update.
Not sure, but I might be the reason for your failure to automatically update.
That was my first guess, so I moved the Obsoletes from docker-compose-switch to docker-compose, which obviously provides "docker-compose" > 2.0.0 and obsoletes the python package which has an additional provides so it was found when people do "zypper in docker-compose". I think zypper calls it "Package capabilities". My tests last week on Leap 15.x and SLES15.x were successful, it only failed to properly replace the python package on Tumbleweed. My guess would be due to the multi-python-setup. Thanks for your help, I'll keep digging and trying. Johannes -- Johannes Kastl Linux Consultant & Trainer Tel.: +49 (0) 151 2372 5802 Mail: kastl@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg http://www.b1-systems.de GF: Ralph Dehner Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
On 07.07.22 at 08:24 Johannes Kastl wrote:
My tests last week on Leap 15.x and SLES15.x were successful, it only failed to properly replace the python package on Tumbleweed. My guess would be due to the multi-python-setup.
Ha! In your face, Tumbleeed! Just after I wrote my previous mail the "zypper ref" finished, and now when calling zypper dup it properly replaces python310-docker-dompose:
LANG=C sudo zypper dup Loading repository data... Reading installed packages... Warning: You are about to do a distribution upgrade with all enabled repositories. Make sure these repositories are compatible before you continue. See 'man zypper' for more information about this command. Computing distribution upgrade...
The following 4 items are locked and will not be changed by any action: Available: gnome-packagekit plasma5-pk-updates plasma5-pk-updates-lang procps-lang
The following 2 NEW packages are going to be installed: docker-compose docker-compose-switch
The following package is going to be REMOVED: python310-docker-compose
2 new packages to install, 1 to remove. Overall download size: 8.4 MiB. Already cached: 0 B. After the operation, additional 29.0 MiB will be used. Continue? [y/n/v/...? shows all options] (y):
Again, thanks for your help, Ben. I'll test that everything properly works on the Leaps and then submit the packages. Kind Regards, Johannes -- Johannes Kastl Linux Consultant & Trainer Tel.: +49 (0) 151 2372 5802 Mail: kastl@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg http://www.b1-systems.de GF: Ralph Dehner Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
On 01.07.22 at 13:29 Johannes Kastl wrote:
TL;DR: Which package should get Obsoletes and Requires?
Packages for both docker-compose v2 as well as docker-compose-switch are waiting for someone to accept the SRs: https://build.opensuse.org/request/show/987334 https://build.opensuse.org/request/show/987335 Any takers? Kind Regards, Johannes -- Johannes Kastl Linux Consultant & Trainer Tel.: +49 (0) 151 2372 5802 Mail: kastl@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg http://www.b1-systems.de GF: Ralph Dehner Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
participants (2)
-
Ben Greiner
-
Johannes Kastl