Skip to content

Commit

Permalink
Rename "cook" command to "fix" so that we can be packaged for Debian
Browse files Browse the repository at this point in the history
  • Loading branch information
tobami committed Sep 12, 2011
1 parent c46660b commit 089e990
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 86 deletions.
42 changes: 20 additions & 22 deletions README.md
Expand Up @@ -68,8 +68,6 @@ pip will then take care of the extra Python dependencies
You can install LittleChef directly from the PyPI:
`pip install littlechef`

Note: your distribution may have a `cook` package that also provides a `cook` executable. If you have installed it, you need to remove it to avoid collisions with LittleChef's executable.
## Usage

### Disclaimer
Expand All @@ -81,7 +79,7 @@ Careful what you do with your nodes!:
### Local Setup
`cook new_kitchen` will create inside the current directory a few files and directories for LittleChef to be able to cook: `auth.cfg`, `roles/`, `data_bags/`, `nodes/`, `cookbooks/` and `site-cookbooks/`. You can create and have as many kitchens as you like on your computer.
`fix new_kitchen` will create inside the current directory a few files and directories for LittleChef to be able to cook: `auth.cfg`, `roles/`, `data_bags/`, `nodes/`, `cookbooks/` and `site-cookbooks/`. You can create and have as many kitchens as you like on your computer.
### Authentication
Expand Down Expand Up @@ -116,48 +114,48 @@ For convenience, there is a command that allows you to deploy chef-solo
to a node.
The best way is to use the packages from the [Opscode repository][]:
`cook node:MYNODE deploy_chef`
`fix node:MYNODE deploy_chef`
LittleChef will try to autodetect the distro type and version of that node, and will use the appropriate installation method and packages.
You can also install Chef Solo with gems and/or without asking for confirmation:
`cook node:MYNODE deploy_chef:gems=yes,ask=no`
`fix node:MYNODE deploy_chef:gems=yes,ask=no`
Currently supported Linux distributions include Ubuntu, Debian, CentOS, RHEL, Scientific Linux and Gentoo.
When using the Debian repository, you need to take into account that Opscode has separated Chef versions in different repos. Current default is Chef 0.10, but you can install Chef 0.9 by typing:
`cook node:MYNODE deploy_chef:version=0.9`
`fix node:MYNODE deploy_chef:version=0.9`
Note that if you already have Chef Solo installed on your nodes, you won't need this. Also, if you previously installed Chef using the Gem procedure, please don't use the deploy_chef package installation method, removing the gem first might be a good idea.
### Cooking
Note: Don't cook outside of a kitchen!

* `cook -l`: Show a list of all available orders
* `cook node:MYNODE recipe:MYRECIPE`: Cook a recipe on a particular node by giving its hostname or IP. "Subrecipes" like `nginx::source` are supported. Note that the first time this is run for a node, a configuration file will be created at `nodes/myhostname.json`. You can then edit this file to override recipe attributes, for example. Further runs of this command will not overwrite this configuration file
* `cook node:MYNODE role:MYROLE`: The same as above but role-based
* `cook node:MYNODE1,MYNODE2`: Configures several pre-configured nodes, in order
* `cook node:all`: It will apply all roles, recipes and attributes defined for each and every node in `nodes/`
* `cook debug node:MYNODE`: You can start all your commands with `cook debug` to see all Chef Solo debugging information
* `fix -l`: Show a list of all available orders
* `fix node:MYNODE recipe:MYRECIPE`: Cook a recipe on a particular node by giving its hostname or IP. "Subrecipes" like `nginx::source` are supported. Note that the first time this is run for a node, a configuration file will be created at `nodes/myhostname.json`. You can then edit this file to override recipe attributes, for example. Further runs of this command will not overwrite this configuration file
* `fix node:MYNODE role:MYROLE`: The same as above but role-based
* `fix node:MYNODE1,MYNODE2`: Configures several pre-configured nodes, in order
* `fix node:all`: It will apply all roles, recipes and attributes defined for each and every node in `nodes/`
* `fix debug node:MYNODE`: You can start all your commands with `fix debug` to see all Chef Solo debugging information

Once a node has a config file, the command you will be using most often is `cook node:MYNODE configure`, which allows you to repeatedly tweak the recipes and attributes for a node and rerun the configuration.
Once a node has a config file, the command you will be using most often is `fix node:MYNODE configure`, which allows you to repeatedly tweak the recipes and attributes for a node and rerun the configuration.

### Consulting the inventory

