cobbler external inventory script, does not seem to pick up the already existing hosts in cobbler

714 views
Skip to first unread message

Joost Ringoot

unread,
Jan 22, 2014, 9:27:48 AM1/22/14
to ansible...@googlegroups.com
Hello,

I wanted to give "This script" (from http://docs.ansible.com/intro_dynamic_inventory.html#example-the-cobbler-external-inventory-script) a try to do the dynamic inventory.

Benno helped me in irc to get rid of some errors, due to not having a cobbler.ini in the same directory.
An example file can be found in /opt/ansible/plugins/inventory/cobbler.ini or in git
It would be nice to include that in the manual, for newbies like me

Now I have currently 6 hosts in cobbler, but the script seems not aware of it, see output below:

[root@geppetto ansible]# cobbler system list
   metop-20.oma.be
   metop-28.oma.be
   zotac-09
   zotac-24.oma.be
   zotac-29
   zotac-36
[root@geppetto ansible]#  ./cobbler.py
{}
[root@geppetto ansible]#
 [root@geppetto ansible]# cobbler --version
Cobbler 2.4.0
  source: ?, ?
  build time: Thu Jun 20 06:07:51 2013
[root@geppetto ansible]#

Any ideas?
Would it make sense if I upload the output of
[root@geppetto ansible]# python -mtrace --trace ./cobbler.py > cobbler.py.debuglog

here? It is big!:
[root@geppetto ansible]# ls -lah cobbler.py.debuglog
-rw-r--r--. 1 root root 3.4M Jan 21 15:01 cobbler.py.debuglog
[root@geppetto ansible]# wc -l cobbler.py.debuglog
76780 cobbler.py.debuglog
[root@geppetto ansible]#



Thanks,

Joost

BTW:
A little note on selinux, since that is often the culprit: I have it running currently in permissive mode.
I grepped /var/log/audit/audit.log for ansible: nothing found.
What I found on cobbler I poured into a policy and applied it and I tried again:


[root@geppetto ansible]# grep ansible /var/log/audit/audit.log
[root@geppetto ansible]#
[root@geppetto ansible]# grep cobbler /var/log/audit/audit.log
type=AVC msg=audit(1390309171.088:106152): avc:  denied  { write } for  pid=27878 comm="httpd" name="webui_sessions" dev=dm-0 ino=17958021 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:cobbler_var_lib_t:s0 tclass=dir
type=AVC msg=audit(1390309171.088:106152): avc:  denied  { add_name } for  pid=27878 comm="httpd" name="sessionid5f93d6b7217e5248218a9c705f0769cf" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:cobbler_var_lib_t:s0 tclass=dir
type=AVC msg=audit(1390309171.088:106152): avc:  denied  { create } for  pid=27878 comm="httpd" name="sessionid5f93d6b7217e5248218a9c705f0769cf" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:cobbler_var_lib_t:s0 tclass=file
type=AVC msg=audit(1390309171.088:106152): avc:  denied  { write } for  pid=27878 comm="httpd" name="sessionid5f93d6b7217e5248218a9c705f0769cf" dev=dm-0 ino=17958488 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:cobbler_var_lib_t:s0 tclass=file
type=AVC msg=audit(1390309171.089:106153): avc:  denied  { remove_name } for  pid=27878 comm="httpd" name="sessionid5f93d6b7217e5248218a9c705f0769cf_out_Ud8hJk" dev=dm-0 ino=17958538 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:cobbler_var_lib_t:s0 tclass=dir
type=AVC msg=audit(1390309171.089:106153): avc:  denied  { rename } for  pid=27878 comm="httpd" name="sessionid5f93d6b7217e5248218a9c705f0769cf_out_Ud8hJk" dev=dm-0 ino=17958538 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:cobbler_var_lib_t:s0 tclass=file
type=AVC msg=audit(1390309171.089:106153): avc:  denied  { unlink } for  pid=27878 comm="httpd" name="sessionid5f93d6b7217e5248218a9c705f0769cf" dev=dm-0 ino=17958488 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:cobbler_var_lib_t:s0 tclass=file
[root@geppetto ansible]#

[root@geppetto selinux]# grep cobbler /var/log/audit/audit.log | audit2allow -M cobblerpol
******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i cobblerpol.pp

[root@geppetto selinux]# semodule -i cobblerpol.pp
[root@geppetto selinux]# cd /etc/ansible
[root@geppetto ansible]#  ./cobbler.py
{}
[root@geppetto ansible]#

But no real difference,... like it should since it is permissive mode.






Vincent Van der Kussen

unread,
Jan 22, 2014, 10:26:59 AM1/22/14
to ansible...@googlegroups.com
Hi Joost,

I think you might need to add --list as an argument to the script if
you run it "stand alone".

If you want to use it with ansible or ansible-playbook you can run it
with -i cobbler.py ( example : ansible-playbook -i cobbler.py
<playbook> ).

I have no cobbler setup to test this, so I might be wrong.

Vincent
> --
> You received this message because you are subscribed to the Google Groups
> "Ansible Project" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to ansible-proje...@googlegroups.com.
> To post to this group, send email to ansible...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Michael DeHaan

unread,
Jan 22, 2014, 10:32:11 AM1/22/14
to ansible...@googlegroups.com
Vincent,

You are incorrect, the default behavior is in fact the same as --list.

I'd probably recommend debugging the example inventory script or you may have an issue with their being no systems the last time the cache of the inventory was written, which is in cobbler.ini as 900 seconds.


--
Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Vincent Van der Kussen

unread,
Jan 22, 2014, 10:51:26 AM1/22/14
to ansible...@googlegroups.com
On Wed, Jan 22, 2014 at 4:32 PM, Michael DeHaan
<mic...@ansibleworks.com> wrote:
> Vincent,
>
> You are incorrect, the default behavior is in fact the same as --list.

Didn't know that. I also didn't check ( my bad ).

Joost Ringoot

unread,
Jan 22, 2014, 5:33:50 PM1/22/14
to ansible...@googlegroups.com

Thanks for looking into this, Michael and Vincent.
Alas no solution yet.
More than 900 seconds have passed by now, but still no hosts seen with the script:

[root@geppetto ansible]# cobbler system list
   metop-20.oma.be
   metop-28.oma.be
   zotac-09
   zotac-24.oma.be
   zotac-29
   zotac-36
[root@geppetto ansible]# ./cobbler.py --list
{}
[root@geppetto ansible]# ./cobbler.py
{}
[root@geppetto ansible]# date
wo jan 22 23:04:40 CET 2014
[root@geppetto ansible]# cat cobbler.ini
# Ansible Cobbler external inventory script settings
#

[cobbler]

host = http://geppetto.oma.be/cobbler_api

# API calls to Cobbler can be slow. For this reason, we cache the results of an API
# call. Set this to the path you want cache files to be written to. Two files
# will be written to this directory:
#   - ansible-cobbler.cache
#   - ansible-cobbler.index
cache_path = /tmp

# The number of seconds a cache file is considered valid. After this many
# seconds, a new API call will be made, and the cache file will be updated.
cache_max_age = 900



[root@geppetto ansible]#

I forgot to mention, on suggestion of Benno, I did some tests to get that page and get strangely: proxy-errors:

[root@geppetto ansible]# wget http://geppetto.oma.be/cobbler_api
--2014-01-22 23:13:40--  http://geppetto.oma.be/cobbler_api
Resolving geppetto.oma.be... 192.168.16.49
Connecting to geppetto.oma.be|192.168.16.49|:80... connected.
HTTP request sent, awaiting response... 502 Proxy Error
2014-01-22 23:13:40 ERROR 502: Proxy Error.

[root@geppetto ansible]#
[root@geppetto ansible]# wget http://geppetto.oma.be/cobbler_web
--2014-01-22 23:15:54--  http://geppetto.oma.be/cobbler_web
Resolving geppetto.oma.be... 192.168.16.49
Connecting to geppetto.oma.be|192.168.16.49|:80... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://geppetto.oma.be/cobbler_web [following]
--2014-01-22 23:15:54--  https://geppetto.oma.be/cobbler_web
Connecting to geppetto.oma.be|192.168.16.49|:443... connected.
ERROR: cannot verify geppetto.oma.be's certificate, issued by `/C=--/ST=SomeState/L=SomeCity/O=SomeOrganization/OU=SomeOrganizationalUnit/CN=geppetto.oma.be/emailAddress=root_at_geppetto.oma.be':
  Self-signed certificate encountered.
To connect to geppetto.oma.be insecurely, use `--no-check-certificate'.
[root@geppetto ansible]# wget http://geppetto.oma.be/cobbler_web --no-check-certificate
--2014-01-22 23:16:21--  http://geppetto.oma.be/cobbler_web
Resolving geppetto.oma.be... 192.168.16.49
Connecting to geppetto.oma.be|192.168.16.49|:80... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://geppetto.oma.be/cobbler_web [following]
--2014-01-22 23:16:21--  https://geppetto.oma.be/cobbler_web
Connecting to geppetto.oma.be|192.168.16.49|:443... connected.
WARNING: cannot verify geppetto.oma.be's certificate, issued by `/C=--/ST=SomeState/L=SomeCity/O=SomeOrganization/OU=SomeOrganizationalUnit/CN=geppetto.oma.be/emailAddress=root_at_geppetto.oma.be':
  Self-signed certificate encountered.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: `cobbler_web'

    [ <=>                                                                                                                           ] 1.356       --.-K/s   in 0s     

2014-01-22 23:16:22 (23,2 MB/s) - `cobbler_web' saved [1356]

[root@geppetto ansible]#
[root@geppetto ansible]# wget https://geppetto.oma.be/cobbler_api --no-check-certificate
--2014-01-22 23:18:19--  https://geppetto.oma.be/cobbler_api
Resolving geppetto.oma.be... 192.168.16.49
Connecting to geppetto.oma.be|192.168.16.49|:443... connected.
WARNING: cannot verify geppetto.oma.be's certificate, issued by `/C=--/ST=SomeState/L=SomeCity/O=SomeOrganization/OU=SomeOrganizationalUnit/CN=geppetto.oma.be/emailAddress=root_at_geppetto.oma.be':
  Self-signed certificate encountered.
HTTP request sent, awaiting response... 502 Proxy Error
2014-01-22 23:18:19 ERROR 502: Proxy Error.

[root@geppetto ansible]#

This might point that the problem is rather with cobbler api than with ansible.

BTW: there is imho no firewalling:
[root@geppetto ansible]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination        

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        
[root@geppetto ansible]#

Michael you suggest debugging the script, what should I look for?
I'll post a grep in next message.

Joost Ringoot

unread,
Jan 22, 2014, 5:37:14 PM1/22/14
to ansible...@googlegroups.com

Hereby some grep output as promised in previous mail:
[root@geppetto ansible]# grep -i error -B 2 -A 2  cobbler.py.debuglog > errorswithsomelinesbeforeandsomeafter.log
[root@geppetto ansible]# [root@geppetto ansible]# cat errorswithsomelinesbeforeandsomeafter.log
argparse.py(64): __version__ = '1.2.1'
argparse.py(66):     'ArgumentParser',
argparse.py(67):     'ArgumentError',
argparse.py(68):     'ArgumentTypeError',
argparse.py(69):     'FileType',
argparse.py(70):     'HelpFormatter',
--
copy.py(51): import types
copy.py(52): from copy_reg import dispatch_table
copy.py(54): class Error(Exception):
 --- modulename: copy, funcname: Error
copy.py(54): class Error(Exception):
copy.py(55):     pass
copy.py(56): error = Error   # backward compatibility
copy.py(58): try:
copy.py(59):     from org.python.core import PyStringMap
copy.py(60): except ImportError:
copy.py(61):     PyStringMap = None
copy.py(63): __all__ = ["Error", "copy", "deepcopy"]
copy.py(65): def copy(x):
copy.py(98): _copy_dispatch = d = {}
--
locale.py(14): import sys, encodings, encodings.aliases
locale.py(15): import functools
locale.py(23): __all__ = ["getlocale", "getdefaultlocale", "getpreferredencoding", "Error",
locale.py(24):            "setlocale", "resetlocale", "localeconv", "strcoll", "strxfrm",
locale.py(25):            "str", "atof", "atoi", "format", "format_string", "currency",
--
argparse.py(677):     def _get_help_string(self, action):
argparse.py(691): def _get_action_name(argument):
argparse.py(704): class ArgumentError(Exception):
 --- modulename: argparse, funcname: ArgumentError
argparse.py(704): class ArgumentError(Exception):
argparse.py(709):     """
argparse.py(711):     def __init__(self, argument, message):
argparse.py(715):     def __str__(self):
argparse.py(724): class ArgumentTypeError(Exception):
 --- modulename: argparse, funcname: ArgumentTypeError
argparse.py(724): class ArgumentTypeError(Exception):
argparse.py(725):     """An error from trying to convert a command line string to a type."""
argparse.py(726):     pass
argparse.py(733): class Action(_AttributeHolder):
--
argparse.py(1439):     def _get_handler(self):
argparse.py(1448):     def _check_conflict(self, action):
argparse.py(1462):     def _handle_conflict_error(self, action, conflicting_actions):
argparse.py(1469):     def _handle_conflict_resolve(self, action, conflicting_actions):
argparse.py(1484): class _ArgumentGroup(_ActionsContainer):
--
argparse.py(1564):                  fromfile_prefix_chars=None,
argparse.py(1565):                  argument_default=None,
argparse.py(1566):                  conflict_handler='error',
argparse.py(1567):                  add_help=True):
argparse.py(1636):     def _get_kwargs(self):
--
argparse.py(2338):     def _print_message(self, message, file=None):
argparse.py(2347):     def exit(self, status=0, message=None):
argparse.py(2352):     def error(self, message):
cobbler.py(59): import ConfigParser
 --- modulename: ConfigParser, funcname: <module>
ConfigParser.py(88): """
ConfigParser.py(90): import re
ConfigParser.py(92): __all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError",
ConfigParser.py(93):            "InterpolationError", "InterpolationDepthError",
ConfigParser.py(94):            "InterpolationSyntaxError", "ParsingError",
ConfigParser.py(95):            "MissingSectionHeaderError",
ConfigParser.py(96):            "ConfigParser", "SafeConfigParser", "RawConfigParser",
ConfigParser.py(97):            "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
ConfigParser.py(99): DEFAULTSECT = "DEFAULT"
ConfigParser.py(101): MAX_INTERPOLATION_DEPTH = 10
ConfigParser.py(106): class Error(Exception):
 --- modulename: ConfigParser, funcname: Error
ConfigParser.py(106): class Error(Exception):
ConfigParser.py(107):     """Base class for ConfigParser exceptions."""
ConfigParser.py(109):     def _get_message(self):
--
ConfigParser.py(128):     def __repr__(self):
ConfigParser.py(131):     __str__ = __repr__
ConfigParser.py(133): class NoSectionError(Error):
 --- modulename: ConfigParser, funcname: NoSectionError
ConfigParser.py(133): class NoSectionError(Error):
ConfigParser.py(134):     """Raised when no section matches a requested option."""
ConfigParser.py(136):     def __init__(self, section):
ConfigParser.py(140): class DuplicateSectionError(Error):
 --- modulename: ConfigParser, funcname: DuplicateSectionError
ConfigParser.py(140): class DuplicateSectionError(Error):
ConfigParser.py(141):     """Raised when a section is multiply-created."""
ConfigParser.py(143):     def __init__(self, section):
ConfigParser.py(147): class NoOptionError(Error):
 --- modulename: ConfigParser, funcname: NoOptionError
ConfigParser.py(147): class NoOptionError(Error):
ConfigParser.py(148):     """A requested option was not found."""
ConfigParser.py(150):     def __init__(self, option, section):
ConfigParser.py(156): class InterpolationError(Error):
 --- modulename: ConfigParser, funcname: InterpolationError
ConfigParser.py(156): class InterpolationError(Error):
ConfigParser.py(157):     """Base class for interpolation-related exceptions."""
ConfigParser.py(159):     def __init__(self, option, section, msg):
ConfigParser.py(164): class InterpolationMissingOptionError(InterpolationError):
 --- modulename: ConfigParser, funcname: InterpolationMissingOptionError
ConfigParser.py(164): class InterpolationMissingOptionError(InterpolationError):
ConfigParser.py(165):     """A string substitution required a setting which was not available."""
ConfigParser.py(167):     def __init__(self, option, section, rawval, reference):
ConfigParser.py(177): class InterpolationSyntaxError(InterpolationError):
 --- modulename: ConfigParser, funcname: InterpolationSyntaxError
ConfigParser.py(177): class InterpolationSyntaxError(InterpolationError):
ConfigParser.py(179):     does not conform to the required syntax."""
ConfigParser.py(181): class InterpolationDepthError(InterpolationError):
 --- modulename: ConfigParser, funcname: InterpolationDepthError
ConfigParser.py(181): class InterpolationDepthError(InterpolationError):
ConfigParser.py(182):     """Raised when substitutions are nested too deeply."""
ConfigParser.py(184):     def __init__(self, option, section, rawval):
ConfigParser.py(192): class ParsingError(Error):
 --- modulename: ConfigParser, funcname: ParsingError
ConfigParser.py(192): class ParsingError(Error):
ConfigParser.py(193):     """Raised when a configuration file does not follow legal syntax."""
ConfigParser.py(195):     def __init__(self, filename):
ConfigParser.py(200):     def append(self, lineno, line):
ConfigParser.py(204): class MissingSectionHeaderError(ParsingError):
 --- modulename: ConfigParser, funcname: MissingSectionHeaderError
ConfigParser.py(204): class MissingSectionHeaderError(ParsingError):
ConfigParser.py(205):     """Raised when a key-value pair is found before any section header."""
ConfigParser.py(207):     def __init__(self, filename, lineno, line):
--
xmlrpclib.py(186): MAXINT =  2L**31-1
xmlrpclib.py(187): MININT = -2L**31
xmlrpclib.py(194): PARSE_ERROR       = -32700
xmlrpclib.py(195): SERVER_ERROR      = -32600
xmlrpclib.py(196): APPLICATION_ERROR = -32500
xmlrpclib.py(197): SYSTEM_ERROR      = -32400
xmlrpclib.py(198): TRANSPORT_ERROR   = -32300
xmlrpclib.py(201): NOT_WELLFORMED_ERROR  = -32700
xmlrpclib.py(202): UNSUPPORTED_ENCODING  = -32701
xmlrpclib.py(203): INVALID_ENCODING_CHAR = -32702
--
xmlrpclib.py(205): METHOD_NOT_FOUND      = -32601
xmlrpclib.py(206): INVALID_METHOD_PARAMS = -32602
xmlrpclib.py(207): INTERNAL_ERROR        = -32603
xmlrpclib.py(215): class Error(Exception):
 --- modulename: xmlrpclib, funcname: Error
xmlrpclib.py(215): class Error(Exception):
xmlrpclib.py(216):     """Base class for client errors."""
xmlrpclib.py(217):     def __str__(self):
xmlrpclib.py(230): class ProtocolError(Error):
 --- modulename: xmlrpclib, funcname: ProtocolError
xmlrpclib.py(230): class ProtocolError(Error):
xmlrpclib.py(231):     """Indicates an HTTP protocol error."""
xmlrpclib.py(232):     def __init__(self, url, errcode, errmsg, headers):
xmlrpclib.py(238):     def __repr__(self):
xmlrpclib.py(249): class ResponseError(Error):
 --- modulename: xmlrpclib, funcname: ResponseError
xmlrpclib.py(249): class ResponseError(Error):
xmlrpclib.py(250):     """Indicates a broken response package."""
xmlrpclib.py(251):     pass
xmlrpclib.py(262): class Fault(Error):
 --- modulename: xmlrpclib, funcname: Fault
xmlrpclib.py(262): class Fault(Error):
xmlrpclib.py(263):     """Indicates an XML-RPC fault package."""
xmlrpclib.py(264):     def __init__(self, faultCode, faultString, **extra):
--
xmlrpclib.py(515): try:
xmlrpclib.py(517):     import _xmlrpclib
xmlrpclib.py(520): except (AttributeError, ImportError):
xmlrpclib.py(521):     FastParser = FastUnmarshaller = None
xmlrpclib.py(523): try:
xmlrpclib.py(524):     import _xmlrpclib
xmlrpclib.py(526): except (AttributeError, ImportError):
xmlrpclib.py(527):     FastMarshaller = None
xmlrpclib.py(536): try:
xmlrpclib.py(537):     import sgmlop
xmlrpclib.py(540): except ImportError:
xmlrpclib.py(541):     SgmlopParser = None # sgmlop accelerator not available
xmlrpclib.py(579): try:
--
__init__.py(31): try:
__init__.py(32):     import _xmlplus
__init__.py(33): except ImportError:
__init__.py(34):     pass
 --- modulename: __init__, funcname: <module>
--
genericpath.py(17):     try:
genericpath.py(18):         st = os.stat(path)
genericpath.py(19):     except os.error:
genericpath.py(20):         return False
gettext.py(447):     for lang in nelangs:
--
genericpath.py(17):     try:
genericpath.py(18):         st = os.stat(path)
genericpath.py(19):     except os.error:
genericpath.py(20):         return False
gettext.py(447):     for lang in nelangs:
--
genericpath.py(17):     try:
genericpath.py(18):         st = os.stat(path)
genericpath.py(19):     except os.error:
genericpath.py(20):         return False
gettext.py(447):     for lang in nelangs:
--
genericpath.py(17):     try:
genericpath.py(18):         st = os.stat(path)
genericpath.py(19):     except os.error:
genericpath.py(20):         return False
gettext.py(447):     for lang in nelangs:
--
gettext.py(468):     if not mofiles:
gettext.py(469):         if fallback:
gettext.py(471):         raise IOError(ENOENT, 'No translation file found for domain', domain)
gettext.py(533):     except IOError:
gettext.py(534):         return message
 --- modulename: argparse, funcname: add_argument_group
--
genericpath.py(17):     try:
genericpath.py(18):         st = os.stat(path)
genericpath.py(19):     except os.error:
genericpath.py(20):         return False
gettext.py(447):     for lang in nelangs:
--
genericpath.py(17):     try:
genericpath.py(18):         st = os.stat(path)
genericpath.py(19):     except os.error:
genericpath.py(20):         return False
gettext.py(447):     for lang in nelangs:
--
genericpath.py(17):     try:
genericpath.py(18):         st = os.stat(path)
genericpath.py(19):     except os.error:
genericpath.py(20):         return False
gettext.py(447):     for lang in nelangs:
--
genericpath.py(17):     try:
genericpath.py(18):         st = os.stat(path)
genericpath.py(19):     except os.error:
genericpath.py(20):         return False
gettext.py(447):     for lang in nelangs:
--
gettext.py(468):     if not mofiles:
gettext.py(469):         if fallback:
gettext.py(471):         raise IOError(ENOENT, 'No translation file found for domain', domain)
gettext.py(533):     except IOError:
gettext.py(534):         return message
 --- modulename: argparse, funcname: add_argument_group
--
genericpath.py(17):     try:
genericpath.py(18):         st = os.stat(path)
genericpath.py(19):     except os.error:
genericpath.py(20):         return False
gettext.py(447):     for lang in nelangs:
--
genericpath.py(17):     try:
genericpath.py(18):         st = os.stat(path)
genericpath.py(19):     except os.error:
genericpath.py(20):         return False
gettext.py(447):     for lang in nelangs:
--
genericpath.py(17):     try:
genericpath.py(18):         st = os.stat(path)
genericpath.py(19):     except os.error:
genericpath.py(20):         return False
gettext.py(447):     for lang in nelangs:
--
genericpath.py(17):     try:
genericpath.py(18):         st = os.stat(path)
genericpath.py(19):     except os.error:
genericpath.py(20):         return False
gettext.py(447):     for lang in nelangs:
--
gettext.py(468):     if not mofiles:
gettext.py(469):         if fallback:
gettext.py(471):         raise IOError(ENOENT, 'No translation file found for domain', domain)
gettext.py(533):     except IOError:
gettext.py(534):         return message
 --- modulename: argparse, funcname: add_argument
[root@geppetto ansible]#

Joost Ringoot

unread,
Jan 27, 2014, 7:45:43 AM1/27/14
to ansible...@googlegroups.com
I looked a bit further, did RTFM of cobbler, and found this:
https://fedorahosted.org/cobbler/wiki/CobblerXmlrpc
Where I did a test with the included example code:

#!/usr/bin/python import xmlrpclib server = xmlrpclib.Server("http://127.0.0.1/cobbler_api") server = xmlrpclib.Server("http://127.0.0.1/cobbler_api") print server.get_distros() print server.get_profiles() print server.get_systems() print server.get_images() print server.get_repos()

This gives a lot of output, not well formatted, but I recognise what is stored in cobbler.

So imho, the cobbler_api works, ... but not the way the cobbler.py script tries present data from it.

Thanks,

Joost

Michael DeHaan

unread,
Jan 27, 2014, 8:34:34 AM1/27/14
to ansible...@googlegroups.com
That's curious.

I wrote that script against a live Cobbler install and we've got users using it in the wild.

Unfortunately, this isn't something we really have time to troubleshoot here.  It is something that we'd help support customers with, but it involves replicating and digging inside of your Cobbler setup, so it's a bit out of scope for ansible-project's mailing list.




--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Joost Ringoot

unread,
Feb 4, 2014, 3:52:32 AM2/4/14
to ansible...@googlegroups.com
Hi Michael,

That's really no problem. I just wanted to give it a go since it was in the tutorial.
Thanks for looking into it anyway.

I am glad I am now on http://cfgmgmtcamp.eu/ , the tutors here are great, I am learning a lot here.

Joost


Op maandag 27 januari 2014 14:34:34 UTC+1 schreef Michael DeHaan:

Vincent Van der Kussen

unread,
Feb 4, 2014, 4:02:18 AM2/4/14
to ansible...@googlegroups.com
I'm about to test cobbler to. I might have a look when I find the time.

Maybe later in the afternoon at cgmgmntcamp.

Vincent

Wouter Jagers

unread,
Feb 8, 2014, 6:07:14 PM2/8/14
to ansible...@googlegroups.com
Hi Joost,

I just spent some time digging for the same. Turns out that my existing systems did not have "management" set and were therefore not included in the results.

Should this be the case, you should start getting output after issuing one of these:
# cobbler system edit --name=somenode --management=yes

Cheers
Wouter

Joost Ringoot

unread,
Feb 11, 2014, 10:17:16 AM2/11/14
to ansible...@googlegroups.com
Hi Wouter,

Thank you for looking into this and sharing your findings Wouter.
Good to hear that enabling management fixed it for you.
Alas for me that's not the case.

[root@geppetto ansible]# cobbler system list
   metop-20.oma.be
   metop-28.oma.be
   zotac-09
   zotac-24.oma.be
   zotac-29
   zotac-36
[root@geppetto ansible]#
[root@geppetto ansible]# ./cobbler.py
{}
[root@geppetto ansible]# cobbler system edit --name=zotac-29 --management=yes
[root@geppetto ansible]# ./cobbler.py
{}

Whereas the api still works, because the following line gives lots of output (too much to be readable):

[root@geppetto ansible]# ./cobblerdemo.py | grep zotac-29

and this being the contents:
[root@geppetto ansible]# cat ./cobblerdemo.py

#!/usr/bin/python
import xmlrpclib
server = xmlrpclib.Server("http://127.0.0.1/cobbler_api")
server = xmlrpclib.Server("http://127.0.0.1/cobbler_api")
print server.get_systems()
[root@geppetto ansible]#


Cheers,

Joost

Op zondag 9 februari 2014 00:07:14 UTC+1 schreef Wouter Jagers:

Tomasz Leśniewski

unread,
Mar 7, 2014, 9:26:16 AM3/7/14
to ansible...@googlegroups.com
It is required to have filled both "management interface" and "dns name" (for the same interface if you have more than one).

Joost Ringoot

unread,
Mar 17, 2014, 10:23:45 AM3/17/14
to ansible...@googlegroups.com
With help of Wouter Jagers, the script now picks up the systems installed by cobbler.
I needed to perform something like this for the hosts
 
cobbler system edit --name=$COBBLERHOSTNAME --dns-name=$FQDN --management=true

Thanks Wouter.
Thanks also to Michael for all your enormous work for the community.
Thanks also to Vincent and Tomasz and others I might forget.

Michael DeHaan

unread,
Mar 17, 2014, 10:51:23 AM3/17/14
to ansible...@googlegroups.com
IIRC, the management=true stuff is after my time with the project.

IMHO, the inventroy script shouldn't care about this, but it may be something on the API side that was not returning something.




--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages