From 148d8859ba67687ce2d3a1b39228453ea8bc42ba Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Fri, 12 Apr 2013 17:41:16 -0400 Subject: [PATCH] Docs on parameterized roles, make document generation output less noisy --- Makefile | 14 +++ docsite/latest/js/ansible/application.js | 106 +++++++++++++++++++++++ docsite/rst/playbooks.rst | 64 ++++++++++++++ hacking/module_formatter.py | 3 +- 4 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 docsite/latest/js/ansible/application.js diff --git a/Makefile b/Makefile index 6ab81e395b5..97c646dec3b 100644 --- a/Makefile +++ b/Makefile @@ -178,6 +178,7 @@ modulepages: PYTHONPATH=./lib $(PYTHON) hacking/module_formatter.py -A $(VERSION) -t man -o docs/man/man3/ --module-dir=library --template-dir=hacking/templates modulejson: +<<<<<<< HEAD mkdir -p docs/json PYTHONPATH=./lib $(PYTHON) hacking/module_formatter.py -A $(VERSION) -t json -o docs/json --module-dir=library --template-dir=hacking/templates @@ -190,6 +191,19 @@ modulejs: webdocs: (cd docsite; make docs) +======= + -(mkdir -p docs/json) + PYTHONPATH=./lib $(PYTHON) hacking/module_formatter.py -A $(VERSION) -t json -o docs/json --module-dir=library --template-dir=hacking/templates + +modulejs: modulejson + -(mkdir -p docs/json) + PYTHONPATH=./lib $(PYTHON) hacking/module_formatter.py -A $(VERSION) -t js -o docs/json --module-dir=library --template-dir=hacking/templates + +# because this requires Sphinx it is not run as part of every build, those building the RPM and so on can ignore this + +webdocs: + (cd docsite/latest; make docs) +>>>>>>> Docs on parameterized roles, make document generation output less noisy # just for quick testing of all the module docs webdocs2: diff --git a/docsite/latest/js/ansible/application.js b/docsite/latest/js/ansible/application.js new file mode 100644 index 00000000000..5e9f81ba526 --- /dev/null +++ b/docsite/latest/js/ansible/application.js @@ -0,0 +1,106 @@ +angular.module('ansibleApp', []).filter('moduleVersion', function() { + return function(modules, version) { + + var parseVersionString = function (str) { + if (typeof(str) != 'string') { return false; } + var x = str.split('.'); + // parse from string or default to 0 if can't parse + var maj = parseInt(x[0]) || 0; + var min = parseInt(x[1]) || 0; + var pat = parseInt(x[2]) || 0; + return { + major: maj, + minor: min, + patch: pat + } + } + + var vMinMet = function(vmin, vcurrent) { + minimum = parseVersionString(vmin); + running = parseVersionString(vcurrent); + if (running.major != minimum.major) + return (running.major > minimum.major); + else { + if (running.minor != minimum.minor) + return (running.minor > minimum.minor); + else { + if (running.patch != minimum.patch) + return (running.patch > minimum.patch); + else + return true; + } + } + }; + + var result = []; + if (!version) { + return modules; + } + for (var i = 0; i < modules.length; i++) { + if (vMinMet(modules[i].version_added, version)) { + result[result.length] = modules[i]; + } + } + + return result; + }; +}).filter('uniqueVersion', function() { + return function(modules) { + var result = []; + var inArray = function (needle, haystack) { + var length = haystack.length; + for(var i = 0; i < length; i++) { + if(haystack[i] == needle) return true; + } + return false; + } + + var parseVersionString = function (str) { + if (typeof(str) != 'string') { return false; } + var x = str.split('.'); + // parse from string or default to 0 if can't parse + var maj = parseInt(x[0]) || 0; + var min = parseInt(x[1]) || 0; + var pat = parseInt(x[2]) || 0; + return { + major: maj, + minor: min, + patch: pat + } + } + + for (var i = 0; i < modules.length; i++) { + if (!inArray(modules[i].version_added, result)) { + // Some module do not define version + if (modules[i].version_added) { + result[result.length] = "" + modules[i].version_added; + } + } + } + + result.sort( + function (a, b) { + ao = parseVersionString(a); + bo = parseVersionString(b); + if (ao.major == bo.major) { + if (ao.minor == bo.minor) { + if (ao.patch == bo.patch) { + return 0; + } + else { + return (ao.patch > bo.patch) ? 1 : -1; + } + } + else { + return (ao.minor > bo.minor) ? 1 : -1; + } + } + else { + return (ao.major > bo.major) ? 1 : -1; + } + }); + + return result; + }; +}); + diff --git a/docsite/rst/playbooks.rst b/docsite/rst/playbooks.rst index fe847ba954a..ed774e29f99 100644 --- a/docsite/rst/playbooks.rst +++ b/docsite/rst/playbooks.rst @@ -417,6 +417,70 @@ inside another. play are going to get the same tasks. ('only_if' provides some ability for hosts to conditionally skip tasks). +<<<<<<< HEAD:docsite/rst/playbooks.rst +======= +Roles +````` + +Now that you have learned about vars_files, tasks, and handlers, what is the best way to organize your playbooks? +The short answer is to use roles! Roles are automatic ways of automatically loading certain vars_files, tasks, and +handlers based on a known file structure. Grouping content by roles also allows easy sharing of roles with other users. + +Roles are just automation around 'include' directives as redescribed above, and really don't contain much +additional magic beyond some improvements to search path handling for referenced files. However, that can be a big thing! + +Example project structure:: + + site.yml + webservers.yml + fooservers.yml + roles/ + common/ + files/ + templates/ + tasks/ + handlers/ + vars/ + webservers/ + files/ + templates/ + tasks/ + handlers/ + vars/ + +In a playbook, it would look like this:: + + --- + - hosts: webservers + roles: + - common + - webservers + +This designates the following behaviors, for each role 'x': + +- If roles/x/tasks/main.yml exists, tasks listed therein will be added to the play +- If roles/x/handlers/main.yml exists, handlers listed therein will be added to the play +- If roles/x/vars/main.yml exists, variables listed therein will be added to the play +- Any copy tasks can reference files in roles/x/files/ without having to path them relatively or absolutely +- Any template tasks can reference files in roles/x/templates/ without having to path them relatively or absolutely + +If any files are not present, they are just ignored. So it's ok to not have a 'vars/' subdirectory for the role, +for instance. + +Note, you are still allowed to list tasks, vars_files, and handlers "loose" in playbooks without using roles, +but roles are a good organizational feature and are highly recommended. if there are loose things in the playbook, +the roles are evaluated first. + +Also, should you wish to parameterize roles, by adding variables, you can do so, like this:: + + --- + - hosts: webservers + roles: + - common + - { role: foo_app_instance, dir: '/opt/a', port: 5000 } + - { role: foo_app_instance, dir: '/opt/b', port: 5001 } + +>>>>>>> Docs on parameterized roles, make document generation output less noisy:docsite/latest/rst/playbooks.rst Executing A Playbook ```````````````````` diff --git a/hacking/module_formatter.py b/hacking/module_formatter.py index 88540d24f2c..ebf73819087 100755 --- a/hacking/module_formatter.py +++ b/hacking/module_formatter.py @@ -286,7 +286,7 @@ def main(): if fname.endswith(".swp") or fname.endswith(".orig") or fname.endswith(".rej"): continue - print " processing module source ---> %s" % fname + # print " processing module source ---> %s" % fname if options.type == 'js': if fname.endswith(".json"): @@ -299,6 +299,7 @@ def main(): doc, examples = ansible.utils.module_docs.get_docstring(fname, verbose=options.verbose) if doc is None and module not in ansible.utils.module_docs.BLACKLIST_MODULES: + print " while processing module source ---> %s" % fname sys.stderr.write("*** ERROR: CORE MODULE MISSING DOCUMENTATION: %s ***\n" % module) #sys.exit(1)