* `cook list_nodes`: Lists all configured nodes, showing its associated recipes and roles
* `cook list_nodes_detailed`: Same as above, but it also shows allattributes
* `cook list_nodes_with_recipe:MYRECIPE`: The same as above but itonly lists nodes which have associated the recipe `MYRECIPE`
* `cook list_nodes_with_role:MYROLE`: The same as above but it onlylists nodes which have associated the role `MYROLE`
* `cook list_recipes`: Lists all available recipes
* `cook list_recipes_detailed`: Same as above, but shows description,version, dependencies and attributes
* `cook list_roles`: Lists all available roles
* `cook list_roles_detailed`: Same as above, but shows description and attributes
* `fix list_nodes`: Lists all configured nodes, showing its associated recipes and roles
* `fix list_nodes_detailed`: Same as above, but it also shows allattributes
* `fix list_nodes_with_recipe:MYRECIPE`: The same as above but itonly lists nodes which have associated the recipe `MYRECIPE`
* `fix list_nodes_with_role:MYROLE`: The same as above but it onlylists nodes which have associated the role `MYROLE`
* `fix list_recipes`: Lists all available recipes
* `fix list_recipes_detailed`: Same as above, but shows description,version, dependencies and attributes
* `fix list_roles`: Lists all available roles
* `fix list_roles_detailed`: Same as above, but shows description and attributes

### Using LittleChef as a library

You can import littlechef.py into your own Python project. The following
script is equivalent to using the `cook` orders:
script is equivalent to using the `fix` orders:

