I'm working on a RHEL7 docker container with cobbler in it. I have setup cobbler in this container to manage dhcpd. One hurdle with this setup is that a cobbler sync needs to restart dhcpd, but a docker container has no systemd. So what I've done to work around this is to edit /usr/lib/python2.7/site-packages/cobbler/modules/sync_post_restart_services .py and change the dhcp_restart_command to call a simple shell script:
-- #!/bin/sh
#dhcpd writes its pid to /var/run/dhcpd.pid #kill the PID in the file, if the file exists if [ -f "/var/run/dhcpd.pid" ] then kill `cat /var/run/dhcpd.pid` fi
#Start again using command line from /usr/lib/systemd/system/dhcpd.service /usr/sbin/dhcpd -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --
I do realize I'm not really supposed to have more than one process in a container. But if I put dhcpd in its own container, the problem would just be even harder b/c now cobbler in its container needs to restart another container. So I took the easier route and put them in the same container. So in this implementation, it would be useful if I could specify a custom dhcp_restart_command in /etc/cobbler/settings. Would that be a change the community would be interested in accepting?
Thx, britt
On 03.04.2015 [02:17:17 +0000], Britt Houser (bhouser) wrote:
I'm working on a RHEL7 docker container with cobbler in it. I have setup cobbler in this container to manage dhcpd.
It seems like you're not configuring the containers correctly. Cobbler should run in one container and dhcpd should run in another, right?
Dare I ask why you're doing this? :)
One hurdle with this setup is that a cobbler sync needs to restart dhcpd, but a docker container has no systemd. So what I've done to work around this is to edit /usr/lib/python2.7/site-packages/cobbler/modules/sync_post_restart_services .py and change the dhcp_restart_command to call a simple shell script:
-- #!/bin/sh
#dhcpd writes its pid to /var/run/dhcpd.pid #kill the PID in the file, if the file exists if [ -f "/var/run/dhcpd.pid" ] then kill `cat /var/run/dhcpd.pid` fi
#Start again using command line from /usr/lib/systemd/system/dhcpd.service /usr/sbin/dhcpd -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --
I do realize I'm not really supposed to have more than one process in a container. But if I put dhcpd in its own container, the problem would just be even harder b/c now cobbler in its container needs to restart another container.
No, it just needs to restart (reload) that process. Meaning dhcpd needs either graceful reload, or, as you said, you need to be able to restart the DHCP process itself. Containerization isn't free :)
So I took the easier route and put them in the same container. So in this implementation, it would be useful if I could specify a custom dhcp_restart_command in /etc/cobbler/settings. Would that be a change the community would be interested in accepting?
I think the right way is to provide another option to the
[dhcp] module = manage_isc
section of configuration, which is something like
[dhcp] module = manage_local
And configure that appropriately? I've done that, for instance, for having a local version of authentication.
-Nish
On 4/3/15, 12:30 PM, "Nishanth Aravamudan" nacc@linux.vnet.ibm.com wrote:
On 03.04.2015 [02:17:17 +0000], Britt Houser (bhouser) wrote:
I'm working on a RHEL7 docker container with cobbler in it. I have setup cobbler in this container to manage dhcpd.
It seems like you're not configuring the containers correctly. Cobbler should run in one container and dhcpd should run in another, right?
Dare I ask why you're doing this? :)
Right - not the container ideal, but I put the "why" further down.
One hurdle with this setup is that a cobbler sync needs to restart dhcpd, but a docker container has no systemd. So what I've done to work around this is to edit
/usr/lib/python2.7/site-packages/cobbler/modules/sync_post_restart_servic es .py and change the dhcp_restart_command to call a simple shell script:
-- #!/bin/sh
#dhcpd writes its pid to /var/run/dhcpd.pid #kill the PID in the file, if the file exists if [ -f "/var/run/dhcpd.pid" ] then kill `cat /var/run/dhcpd.pid` fi
#Start again using command line from /usr/lib/systemd/system/dhcpd.service /usr/sbin/dhcpd -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --
I do realize I'm not really supposed to have more than one process in a container. But if I put dhcpd in its own container, the problem would just be even harder b/c now cobbler in its container needs to restart another container.
No, it just needs to restart (reload) that process. Meaning dhcpd needs either graceful reload, or, as you said, you need to be able to restart the DHCP process itself. Containerization isn't free :)
So to my knowledge, ISC-DHCP doesn't have a "reload", you must kill and then restart. If DHCP is in its own container, killing the process means killing the container. Respawning the process means starting a new container. This in and of itself isn't hard, but invoking that from within another container I think would be more difficult than keeping both processes in the same container.
So I took the easier route and put them in the same container. So in this implementation, it would be useful if I could specify a custom dhcp_restart_command in /etc/cobbler/settings. Would that be a change the community would be interested in accepting?
I think the right way is to provide another option to the
[dhcp] module = manage_isc
section of configuration, which is something like
[dhcp] module = manage_local
And configure that appropriately? I've done that, for instance, for having a local version of authentication.
-Nish
Can you elaborate on what you envision manage_local would do? I'm not quite following how this would work? I still want cobbler to be generating my dhcpd.conf file from template, I just want to change how cobbler restarts dhcpd.
Thx, britt
On 03.04.2015 [17:05:30 +0000], Britt Houser (bhouser) wrote:
On 4/3/15, 12:30 PM, "Nishanth Aravamudan" nacc@linux.vnet.ibm.com wrote:
On 03.04.2015 [02:17:17 +0000], Britt Houser (bhouser) wrote:
I'm working on a RHEL7 docker container with cobbler in it. I have setup cobbler in this container to manage dhcpd.
It seems like you're not configuring the containers correctly. Cobbler should run in one container and dhcpd should run in another, right?
Dare I ask why you're doing this? :)
Right - not the container ideal, but I put the "why" further down.
One hurdle with this setup is that a cobbler sync needs to restart dhcpd, but a docker container has no systemd. So what I've done to work around this is to edit
/usr/lib/python2.7/site-packages/cobbler/modules/sync_post_restart_servic es .py and change the dhcp_restart_command to call a simple shell script:
-- #!/bin/sh
#dhcpd writes its pid to /var/run/dhcpd.pid #kill the PID in the file, if the file exists if [ -f "/var/run/dhcpd.pid" ] then kill `cat /var/run/dhcpd.pid` fi
#Start again using command line from /usr/lib/systemd/system/dhcpd.service /usr/sbin/dhcpd -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --
I do realize I'm not really supposed to have more than one process in a container. But if I put dhcpd in its own container, the problem would just be even harder b/c now cobbler in its container needs to restart another container.
No, it just needs to restart (reload) that process. Meaning dhcpd needs either graceful reload, or, as you said, you need to be able to restart the DHCP process itself. Containerization isn't free :)
So to my knowledge, ISC-DHCP doesn't have a "reload", you must kill and then restart. If DHCP is in its own container, killing the process means killing the container. Respawning the process means starting a new container. This in and of itself isn't hard, but invoking that from within another container I think would be more difficult than keeping both processes in the same container.
So I took the easier route and put them in the same container. So in this implementation, it would be useful if I could specify a custom dhcp_restart_command in /etc/cobbler/settings. Would that be a change the community would be interested in accepting?
I think the right way is to provide another option to the
[dhcp] module = manage_isc
section of configuration, which is something like
[dhcp] module = manage_local
And configure that appropriately? I've done that, for instance, for having a local version of authentication.
-Nish
Can you elaborate on what you envision manage_local would do? I'm not quite following how this would work? I still want cobbler to be generating my dhcpd.conf file from template, I just want to change how cobbler restarts dhcpd.
Something like this:
diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py index 7a41ee2..d201ab6 100644 --- a/cobbler/action_sync.py +++ b/cobbler/action_sync.py @@ -233,6 +233,14 @@ class CobblerSync: error_msg = "service dnsmasq restart failed" self.logger.error(error_msg) raise CX(error_msg) + elif which_dhcp_module == "manage_local": + if restart_dhcp != "0": + # call some external process + rc = utils.subprocess_call(self.logger, "your_script", shell=True) + if rc != 0: + error_msg = "script restart failed" + self.logger.error(error_msg) + raise CX(error_msg)
def clean_link_cache(self): for dirtree in [os.path.join(self.bootloc, 'images'), self.settings.webdir]:
It's sort of gross that cobbler has so specific knowledge of dhcpd in action_sync.py. In the interest of abstraction and cleaning the code, I'd suggest, pulling sync_dhcp() itself into the dhcp modules code (manage_isc, manage_dnsmasq). That is, make sync_dhcp() a member of self.dhcp objects in action_sync.py
Then you'd just inherit in manage_local from manage_isc and override sync_dhcp.
-Nish
Hi Nish,
I agree and i'd be happy to take any patches to clean stuff up.
Cheers!
On Fri, Apr 3, 2015 at 7:22 PM, Nishanth Aravamudan <nacc@linux.vnet.ibm.com
wrote:
On 03.04.2015 [17:05:30 +0000], Britt Houser (bhouser) wrote:
On 4/3/15, 12:30 PM, "Nishanth Aravamudan" nacc@linux.vnet.ibm.com
wrote:
On 03.04.2015 [02:17:17 +0000], Britt Houser (bhouser) wrote:
I'm working on a RHEL7 docker container with cobbler in it. I have setup cobbler in this container to manage dhcpd.
It seems like you're not configuring the containers correctly. Cobbler should run in one container and dhcpd should run in another, right?
Dare I ask why you're doing this? :)
Right - not the container ideal, but I put the "why" further down.
One hurdle with this setup is that a cobbler sync needs to restart dhcpd, but a docker container has no systemd. So what I've done to work around this is to edit
/usr/lib/python2.7/site-packages/cobbler/modules/sync_post_restart_servic
es .py and change the dhcp_restart_command to call a simple shell script:
-- #!/bin/sh
#dhcpd writes its pid to /var/run/dhcpd.pid #kill the PID in the file, if the file exists if [ -f "/var/run/dhcpd.pid" ] then kill `cat /var/run/dhcpd.pid` fi
#Start again using command line from /usr/lib/systemd/system/dhcpd.service /usr/sbin/dhcpd -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --
I do realize I'm not really supposed to have more than one process in
a
container. But if I put dhcpd in its own container, the problem would just be even harder b/c now cobbler in its container needs to restart
another
container.
No, it just needs to restart (reload) that process. Meaning dhcpd needs either graceful reload, or, as you said, you need to be able to restart the DHCP process itself. Containerization isn't free :)
So to my knowledge, ISC-DHCP doesn't have a "reload", you must kill and then restart. If DHCP is in its own container, killing the process means killing the container. Respawning the process means starting a new container. This in and of itself isn't hard, but invoking that from within another container I think would be more difficult than keeping
both
processes in the same container.
So I took the easier route and put them in the same container. So in this implementation, it would be useful if I could specify a custom dhcp_restart_command in /etc/cobbler/settings. Would that be a change the community would be interested in accepting?
I think the right way is to provide another option to the
[dhcp] module = manage_isc
section of configuration, which is something like
[dhcp] module = manage_local
And configure that appropriately? I've done that, for instance, for having a local version of authentication.
-Nish
Can you elaborate on what you envision manage_local would do? I'm not quite following how this would work? I still want cobbler to be generating my dhcpd.conf file from template, I just want to change how cobbler restarts dhcpd.
Something like this:
diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py index 7a41ee2..d201ab6 100644 --- a/cobbler/action_sync.py +++ b/cobbler/action_sync.py @@ -233,6 +233,14 @@ class CobblerSync: error_msg = "service dnsmasq restart failed" self.logger.error(error_msg) raise CX(error_msg)
elif which_dhcp_module == "manage_local":
if restart_dhcp != "0":
# call some external process
rc = utils.subprocess_call(self.logger,
"your_script", shell=True)
if rc != 0:
error_msg = "script restart failed"
self.logger.error(error_msg)
raise CX(error_msg)
def clean_link_cache(self): for dirtree in [os.path.join(self.bootloc, 'images'),
self.settings.webdir]:
It's sort of gross that cobbler has so specific knowledge of dhcpd in action_sync.py. In the interest of abstraction and cleaning the code, I'd suggest, pulling sync_dhcp() itself into the dhcp modules code (manage_isc, manage_dnsmasq). That is, make sync_dhcp() a member of self.dhcp objects in action_sync.py
Then you'd just inherit in manage_local from manage_isc and override sync_dhcp.
-Nish
cobbler-devel mailing list cobbler-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/cobbler-devel
On 06.04.2015 [08:58:35 +0200], J?rgen Maas wrote:
Hi Nish,
I agree and i'd be happy to take any patches to clean stuff up.
Not yet tested, but this should work...
diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py index 7a41ee2..8734151 100644 --- a/cobbler/action_sync.py +++ b/cobbler/action_sync.py @@ -212,27 +212,7 @@ class CobblerSync:
if self.settings.manage_dhcp: self.write_dhcp() - if which_dhcp_module == "manage_isc": - service_name = utils.dhcp_service_name(self.api) - if restart_dhcp != "0": - rc = utils.subprocess_call(self.logger, "dhcpd -t -q", shell=True) - if rc != 0: - error_msg = "dhcpd -t failed" - self.logger.error(error_msg) - raise CX(error_msg) - service_restart = "service %s restart" % service_name - rc = utils.subprocess_call(self.logger, service_restart, shell=True) - if rc != 0: - error_msg = "%s failed" % service_name - self.logger.error(error_msg) - raise CX(error_msg) - elif which_dhcp_module == "manage_dnsmasq": - if restart_dhcp != "0": - rc = utils.subprocess_call(self.logger, "service dnsmasq restart") - if rc != 0: - error_msg = "service dnsmasq restart failed" - self.logger.error(error_msg) - raise CX(error_msg) + self.dhcp.sync_dhcp()
def clean_link_cache(self): for dirtree in [os.path.join(self.bootloc, 'images'), self.settings.webdir]: diff --git a/cobbler/modules/manage_dnsmasq.py b/cobbler/modules/manage_dnsmasq.py index a87365c..7ec24e6 100644 --- a/cobbler/modules/manage_dnsmasq.py +++ b/cobbler/modules/manage_dnsmasq.py @@ -191,6 +191,14 @@ class DnsmasqManager: # already taken care of by the regen_hosts() pass
+ def sync_dhcp(self): + restart_dhcp = str(self.settings.restart_dhcp).lower() + if restart_dhcp != "0": + rc = utils.subprocess_call(self.logger, "service dnsmasq restart") + if rc != 0: + error_msg = "service dnsmasq restart failed" + self.logger.error(error_msg) + raise CX(error_msg)
def get_manager(collection_mgr, logger): return DnsmasqManager(collection_mgr, logger) diff --git a/cobbler/modules/manage_isc.py b/cobbler/modules/manage_isc.py index 6dabd32..d0a8102 100644 --- a/cobbler/modules/manage_isc.py +++ b/cobbler/modules/manage_isc.py @@ -188,6 +188,21 @@ class IscManager: def regen_ethers(self): pass # ISC/BIND do not use this
+ def sync_dhcp(self): + restart_dhcp = str(self.settings.restart_dhcp).lower() + service_name = utils.dhcp_service_name(self.api) + if restart_dhcp != "0": + rc = utils.subprocess_call(self.logger, "dhcpd -t -q", shell=True) + if rc != 0: + error_msg = "dhcpd -t failed" + self.logger.error(error_msg) + raise CX(error_msg) + service_restart = "service %s restart" % service_name + rc = utils.subprocess_call(self.logger, service_restart, shell=True) + if rc != 0: + error_msg = "%s failed" % service_name + self.logger.error(error_msg) + raise CX(error_msg)
def get_manager(collection_mgr, logger): return IscManager(collection_mgr, logger)
We are also using cobbler in a docker container, and we use supervisord for process management in CentOS 6.6. What we did is, we changed the Sys V init script of dhcpd service to use supervisorctl. *service dhcpd start *is an standard command and since your container is always customised to your specific requirements, you can always modify the startup scripts.
On Mon, Apr 6, 2015 at 11:47 PM, Nishanth Aravamudan < nacc@linux.vnet.ibm.com> wrote:
On 06.04.2015 [08:58:35 +0200], J?rgen Maas wrote:
Hi Nish,
I agree and i'd be happy to take any patches to clean stuff up.
Not yet tested, but this should work...
diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py index 7a41ee2..8734151 100644 --- a/cobbler/action_sync.py +++ b/cobbler/action_sync.py @@ -212,27 +212,7 @@ class CobblerSync:
if self.settings.manage_dhcp: self.write_dhcp()
if which_dhcp_module == "manage_isc":
service_name = utils.dhcp_service_name(self.api)
if restart_dhcp != "0":
rc = utils.subprocess_call(self.logger, "dhcpd -t
-q", shell=True)
if rc != 0:
error_msg = "dhcpd -t failed"
self.logger.error(error_msg)
raise CX(error_msg)
service_restart = "service %s restart" % service_name
rc = utils.subprocess_call(self.logger,
service_restart, shell=True)
if rc != 0:
error_msg = "%s failed" % service_name
self.logger.error(error_msg)
raise CX(error_msg)
elif which_dhcp_module == "manage_dnsmasq":
if restart_dhcp != "0":
rc = utils.subprocess_call(self.logger, "service
dnsmasq restart")
if rc != 0:
error_msg = "service dnsmasq restart failed"
self.logger.error(error_msg)
raise CX(error_msg)
self.dhcp.sync_dhcp()
def clean_link_cache(self): for dirtree in [os.path.join(self.bootloc, 'images'),
self.settings.webdir]: diff --git a/cobbler/modules/manage_dnsmasq.py b/cobbler/modules/manage_dnsmasq.py index a87365c..7ec24e6 100644 --- a/cobbler/modules/manage_dnsmasq.py +++ b/cobbler/modules/manage_dnsmasq.py @@ -191,6 +191,14 @@ class DnsmasqManager: # already taken care of by the regen_hosts() pass
- def sync_dhcp(self):
restart_dhcp = str(self.settings.restart_dhcp).lower()
if restart_dhcp != "0":
rc = utils.subprocess_call(self.logger, "service dnsmasq
restart")
if rc != 0:
error_msg = "service dnsmasq restart failed"
self.logger.error(error_msg)
raise CX(error_msg)
def get_manager(collection_mgr, logger): return DnsmasqManager(collection_mgr, logger) diff --git a/cobbler/modules/manage_isc.py b/cobbler/modules/manage_isc.py index 6dabd32..d0a8102 100644 --- a/cobbler/modules/manage_isc.py +++ b/cobbler/modules/manage_isc.py @@ -188,6 +188,21 @@ class IscManager: def regen_ethers(self): pass # ISC/BIND do not use this
- def sync_dhcp(self):
restart_dhcp = str(self.settings.restart_dhcp).lower()
service_name = utils.dhcp_service_name(self.api)
if restart_dhcp != "0":
rc = utils.subprocess_call(self.logger, "dhcpd -t -q",
shell=True)
if rc != 0:
error_msg = "dhcpd -t failed"
self.logger.error(error_msg)
raise CX(error_msg)
service_restart = "service %s restart" % service_name
rc = utils.subprocess_call(self.logger, service_restart,
shell=True)
if rc != 0:
error_msg = "%s failed" % service_name
self.logger.error(error_msg)
raise CX(error_msg)
def get_manager(collection_mgr, logger): return IscManager(collection_mgr, logger)
cobbler-devel mailing list cobbler-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/cobbler-devel
Applied patch to master, thanks! ;-)
On Mon, Apr 6, 2015 at 8:32 PM, Santosh Kumar Gupta santosh0705@gmail.com wrote:
We are also using cobbler in a docker container, and we use supervisord for process management in CentOS 6.6. What we did is, we changed the Sys V init script of dhcpd service to use supervisorctl. *service dhcpd start *is an standard command and since your container is always customised to your specific requirements, you can always modify the startup scripts.
On Mon, Apr 6, 2015 at 11:47 PM, Nishanth Aravamudan < nacc@linux.vnet.ibm.com> wrote:
On 06.04.2015 [08:58:35 +0200], J?rgen Maas wrote:
Hi Nish,
I agree and i'd be happy to take any patches to clean stuff up.
Not yet tested, but this should work...
diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py index 7a41ee2..8734151 100644 --- a/cobbler/action_sync.py +++ b/cobbler/action_sync.py @@ -212,27 +212,7 @@ class CobblerSync:
if self.settings.manage_dhcp: self.write_dhcp()
if which_dhcp_module == "manage_isc":
service_name = utils.dhcp_service_name(self.api)
if restart_dhcp != "0":
rc = utils.subprocess_call(self.logger, "dhcpd -t
-q", shell=True)
if rc != 0:
error_msg = "dhcpd -t failed"
self.logger.error(error_msg)
raise CX(error_msg)
service_restart = "service %s restart" % service_name
rc = utils.subprocess_call(self.logger,
service_restart, shell=True)
if rc != 0:
error_msg = "%s failed" % service_name
self.logger.error(error_msg)
raise CX(error_msg)
elif which_dhcp_module == "manage_dnsmasq":
if restart_dhcp != "0":
rc = utils.subprocess_call(self.logger, "service
dnsmasq restart")
if rc != 0:
error_msg = "service dnsmasq restart failed"
self.logger.error(error_msg)
raise CX(error_msg)
self.dhcp.sync_dhcp()
def clean_link_cache(self): for dirtree in [os.path.join(self.bootloc, 'images'),
self.settings.webdir]: diff --git a/cobbler/modules/manage_dnsmasq.py b/cobbler/modules/manage_dnsmasq.py index a87365c..7ec24e6 100644 --- a/cobbler/modules/manage_dnsmasq.py +++ b/cobbler/modules/manage_dnsmasq.py @@ -191,6 +191,14 @@ class DnsmasqManager: # already taken care of by the regen_hosts() pass
- def sync_dhcp(self):
restart_dhcp = str(self.settings.restart_dhcp).lower()
if restart_dhcp != "0":
rc = utils.subprocess_call(self.logger, "service dnsmasq
restart")
if rc != 0:
error_msg = "service dnsmasq restart failed"
self.logger.error(error_msg)
raise CX(error_msg)
def get_manager(collection_mgr, logger): return DnsmasqManager(collection_mgr, logger) diff --git a/cobbler/modules/manage_isc.py b/cobbler/modules/manage_isc.py index 6dabd32..d0a8102 100644 --- a/cobbler/modules/manage_isc.py +++ b/cobbler/modules/manage_isc.py @@ -188,6 +188,21 @@ class IscManager: def regen_ethers(self): pass # ISC/BIND do not use this
- def sync_dhcp(self):
restart_dhcp = str(self.settings.restart_dhcp).lower()
service_name = utils.dhcp_service_name(self.api)
if restart_dhcp != "0":
rc = utils.subprocess_call(self.logger, "dhcpd -t -q",
shell=True)
if rc != 0:
error_msg = "dhcpd -t failed"
self.logger.error(error_msg)
raise CX(error_msg)
service_restart = "service %s restart" % service_name
rc = utils.subprocess_call(self.logger, service_restart,
shell=True)
if rc != 0:
error_msg = "%s failed" % service_name
self.logger.error(error_msg)
raise CX(error_msg)
def get_manager(collection_mgr, logger): return IscManager(collection_mgr, logger)
cobbler-devel mailing list cobbler-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/cobbler-devel
cobbler-devel mailing list cobbler-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/cobbler-devel
No it was not. And yes, i really should have done that...
For cobbler 3.0 all features need to be tested manually and documented for the new docs anyway That process will fix a lot of bugs/regressions that got introduced to master (much RF work)
(un)forutnately, we're not anywhere close to a cobbler 3.0 release...
On Tue, Apr 7, 2015 at 2:50 PM, Alan Evangelista alanoe@linux.vnet.ibm.com wrote:
On 04/07/2015 01:22 AM, Jörgen Maas wrote:
Applied patch to master, thanks! ;-)
I assume this patch was tested before merged?
cobbler-devel mailing list cobbler-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/cobbler-devel
cobbler-devel@lists.fedorahosted.org