Skip to content
Browse files

Configuration runs will now ignore nodes with 'dummy=true'

  • Loading branch information...
1 parent 29dfd78 commit 0f312f31df8cd65b591a18602a5a969729a4b055 @tobami committed Apr 4, 2012
Showing with 43 additions and 19 deletions.
  1. +2 −1 README.md
  2. +8 −4 littlechef/runner.py
  3. +7 −0 tests/nodes/testnode4.json
  4. +5 −0 tests/test_command.py
  5. +21 −14 tests/test_lib.py
View
3 README.md
@@ -177,7 +177,8 @@ List of commands:
* `fix -v`: Shows the version number
* `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 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. Nodes with the attribute
+`dummy` set to `true` will *not* be configured
* `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/`
View
12 littlechef/runner.py
@@ -123,11 +123,15 @@ def node(*nodes):
for hostname in env.hosts:
env.host = hostname
env.host_string = hostname
- lib.print_header("Configuring {0}".format(env.host))
- # Read node data and configure node
node = lib.get_node(env.host)
- if not __testing__:
- chef.sync_node(node)
+ if node.get('dummy'):
+ lib.print_header("Skipping dummy: {0}".format(env.host))
+ else:
+ lib.print_header("Configuring {0}".format(env.host))
+ if __testing__:
+ print "TEST: would now configure {0}".format(env.host)
+ else:
+ chef.sync_node(node)
def deploy_chef(gems="no", ask="yes", version="0.10",
View
7 tests/nodes/testnode4.json
@@ -0,0 +1,7 @@
+{
+ "chef_environment": "production",
+ "dummy": true,
+ "run_list": [
+ "recipe[man]"
+ ]
+}
View
5 tests/test_command.py
@@ -134,6 +134,11 @@ def test_one_node(self):
# Will try to configure testnode2 and will fail DNS lookup
self.assertTrue("tal error: Name lookup failed for testnode2" in error,
error)
+ def test_dummy_node(self):
+ """Should *not* configure a node when dummy is set to true"""
+ resp, error = self.execute([fix, 'node:testnode4'])
+ self.assertFalse("Configuring" in resp)
+ self.assertTrue("== Skipping dummy: testnode4 ==" in resp)
def test_several_nodes(self):
"""Should try to configure two nodes"""
View
35 tests/test_lib.py
@@ -35,10 +35,11 @@ def tearDown(self):
'tmp_testnode1',
'tmp_testnode2',
'tmp_testnode3.mydomain.com',
- 'tmp_testnode4']:
+ 'tmp_testnode4',
+ 'tmp_extranode']:
if os.path.exists(nodename + '.json'):
os.remove(nodename + '.json')
- extra_node = os.path.join("nodes", "testnode4" + '.json')
+ extra_node = os.path.join("nodes", "extranode" + '.json')
if os.path.exists(extra_node):
os.remove(extra_node)
runner.env.chef_environment = None
@@ -72,7 +73,7 @@ def test_nodes_with_role_in_env_empty(self):
self.assertEquals(runner.env.hosts, [])
def test_nodes_one(self):
- """Should configure one node"""
+ """Should configure one node when an existing node name is given"""
runner.node('testnode1')
self.assertEquals(runner.env.hosts, ['testnode1'])
@@ -82,10 +83,10 @@ def test_nodes_several(self):
self.assertEquals(runner.env.hosts, ['testnode1', 'testnode2'])
def test_nodes_all(self):
- """Should configure all nodes"""
+ """Should configure all nodes when 'all' is given"""
runner.node('all')
self.assertEquals(runner.env.hosts,
- ['testnode1', 'testnode2', 'testnode3.mydomain.com'])
+ ['testnode1', 'testnode2', 'testnode3.mydomain.com', 'testnode4'])
def test_nodes_all_in_env(self):
"""Should configure all nodes in a given environment"""
@@ -129,12 +130,18 @@ def test_get_nodes(self):
"chef_environment": "production",
'run_list': ['recipe[subversion]', 'recipe[vim]']
},
+ {
+ 'dummy': True,
+ 'chef_environment': 'production',
+ 'name': 'testnode4',
+ 'run_list': ['recipe[man]']
+ },
]
self.assertEquals(lib.get_nodes(), expected)
def test_get_nodes_in_env(self):
"""Should list all nodes in the given environment"""
- self.assertEquals(len(lib.get_nodes("production")), 2)
+ self.assertEquals(len(lib.get_nodes("production")), 3)
self.assertEquals(len(lib.get_nodes("staging")), 1)
def test_nodes_with_role(self):
@@ -179,13 +186,13 @@ def test_nodes_with_recipe(self):
nodes = list(lib.get_nodes_with_recipe('vim'))
self.assertEquals(len(nodes), 1)
self.assertEquals(nodes[0]['name'], 'testnode3.mydomain.com')
- # man recipe inside role "all_you_can_eat"
+ # man recipe inside role "all_you_can_eat" and in testnode4
nodes = list(lib.get_nodes_with_recipe('man'))
- self.assertEquals(len(nodes), 1)
+ self.assertEquals(len(nodes), 2)
self.assertEquals(nodes[0]['name'], 'testnode2')
# Get node with at least one recipe
nodes = list(lib.get_nodes_with_recipe('*'))
- self.assertEquals(len(nodes), 3)
+ self.assertEquals(len(nodes), 4)
nodes = list(lib.get_nodes_with_role(''))
self.assertEquals(len(nodes), 0)
@@ -234,15 +241,15 @@ def tearDown(self):
super(TestChef, self).tearDown()
def test_save_config(self):
- """Should create a tmp_testnode4.json and a nodes/testnode4.json config
+ """Should create a tmp_extranode.json and a nodes/extranode.json config
file
"""
# Save a new node
- env.host_string = 'testnode4'
+ env.host_string = 'extranode'
run_list = ["role[base]"]
chef.save_config({"run_list": run_list})
- file_path = os.path.join('nodes', 'testnode4.json')
+ file_path = os.path.join('nodes', 'extranode.json')
self.assertTrue(os.path.exists(file_path))
with open(file_path, 'r') as f:
data = json.loads(f.read())
@@ -324,7 +331,7 @@ def test_attribute_merge_cookbook_not_found(self):
"""
# Save new node with a non-existing cookbook assigned
- env.host_string = 'testnode4'
+ env.host_string = 'extranode'
chef.save_config({"run_list": ["recipe[phantom_cookbook]"]})
self.assertRaises(SystemExit, chef._build_node_data_bag)
@@ -362,7 +369,7 @@ def test_attribute_merge_site_cookbook_default(self):
def test_attribute_merge_role_not_found(self):
"""Should print a warning when an assigned role if not found"""
# Save new node with a non-existing cookbook assigned
- env.host_string = 'testnode4'
+ env.host_string = 'extranode'
chef.save_config({"run_list": ["role[phantom_role]"]})
self.assertRaises(SystemExit, chef._build_node_data_bag)

0 comments on commit 0f312f3

Please sign in to comment.
Something went wrong with that request. Please try again.