Skip to content

Commit

Permalink
Update Changelog and readme, tag 0.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
tobami committed Mar 31, 2011
1 parent 7137807 commit d58ff4f
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 33 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
*.pyc
MANIFEST
15 changes: 15 additions & 0 deletions CHANGELOG
Expand Up @@ -2,12 +2,26 @@
Little Chef Change Log
======================


Version 0.5.0 March 30, 2011
-----------------------------------------
* NEW: Igal added site-cookbooks support
* NEW: Igal made LittleChef run with the newest fabric. Fabric 1.0+ is now required
* NEW: Special effects: colored output!
* NEW: Nicer displaying of node, roles and cookbook information
* FIX: Igal changed node's chef-solo directory to improve security,
together with other fixes
* FIX: Added first unit tests!



Version 0.4.2 March 10, 2011
-----------------------------------------
* NEW: cocoy added keypair support
* HOTFIX: Require exactly fabric 0.9.3, as fabric 1.0 has been released with
backwards incompatible changes that break LittleChef


Version 0.4.1 January 19, 2011
-----------------------------------------
* NEW: "list_recipes" now shows only a simple name list.
Expand All @@ -20,6 +34,7 @@ Version 0.4.1 January 19, 2011
* FIX: emilsit refactored new_deployment so that it doesn't use fabric
but directly python instead. Fixes auth.cfg creation for some OSs


Version 0.4.0 December 9, 2010
-----------------------------------------
* NEW: The saved node.json doesn't have any custom littlechef fields anymore
Expand Down
14 changes: 9 additions & 5 deletions README.textile
Expand Up @@ -14,6 +14,7 @@ It all starts in the kitchen, your deployment directory, which you should keep u
@auth.cfg@: Authentication information needed to be able to connect to the nodes
@nodes/@: After recipes are run on nodes, their configuration is stored here
@cookbooks/@: This will be your cookbooks repository
@site-cookbooks/@: Here you can override upstream cookbooks (Opscode's, for example)
@roles/@: Where Chef roles are defined

Whenever you apply a recipe to a node, all needed cookbooks (including dependencies) and all roles are gzipped and uploaded to that node, to the @/tmp/chef-solo/@ directory. A 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.
Expand All @@ -26,19 +27,21 @@ h3. Requirements

* Python 2.6+
* Setuptools
* Fabric 0.9.3
* Fabric 1.0.1+

All needed packages are installed by typing
All needed packages are installed by typing:
@sudo apt-get install python-pip python-fabric@ for Debian and Ubuntu
or
@yum install python-pip fabric@ for RHEL and CentOS

Note: If your distribution doesn't have an up-to-date version of Fabric, don't install the distribution package: the installation step will take care of that dependency.

h3. Installation

You can install Little Chef 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.
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 Little Chef's executable.

h2. Usage

Expand Down Expand Up @@ -92,8 +95,9 @@ h3. Consulting the inventory
* @cook list_nodes_with_recipe:MYRECIPE@: The same as above but it only lists nodes which have associated the recipe @MYRECIPE@
* @cook list_nodes_with_role:MYROLE@: The same as above but it only lists nodes which have associated the role @MYROLE@
* @cook list_recipes@: Lists all available recipes
* @cook list_recipes_detailed@: Same as above, but shows description, dependencies and attributes
* @cook list_roles@: Lists all available roles, with associated information
* @cook list_recipes_detailed@: Same as above, but shows description, version, dependencies and attributes
* @cook list_roles@: Lists all available roles
* @cook list_roles@: Same as above, but shows description and attributes

h3. Using Little Chef as a library

Expand Down
62 changes: 35 additions & 27 deletions littlechef.py
Expand Up @@ -23,7 +23,7 @@
from fabric.contrib.console import confirm
from fabric import colors

VERSION = (0, 5, '0beta')
VERSION = (0, 5, 0)
version = ".".join([str(x) for x in VERSION])

NODEPATH = "nodes/"
Expand Down Expand Up @@ -76,7 +76,7 @@ def deploy_chef(gems="no", ask="yes"):
abort('no node specified\nUsage: cook node:MYNODE deploy_chef:MYDISTRO')

distro_type, distro = _check_distro()
print
print ""
message = 'Are you sure you want to install Chef at the node {0}'.format(
env.host_string)
if gems == "yes":
Expand All @@ -101,7 +101,9 @@ def deploy_chef(gems="no", ask="yes"):
_configure_chef_solo()

def recipe(recipe, save=False):
'''Execute the given recipe, ignores existing config unless save=True'''
"""Apply the given recipe to a node
ignores existing config unless save=True
"""
# Do some checks
if not env.host_string:
abort('no node specified\nUsage: cook node:MYNODE recipe:MYRECIPE')
Expand All @@ -123,7 +125,8 @@ def recipe(recipe, save=False):
_sync_node(filepath)

def role(role, save=False):
'''Execute the given role, ignores existing config unless save=True'''
"""Apply the given role to a node
ignores existing config unless save=True"""
# Do some checks
if not env.host_string:
abort('no node specified\nUsage: cook node:MYNODE role:MYROLE')
Expand All @@ -148,7 +151,7 @@ def configure():
msg += 'Usage:\n cook node:MYNODE configure\n cook node:all configure'
abort(msg)

print(colors.cyan("\n== Configuring {0} ==".format(env.host_string)))
print(colors.yellow("\n== Configuring {0} ==".format(env.host_string)))

configfile = env.host_string + ".json"
if not os.path.exists(NODEPATH + configfile):
Expand Down Expand Up @@ -198,7 +201,7 @@ def list_recipes():

@hosts('api')
def list_recipes_detailed():
'''Show a list of all available recipes'''
'''Show information for all recipes'''
for recipe in _get_recipes():
_print_recipe(recipe)

Expand All @@ -212,7 +215,7 @@ def list_roles():

@hosts('api')
def list_roles_detailed():
'''Show a list of all available roles'''
'''Show information for all roles'''
for role in _get_roles():
_print_role(role)

Expand Down Expand Up @@ -300,9 +303,7 @@ def _check_distro():
rpm_distros = ['centos', 'rhel', 'sl']

with settings(
hide('warnings', 'running', 'stdout', 'stderr'),
warn_only=True
):
hide('warnings', 'running', 'stdout', 'stderr'), warn_only=True):

