Gripp
Gripp

Reputation: 166

python chef works in console not in script

I can run:

import chef
chef.autoconfigure()
for node in chef.Node.list():
    if "auto" in node.lower():
        print "deleting node " + node
        nodeObj = chef.Node(node)
        nodeObj.delete()

in a console directly, but when I try to run it as a script: python2.7 test.py I get the following error:

Traceback (most recent call last):
  File "test.py", line 38, in <module>
    for node in chef.Node.list():
  File "/usr/local/lib/python2.7/site-packages/chef/base.py", line 86, in list
    names = [name for name, url in api[cls.url].iteritems()]
TypeError: 'NoneType' object has no attribute '__getitem__'

I used the console verify that

>>> chef.__path__
['/usr/local/lib/python2.7/site-packages/chef']

So, the machine is the same, the version of python is the same, and the module is the same. Why could this possibly happen?

Upvotes: 1

Views: 1716

Answers (3)

Left Byte
Left Byte

Reputation: 11

You can import your local configuration using chef.autoconfigure. For example:

from chef import autoconfigure, Client, Node
api = autoconfigure()

http://pychef.readthedocs.org/en/latest/api.html#chef.autoconfigure

Try to find a knife or chef-client config file to load parameters from, starting from either the given base path or the current working directory.

Upvotes: 1

stavxyz
stavxyz

Reputation: 2035

While I don't know why that ChefAPI object does not persist in a script, I found that I must pass my Search object my ChefAPI object, as seen as a keyword argument in the signature here. And like in your case, this wasn't necessary when testing my code in the console.

In my case, I generate the ChefAPI object from_config_file(), and pass it to my Search object like this:

import chef
chefapiobject = chef.chefAPI.from_config_file('knife.rb')
nodes = chef.Search('node', 'roles:worker', api=chefapiobject)

In the console, this works without passing api=chefapiobject

Upvotes: 1

Gripp
Gripp

Reputation: 166

I figured out that when ran as a script pyChef does not correctly identify the knife.rb file for the autoconfigure step.

This is what got it working instead:

with chef.ChefAPI('http://example.com:4000', '/root/.chef/client.pem', 'client'):
    for node in chef.Node.list():
        if "auto" in node.lower():
            print "deleting node " + node
            nodeObj = chef.Node(node)
            nodeObj.delete()

Note that I do not know why it was unable to use the knife.rb file correctly in one case and not the other (I verified that the same cwd was being used in both cases... - even tried pointing the autoconfigure('/folder/of/knife.rb') with no luck.

Upvotes: 2

Related Questions