```python
from littlechef import runner as lc
Expand Down
16 changes: 8 additions & 8 deletions cook → fix
Expand Up @@ -5,7 +5,7 @@ import os


# Messages
NO_ORDER = "No order given. Type 'cook -l' for a list of orders\n"
NO_ORDER = "No order given. Type 'fix -l' for a list of orders\n"
VERSION = 'LittleChef {0}'
INSTALL_ERROR = "LittleChef was not correctly installed: "\
"Couldn't import littlechef.py"
Expand All @@ -25,13 +25,13 @@ except ImportError:
if not sys.argv:
print(NO_ORDER)
else:
if (os.path.basename(sys.argv[0]).startswith('cook')):
# In windows, the first argument may be just "cook"
cook_cmd = sys.argv[0]
if (os.path.basename(sys.argv[0]).startswith('fix')):
# In windows, the first argument may be just "fix"
fix_cmd = sys.argv[0]
else:
cook_cmd = None
if len(sys.argv) == 1 and cook_cmd:
# All that is in sys.argv is the cook command.
fix_cmd = None
if len(sys.argv) == 1 and fix_cmd:
# All that is in sys.argv is the fix command.
print(NO_ORDER)
else:
# Check for version, that overrides everything else.
Expand All @@ -40,7 +40,7 @@ else:
print(VERSION.format(littlechef.version))
sys.exit(0)
# Otherwise, insert our fabfile at the correct place
if cook_cmd:
if fix_cmd:
sys.argv[1:1] = ['-f', file_path]
else:
sys.argv[0:0] = ['-f', file_path]
Expand Down
2 changes: 1 addition & 1 deletion cook.cmd → fix.cmd
@@ -1,3 +1,3 @@
@setlocal
@python.exe %~dp0cook %*
@python.exe %~dp0fix %*
@"%COMSPEC%" /c exit
36 changes: 18 additions & 18 deletions littlechef/chef.py
Expand Up @@ -66,26 +66,35 @@ def sync_node(node):
It also injects the ipaddress to the node's config file if not already
existent.
"""
current_node = _build_node_data_bag()
with lib.credentials():
# Get merged attributes
current_node = _build_node_data_bag()
# Always configure Chef Solo
solo.configure(current_node)
_synchronize_node()
_remove_node_data_bag()
# Everything was configured alright, so save the node configuration
filepath = save_config(node, _get_ipaddress(node))
_configure_node(filepath)
_synchronize_node(filepath)
_remove_node_data_bag()
_configure_node()


def _synchronize_node():
def _synchronize_node(configfile):
"""Performs the Synchronize step of a Chef run:
Uploads all cookbooks, all roles and all databags to a node and add the
patch for data bags
Returns the node object of the node which is about to be configured, or None
if this node object cannot be found.
"""
print "Synchronizing cookbooks, roles and data bags..."
print "Synchronizing node, cookbooks, roles and data bags..."
# First upload node.json
remote_file = '/etc/chef/node.json'
put(configfile, remote_file, use_sudo=True, mode=400)
with hide('stdout'):
sudo('chown root:root {0}'.format(remote_file)),
# Remove local temporary node file
os.remove(configfile)
# Synchronize kitchen
rsync_project(
node_work_path, './',
exclude=(
Expand Down Expand Up @@ -244,18 +253,9 @@ def _add_search_patch():
os.path.join(lib_path, filename), use_sudo=True)


def _configure_node(configfile):
def _configure_node():
"""Exectutes chef-solo to apply roles and recipes to a node"""
print "Uploading node.json..."
remote_file = '/root/{0}'.format(configfile.split("/")[-1])
# Ensure secure permissions
put(configfile, remote_file, use_sudo=True, mode=400)
with hide('stdout'):
sudo('chown root:root {0}'.format(remote_file)),
sudo('mv {0} /etc/chef/node.json'.format(remote_file)),
# Remove local temporary node file
os.remove(configfile)
print colors.yellow("\n== Cooking ==")
print("\nCooking...")
with settings(hide('warnings', 'running'), warn_only=True):
output = sudo(
'chef-solo -l {0} -j /etc/chef/node.json'.format(env.loglevel))
Expand All @@ -265,7 +265,7 @@ def _configure_node(configfile):
colors.red(
"\nFAILED: Chef Solo is not installed on this node"))
print(
"Type 'cook nodes:{0} deploy_chef' to install it".format(
"Type 'fix nodes:{0} deploy_chef' to install it".format(
env.host))
abort("")
else:
Expand Down
6 changes: 3 additions & 3 deletions littlechef/runner.py
Expand Up @@ -293,9 +293,9 @@ def _readconfig():
missing_str = lambda m: ' and '.join(', '.join(m).rsplit(', ', 1))
if not in_a_kitchen:
msg = "Couldn't find {0}. ".format(missing_str(missing))
msg += "Are you are executing 'cook' outside of a kitchen?\n"\
msg += "Are you are executing 'fix' outside of a kitchen?\n"\
"To create a new kitchen in the current directory "\
" type 'cook new_kitchen'"
" type 'fix new_kitchen'"
abort(msg)
config = ConfigParser.ConfigParser()
config.read("auth.cfg")
Expand Down Expand Up @@ -349,7 +349,7 @@ def _readconfig():
abort('You need to define a password or a keypair-file in auth.cfg.')


# Only read config if cook is being used and we are not creating a new kitchen
# Only read config if fix is being used and we are not creating a new kitchen
import littlechef
if littlechef.COOKING:
# Called from command line
Expand Down
2 changes: 1 addition & 1 deletion littlechef/version.py
@@ -1,2 +1,2 @@
VERSION = (0, 7, '0alpha')
VERSION = (1, 0, '0beta')
version = ".".join([str(x) for x in VERSION])
14 changes: 6 additions & 8 deletions setup.py
Expand Up @@ -6,9 +6,9 @@
import platform


scripts = ['cook']
scripts = ['fix']
if platform.system() == 'Windows':
scripts += ['cook.cmd']
scripts += ['fix.cmd']

setup(
name="littlechef",
Expand All @@ -18,13 +18,13 @@
author_email="tobami@googlemail.com",
url="http://github.com/tobami/littlechef",
download_url="http://github.com/tobami/littlechef/archives/master",
keywords=["chef", "devops"],
keywords=["chef", "devops", "operations", "sysadmin"],
install_requires=['fabric>=1.0.2', 'simplejson'],
packages=['littlechef'],
package_data={
'littlechef': ['search.rb', 'solo.rb', 'parser.rb', 'environment.rb']
},
scripts=['cook'],
scripts=['fix'],
test_suite='nose.collector',
classifiers=[
"Programming Language :: Python",
Expand All @@ -45,13 +45,11 @@
node.json file gets created on the fly and uploaded, and Chef Solo gets
executed at the remote node, using node.json as the node configuration and the
pre-installed solo.rb for Chef Solo configuration. Cookbooks, data bags and roles
are configured to be found at (/var/chef-solo/).
are configured to be found at (/tmp/chef-solo/).
The result is that you can play as often with your recipes and nodes as you
want, without having to worry about a central Chef repository, Chef server nor
anything else. You can make small changes to your cookbooks and test them again
and again without having to commit the changes. LittleChef brings sanity
to cookbook development.
anything else. You are immediately ready to cook.
.. _Chef: http://wiki.opscode.com/display/chef/Home
"""
Expand Down

0 comments on commit 089e990

Please sign in to comment.