output = sudo('cat /etc/issue')
if 'Debian GNU/Linux 5.0' in output:
Expand Down Expand Up @@ -417,9 +418,10 @@ def _configure_node(configfile):
with hide('running'):
print "Uploading node.json..."
remote_file = '/root/{0}'.format(configfile.split("/")[-1])
put(configfile, remote_file, use_sudo=True, mode=_file_mode)
sudo('chown root:root {0}'.format(remote_file)),
sudo('mv {0} /etc/chef/node.json'.format(remote_file)),
with hide('stdout'):# Some shells output 'sudo password'
put(configfile, remote_file, use_sudo=True, mode=_file_mode)
sudo('chown root:root {0}'.format(remote_file)),
sudo('mv {0} /etc/chef/node.json'.format(remote_file)),

print "\n== Cooking ==\n"
with settings(hide('warnings'), warn_only=True):
Expand All @@ -445,7 +447,8 @@ def _update_cookbooks(configfile):
'''Uploads needed cookbooks and all roles to a node'''
# Clean up node
for path in ['roles', 'cache'] + _cookbook_paths:
sudo('rm -rf {0}/{1}'.format(_node_work_path, path))
with hide('stdout'):
sudo('rm -rf {0}/{1}'.format(_node_work_path, path))

cookbooks = []
with open(configfile, 'r') as f:
Expand All @@ -463,18 +466,21 @@ def _update_cookbooks(configfile):

# Fetch cookbooks needed for role recipes
for role in _get_roles_in_node(node):
with open('roles/' + role + '.json', 'r') as f:
try:
roles = json.loads(f.read())
except json.decoder.JSONDecodeError as e:
msg = 'Little Chef found the following error in your'
msg += ' "{0}" role file:\n {1}'.format(role, str(e))
abort(msg)
# Reuse _get_recipes_in_node to extract recipes in a role
for recipe in _get_recipes_in_node(roles):
recipe = recipe.split('::')[0]
if recipe not in cookbooks:
cookbooks.append(recipe)
try:
with open('roles/' + role + '.json', 'r') as f:
try:
roles = json.loads(f.read())
except json.decoder.JSONDecodeError as e:
msg = 'Little Chef found the following error in your'
msg += ' "{0}" role file:\n {1}'.format(role, str(e))
abort(msg)
# Reuse _get_recipes_in_node to extract recipes in a role
for recipe in _get_recipes_in_node(roles):
recipe = recipe.split('::')[0]
if recipe not in cookbooks:
cookbooks.append(recipe)
except IOError:
abort(colors.red("Role '{0}' not found".format(role)))

# Fetch dependencies
warnings = []
Expand Down Expand Up @@ -511,7 +517,7 @@ def _update_cookbooks(configfile):
def _upload_and_unpack(source):
'''Packs the given directory, uploads it to the node
and unpacks it in the "_node_work_path" (typically '/var/chef-solo') directory'''
with hide('running'):
with hide('running', 'stdout'):
# Local archive relative path
local_archive = 'temp.tar.gz'
# Remote archive absolute path
Expand All @@ -538,6 +544,8 @@ def _upload_and_unpack(source):
# Report error with remote paths
msg = "the {0} directory was not found at ".format(_node_work_path)
msg += "the node. Is Chef correctly installed?"
msg += "\nYou can deploy chef-solo by typing:\n"
msg += " cook node:{0} deploy_chef".format(env.host)
abort(msg)
with cd(_node_work_path):
# Install the remote copy of archive
Expand Down
2 changes: 1 addition & 1 deletion tests/tests.py
Expand Up @@ -28,7 +28,7 @@ def test_version(self):
"""Should output the correct Little Chef version"""
resp, error = self.execute(['../cook', '-v'])
self.assertEquals(error, "")
self.assertTrue('littlechef 0.5.0beta' in resp)
self.assertTrue('littlechef 0.5.0' in resp)

def test_list_commands(self):
"""Should output a list of available commands"""
Expand Down

0 comments on commit d58ff4f

Please sign in to comment.