From a284732328843de2b579bd4cd40bfba6dfdf3e47 Mon Sep 17 00:00:00 2001 From: Jack Kuan Date: Sun, 18 Nov 2012 20:22:41 -0500 Subject: [PATCH 1/2] Update docs about troubleshooting YAML. --- .../troubleshooting/yaml_idiosyncrasies.rst | 46 +++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/doc/topics/troubleshooting/yaml_idiosyncrasies.rst b/doc/topics/troubleshooting/yaml_idiosyncrasies.rst index 7be4afb7ae..b7f8400a83 100644 --- a/doc/topics/troubleshooting/yaml_idiosyncrasies.rst +++ b/doc/topics/troubleshooting/yaml_idiosyncrasies.rst @@ -16,7 +16,11 @@ Spaces vs Tabs `YAML uses spaces`_, period. Do not use tabs in your SLS files! If strange errors are coming up in rendering SLS files, make sure to check that -no tabs have crept in! In vi / vim, you can check with ``:se spell``. +no tabs have crept in! In Vim, after enabling search highlighting +with: ``:set hlsearch``, you can check with the following key sequence in +normal mode(you can hit `ESC` twice to be sure): ``/``, `Ctrl-v`, `Tab`, then +hit `Enter`. Also, you can convert tabs to 2 spaces by these commands in Vim: +``:set tabstop=2 expandtab`` and then ``:retab``. .. _`YAML uses spaces`: http://yaml.org/spec/1.1/#id871998 @@ -149,14 +153,33 @@ ALSO DOES NOT WORK: fred: user.present - ssh.present: + ssh_auth.present: - name: AAAAB3NzaC... - - enc: dsa + - user: fred + - enc: ssh-dss + - require: + - user: fred -So, to make these work they would need to be defined the "old way", or with -multiple "full decs" +The correct way is to define them like this: -WORKS: +.. code-block:: yaml + + vim: + pkg.installed: [] + user.present: [] + + fred: + user.present: [] + ssh_auth.present: + - name: AAAAB3NzaC... + - user: fred + - enc: ssh-dss + - require: + - user: fred + + +Alternatively, they can be defined the "old way", or with multiple +"full decs": .. code-block:: yaml @@ -169,9 +192,13 @@ WORKS: fred: user: - present - ssh.present: + ssh_auth: + - present - name: AAAAB3NzaC... - - enc: dsa + - user: fred + - enc: ssh-dss + - require: + - user: fred YAML support only plain ASCII ============================= @@ -206,6 +233,7 @@ Python can also be used to discover the Unicode number for a character: This shell command can find wrong characters in your SLS files: -.. code-block: shell +.. code-block:: bash + find . -name '*.sls' -exec grep --color='auto' -P -n '[^\x00-\x7F]' \{} \; From 190f4bd8282dfe3b62c9492f4d774d55ca1e21be Mon Sep 17 00:00:00 2001 From: Jack Kuan Date: Sun, 18 Nov 2012 22:02:24 -0500 Subject: [PATCH 2/2] Fix a case when a single shorthand state is declared without arguments. Also, now automatically adds the name argument, if one is not provided, for states declared under a dot-prefixed state id. --- salt/renderers/stateconf.py | 42 ++++++++++++++++++++++++++++++++-- tests/unit/stateconf_test.py | 44 +++++++++++++++++++++++++++++++++--- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/salt/renderers/stateconf.py b/salt/renderers/stateconf.py index ab0ea702ff..ed612844b0 100644 --- a/salt/renderers/stateconf.py +++ b/salt/renderers/stateconf.py @@ -70,9 +70,22 @@ salt files easier and cleaner, therefore, additionally, it also: files. For example, in the `salt://some/file.sls`, a state id such as ``.sls_params`` - will be turned into ``some.file::sls_params``. + will be turned into ``some.file::sls_params``. Example:: - Moreover, the leading dot trick can be used with extending state ids as well, + .vim: + package.installed + + Above will be translated into:: + + some.file::vim: + package.installed: + - name: vim + + Notice how that if a state under a dot-prefixed state id has no 'name' + argument then one will be added automatically by using the state id with + the leading dot stripped off. + + The leading dot trick can be used with extending state ids as well, so you can include relatively and extend relatively. For example, when extending a state in `salt://some/other_file.sls`, eg,:: @@ -294,6 +307,7 @@ def render(template_file, env='', sls='', argline='', **kws): # wrong during the preprocessing. data = copy.deepcopy(high) try: + rewrite_single_shorthand_state_decl(data) rewrite_sls_includes_excludes(data, sls) if not extract and IMPLICIT_REQUIRE: @@ -371,6 +385,22 @@ def has_names_decls(data): for _ in nvlist(args, ['names']): return sid +def rewrite_single_shorthand_state_decl(data): + ''' + Rewrite all state declarations that look like this:: + + state_id_decl: + state.func + + into:: + + state_id_decl: + state.func: [] + ''' + for sid, states in data.items(): + if isinstance(states, basestring): + data[sid] = {states: []} + def _parent_sls(sls): i = sls.rfind('.') @@ -477,6 +507,14 @@ def rename_state_ids(data, sls, is_extend=False): 'Can\'t rename state id({0}) into {1} because the later ' 'already exists!'.format(sid, newsid) ) + # add a '- name: sid' to those states without '- name'. + for args in data[sid].itervalues(): + for arg in args: + if isinstance(arg, dict) and iter(arg).next() == 'name': + break + else: # then no '- name: ...' is defined in the state args + # add the sid without the leading dot as the name. + args.insert(0, dict(name=sid[1:])) data[newsid] = data[sid] del data[sid] diff --git a/tests/unit/stateconf_test.py b/tests/unit/stateconf_test.py index 8d1508ca2c..d18264e039 100644 --- a/tests/unit/stateconf_test.py +++ b/tests/unit/stateconf_test.py @@ -67,6 +67,40 @@ test: 'echo sls_dir=path/to') + def test_states_declared_with_shorthand_no_args(self): + result = render_sls(''' +test: + cmd.run: + - name: echo testing + - cwd: / +test1: + pkg.installed +test2: + user.present +''' ) + self.assertTrue(len(result), 3) + for args in (result['test1']['pkg.installed'], + result['test2']['user.present'] ): + self.assertTrue(isinstance(args, list)) + self.assertEqual(len(args), 0) + self.assertEqual(result['test']['cmd.run'][0]['name'], 'echo testing') + + + def test_adding_state_name_arg_for_dot_state_id(self): + result = render_sls(''' +.test: + pkg.installed: + - cwd: / +.test2: + pkg.installed: + - name: vim +''', sls='test') + self.assertEqual( + result['test::test']['pkg.installed'][0]['name'], 'test') + self.assertEqual( + result['test::test2']['pkg.installed'][0]['name'], 'vim') + + def test_state_prefix(self): result = render_sls(''' .test: @@ -153,7 +187,9 @@ extend: ''', sls='test.goalstate', argline='yaml . jinja') self.assertTrue(len(result), len('ABCDE')+1) - reqs = result['test.goalstate::goal']['stateconf.set'][0]['require'] + reqs = result['test.goalstate::goal']['stateconf.set'][1]['require'] + # note: arg 0 is the name arg. + self.assertEqual(set([i.itervalues().next() for i in reqs]), set('ABCDE')) @@ -207,7 +243,9 @@ G: self.assertEqual(G_req[2]['cmd'], 'F') goal_args = result['test::goal']['stateconf.set'] - self.assertEqual(len(goal_args), 1) + # Note: arg 0 is the auto-added name arg. + + self.assertEqual(len(goal_args), 2) self.assertEqual( - [i.itervalues().next() for i in goal_args[0]['require']], + [i.itervalues().next() for i in goal_args[1]['require']], list('ABCDEFG'))