ansible-1.7.2/000077500000000000000000000000001241061774000131405ustar00rootroot00000000000000ansible-1.7.2/.gitignore000066400000000000000000000014521241061774000151320ustar00rootroot00000000000000# build products... *.py[co] build AUTHORS.TXT # Emacs backup files... *~ .\#* # RPM stuff... MANIFEST dist rpm-build # Eclipse/PyDev stuff... .project .pydevproject # PyCharm stuff... .idea #IntelliJ IDEA stuff.. *.iml # Mac OS X stuff... .DS_Store # manpage build stuff... docs/man/man3/* # Sublime stuff *.sublime-project *.sublime-workspace # docsite stuff... docsite/rst/modules_by_category.rst docsite/rst/list_of_*.rst docsite/rst/*_module.rst docsite/*.html docsite/_static/*.gif docsite/_static/*.png docsite/_static/websupport.js docsite/searchindex.js docsite/htmlout # deb building stuff... debian/ deb-build # Vim swap files *.swp *.swo credentials.yml # test output .coverage results.xml coverage.xml /test/units/cover-html # Development /test/develop venv Vagrantfile .vagrant ansible.egg-info/ ansible-1.7.2/CHANGELOG.md000066400000000000000000002241231241061774000147550ustar00rootroot00000000000000Ansible Changes By Release ========================== ## 1.8 "You Really Got Me" - Active Development ## 1.7.2 "Summer Nights" - Sep 24, 2014 - Fixes a bug in accelerate mode which caused a traceback when trying to use that connection method. - Fixes a bug in vault where the password file option was not being used correctly internally. - Improved multi-line parsing when using YAML literal blocks (using > or |). - Fixed a bug with the file module and the creation of relative symlinks. - Fixed a bug where checkmode was not being honored during the templating of files. - Other various bug fixes. ## 1.7.1 "Summer Nights" - Aug 14, 2014 - Security fix to disallow specifying 'args:' as a string, which could allow the insertion of extra module parameters through variables. - Performance enhancements related to previous security fixes, which could cause slowness when modules returned very large JSON results. This specifically impacted the unarchive module frequently, which returns the details of all unarchived files in the result. - Docker module bug fixes: * Fixed support for specifying rw/ro bind modes for volumes * Fixed support for allowing the tag in the image parameter - Various other bug fixes ## 1.7 "Summer Nights" - Aug 06, 2014 Major new features: * Windows support (alpha) using native PowerShell remoting * Tasks can now specify `run_once: true`, meaning they will be executed exactly once. This can be combined with delegate_to to trigger actions you want done just the one time versus for every host in inventory. New inventory scripts: * SoftLayer * Windows Azure New Modules: * cloud: azure * cloud: rax_meta * cloud: rax_scaling_group * cloud: rax_scaling_policy * windows: version of setup module * windows: version of slurp module * windows: win_feature * windows: win_get_url * windows: win_msi * windows: win_ping * windows: win_user * windows: win_service * windows: win_group Other notable changes: * Inventory speed improvements for very large inventories. * Vault password files can now be executable, to support scripts that fetch the vault password. ## 1.6.10 "And the Cradle Will Rock" - Jul 25, 2014 - Fixes an issue with the copy module when copying a directory that fails when changing file attributes and the target file already exists - Improved unicode handling when splitting args ## 1.6.9 "And the Cradle Will Rock" - Jul 24, 2014 - Further improvements to module parameter parsing to address additional regressions caused by security fixes ## 1.6.8 "And the Cradle Will Rock" - Jul 22, 2014 - Corrects a regression in the way shell and command parameters were being parsed ## 1.6.7 "And the Cradle Will Rock" - Jul 21, 2014 - Security fixes: * Strip lookup calls out of inventory variables and clean unsafe data returned from lookup plugins (CVE-2014-4966) * Make sure vars don't insert extra parameters into module args and prevent duplicate params from superseding previous params (CVE-2014-4967) ## 1.6.6 "And the Cradle Will Rock" - Jul 01, 2014 - Security updates to further protect against the incorrect execution of untrusted data ## 1.6.4, 1.6.5 "And the Cradle Will Rock" - Jun 25, 2014 - Security updates related to evaluation of untrusted remote inputs ## 1.6.3 "And the Cradle Will Rock" - Jun 09, 2014 - Corrects a regression where handlers were run across all hosts, not just those that triggered the handler. - Fixed a bug in which modules did not support properly moving a file atomically when su was in use. - Fixed two bugs related to symlinks with directories when using the file module. - Fixed a bug related to MySQL master replication syntax. - Corrects a regression in the order of variable merging done by the internal runner code. - Various other minor bug fixes. ## 1.6.2 "And the Cradle Will Rock" - May 23, 2014 - If an improper locale is specified, core modules will now automatically revert to using the 'C' locale. - Modules using the fetch_url utility will now obey proxy environment variables. - The SSL validation step in fetch_url will likewise obey proxy settings, however only proxies using the http protocol are supported. - Fixed multiple bugs in docker module related to version changes upstream. - Fixed a bug in the ec2_group module where egress rules were lost when a VPC was specified. - Fixed two bugs in the synchronize module: * a trailing slash might be lost when calculating relative paths, resulting in an incorrect destination. * the sync might use the inventory directory incorrectly instead of the playbook or role directory. - Files will now only be chown'd on an atomic move if the src/dest uid/gid do not match. ## 1.6.1 "And the Cradle Will Rock" - May 7, 2014 - Fixed a bug in group_by, where systems were being grouped incorrectly. - Fixed a bug where file descriptors may leak to a child process when using accelerate. - Fixed a bug in apt_repository triggered when python-apt not being installed/available. - Fixed a bug in the apache2_module module, where modules were not being disabled correctly. ## 1.6 "And the Cradle Will Rock" - May 5, 2014 Major features/changes: * The deprecated legacy variable templating system has been finally removed. Use {{ foo }} always not $foo or ${foo}. * Any data file can also be JSON. Use sparingly -- with great power comes great responsibility. Starting file with "{" or "[" denotes JSON. * Added 'gathering' param for ansible.cfg to change the default gather_facts policy. * Accelerate improvements: - multiple users can connect with different keys, when `accelerate_multi_key = yes` is specified in the ansible.cfg. - daemon lifetime is now based on the time from the last activity, not the time from the daemon's launch. * ansible-playbook now accepts --force-handlers to run handlers even if tasks result in failures. * Added VMWare support with the vsphere_guest module. New Modules: * files: replace * packaging: cpanm (Perl) * packaging: portage * packaging: composer (PHP) * packaging: homebrew_tap (OS X) * packaging: homebrew_cask (OS X) * packaging: apt_rpm * packaging: layman * monitoring: logentries * monitoring: rollbar_deployment * monitoring: librato_annotation * notification: nexmo (SMS) * notification: twilio (SMS) * notification: slack (Slack.com) * notification: typetalk (Typetalk.in) * notification: sns (Amazon) * system: debconf * system: ufw * system: locale_gen * system: alternatives * system: capabilities * net_infrastructure: bigip_facts * net_infrastructure: dnssimple * net_infrastructure: lldp * web_infrastructure: apache2_module * cloud: digital_ocean_domain * cloud: digital_ocean_sshkey * cloud: rax_identity * cloud: rax_cbs (cloud block storage) * cloud: rax_cbs_attachments * cloud: ec2_asg (configure autoscaling groups) * cloud: ec2_scaling_policy * cloud: ec2_metric_alarm * cloud: vsphere_guest Other notable changes: * example callback plugin added for hipchat * added example inventory plugin for vcenter/vsphere * added example inventory plugin for doing really trivial inventory from SSH config files * libvirt module now supports destroyed and paused as states * s3 module can specify metadata * security token additions to ec2 modules * setup module code moved into module_utils/, facts now accessible by other modules * synchronize module sets relative dirs based on inventory or role path * misc bugfixes and other parameters * the ec2_key module now has wait/wait_timeout parameters * added version_compare filter (see docs) * added ability for module documentation YAML to utilize shared module snippets for common args * apt module now accepts "deb" parameter to install local dpkg files * regex_replace filter plugin added * added an inventory script for Docker * added an inventory script for Abiquo * the get_url module now accepts url_username and url_password as parameters, so sites which require authentication no longer need to have them embedded in the url * ... to be filled in from changelogs ... * ## 1.5.5 "Love Walks In" - April 18, 2014 - Security fix for vault, to ensure the umask is set to a restrictive mode before creating/editing vault files. - Backported apt_repository security fixes relating to filename/mode upon sources list file creation. ## 1.5.4 "Love Walks In" - April 1, 2014 - Security fix for safe_eval, which further hardens the checking of the evaluation function. - Changing order of variable precendence for system facts, to ensure that inventory variables take precedence over any facts that may be set on a host. ## 1.5.3 "Love Walks In" - March 13, 2014 - Fix validate_certs and run_command errors from previous release - Fixes to the git module related to host key checking ## 1.5.2 "Love Walks In" - March 11, 2014 - Fix module errors in airbrake and apt from previous release ## 1.5.1 "Love Walks In" - March 10, 2014 - Force command action to not be executed by the shell unless specifically enabled. - Validate SSL certs accessed through urllib*. - Implement new default cipher class AES256 in ansible-vault. - Misc bug fixes. ## 1.5 "Love Walks In" - February 28, 2014 Major features/changes: * when_foo which was previously deprecated is now removed, use "when:" instead. Code generates appropriate error suggestion. * include + with_items which was previously deprecated is now removed, ditto. Use with_nested / with_together, etc. * only_if, which is much older than when_foo and was deprecated, is similarly removed. * ssh connection plugin is now more efficient if you add 'pipelining=True' in ansible.cfg under [ssh_connection], see example.cfg * localhost/127.0.0.1 is not required to be in inventory if referenced, if not in inventory, it does not implicitly appear in the 'all' group. * git module has new parameters (accept_hostkey, key_file, ssh_opts) to ease the usage of git and ssh protocols. * when using accelerate mode, the daemon will now be restarted when specifying a different remote_user between plays. * added no_log: option for tasks. When used, no logging information will be sent to syslog during the module execution. * acl module now handles 'default' and allows for either shorthand entry or specific fields per entry section * play_hosts is a new magic variable to provide a list of hosts in scope for the current play. * ec2 module now accepts 'exact_count' and 'count_tag' as a way to enforce a running number of nodes by tags. * all ec2 modules that work with Eucalyptus also now support a 'validate_certs' option, which can be set to 'off' for installations using self-signed certs. * Start of new integration test infrastructure (WIP, more details TBD) * if repoquery is unavailble, the yum module will automatically attempt to install yum-utils * ansible-vault: a framework for encrypting your playbooks and variable files * added support for privilege escalation via 'su' into bin/ansible and bin/ansible-playbook and associated keywords 'su', 'su_user', 'su_pass' for tasks/plays New modules: * cloud: ec2_elb_lb * cloud: ec2_key * cloud: ec2_snapshot * cloud: rax_dns * cloud: rax_dns_record * cloud: rax_files * cloud: rax_files_objects * cloud: rax_keypair * cloud: rax_queue * cloud: docker_image * messaging: rabbitmq_policy * system: at * utilities: assert Other notable changes (many new module params & bugfixes may not not listed): * no_reboot is now defaulted to "no" in the ec2_ami module to ensure filesystem consistency in the resulting AMI. * sysctl module overhauled * authorized_key module overhauled * synchronized module now handles local transport better * apt_key module now ignores case on keys * zypper_repository now skips on check mode * file module now responds to force behavior when dealing with hardlinks * new lookup plugin 'csvfile' * fixes to allow hash_merge behavior to work with dynamic inventory * mysql module will use port argument on dump/import * subversion module now ignores locale to better intercept status messages * rax api_key argument is no longer logged * backwards/forwards compatibility for OpenStack modules, 'quantum' modules grok neutron renaming * hosts properly uniqueified if appearing in redundant groups * hostname module support added for ScientificLinux * ansible-pull can now show live stdout and pass verbosity levels to ansible-playbook * ec2 instances can now be stopped or started * additional volumes can be created when creating new ec2 instances * user module can move a home directory * significant enhancement and cleanup of rackspace modules * ansible_ssh_private_key_file can be templated * docker module updated to support docker-py 0.3.0 * various other bug fixes * md5 logic improved during sudo operation * support for ed25519 keys in authorized_key module * ability to set directory permissions during a recursive copy (directory_mode parameter) ## 1.4.5 "Could This Be Magic" - February 12, 2014 - fixed issue with permissions being incorrect on fireball/accelerate keys when the umask setting was too loose. ## 1.4.4 "Could This Be Magic" - January 6, 2014 - fixed a minor issue with newer versions of pip dropping the "use-mirrors" parameter. ## 1.4.3 "Could This Be Magic" - December 20, 2013 - Fixed role_path parsing from ansible.cfg - Fixed default role templates ## 1.4.2 "Could This Be Magic" - December 18, 2013 * Fixed a few bugs related to unicode * Fixed errors in the ssh connection method with large data returns * Miscellaneous fixes for a few modules * Add the ansible-galaxy command ## 1.4.1 "Could This Be Magic" - November 27, 2013 * Misc fixes to accelerate mode and various modules. ## 1.4 "Could This Be Magic" - November 21, 2013 Highlighted new features: * Added do-until feature, which can be used to retry a failed task a specified number of times with a delay in-between the retries. * Added failed_when option for tasks, which can be used to specify logical statements that make it easier to determine when a task has failed, or to make it easier to ignore certain non-zero return codes for some commands. * Added the "subelement" lookup plugin, which allows iteration of the keys of a dictionary or items in a list. * Added the capability to use either paramiko or ssh for the inital setup connection of an accelerated playbook. * Automatically provide advice on common parser errors users encounter. * Deprecation warnings are now shown for legacy features: when_integer/etc, only_if, include+with_items, etc. Can be disabled in ansible.cfg * The system will now provide helpful tips around possible YAML syntax errors increasing ease of use for new users. * warnings are now shown for using {{ foo }} in loops and conditionals, and suggest leaving the variable expressions bare as per docs. * The roles search path is now configurable in ansible.cfg. 'roles_path' in the config setting. * Includes with parameters can now be done like roles for consistency: - { include: song.yml, year:1984, song:'jump' } * The name of each role is now shown before each task if roles are being used * Adds a "var=" option to the debug module for debugging variable data. "debug: var=hostvars['hostname']" and "debug: var=foo" are all valid syntax. * Variables in {{ format }} can be used as references even if they are structured data * Can force binding of accelerate to ipv6 ports. * the apt module will auto-install python-apt if not present rather than requiring a manual installation * the copy module is now recursive if the local 'src' parameter is a directory. * syntax checks now scan included task and variable files as well as main files New modules and plugins. * cloud: ec2_eip -- manage AWS elastic IPs * cloud: ec2_vpc -- manage ec2 virtual private clouds * cloud: elasticcache -- Manages clusters in Amazon Elasticache * cloud: rax_network -- sets up Rackspace networks * cloud: rax_facts: retrieve facts about a Rackspace Cloud Server * cloud: rax_clb_nodes -- manage Rackspace cloud load balanced nodes * cloud: rax_clb -- manages Rackspace cloud load balancers * cloud: docker - instantiates/removes/manages docker containers * cloud: ovirt -- VM lifecycle controls for ovirt * files: acl -- set or get acls on a file * files: unarchive: pushes and extracts tarballs * files: synchronize: a useful wraper around rsyncing trees of files * system: firewalld -- manage the firewalld configuration * system: modprobe -- manage kernel modules on systems that support modprobe/rmmod * system: open_iscsi -- manage targets on an initiator using open-iscsi * system: blacklist: add or remove modules from the kernel blacklist * system: hostname - sets the systems hostname * utilities: include_vars -- dynamically load variables based on conditions. * packaging: zypper_repository - adds or removes Zypper repositories * packaging: urpmi - work with urpmi packages * packaging: swdepot - a module for working with swdepot * notification: grove - notifies to Grove hosted IRC channels * web_infrastructure: ejabberd_user: add and remove users to ejabberd * web_infrastructure: jboss: deploys or undeploys apps to jboss * source_control: github_hooks: manages GitHub service hooks * net_infrastructure: bigip_monitor_http: manages F5 BIG-IP LTM http monitors * net_infrastructure: bigip_monitor_tcp: manages F5 BIG-IP LTM TCP monitors * net_infrastructure: bigip_pool_member: manages F5 BIG-IP LTM pool members * net_infrastructure: bigip_node: manages F5 BIG-IP LTM nodes * net_infrastructure: openvswitch_port * net_infrastructure: openvswitch_bridge Plugins: * jail connection module (FreeBSD) * lxc connection module * added inventory script for listing FreeBSD jails * added md5 as a Jinja2 filter: {{ path | md5 }} * added a fileglob filter that will return files matching a glob pattern. with_items: "/foo/pattern/*.txt | fileglob" * 'changed' filter returns whether a previous step was changed easier. when: registered_result | changed * DOCS NEEDED: 'unique' and 'intersect' filters are added for dealing with lists. * DOCS NEEDED: new lookup plugin added for etcd * a 'func' connection type to help people migrating from func/certmaster. Misc changes (all module additions/fixes may not listed): * (docs pending) New features for accelerate mode: configurable timeouts and a keepalives for long running tasks. * Added a `delimiter` field to the assemble module. * Added `ansible_env` to the list of facts returned by the setup module. * Added `state=touch` to the file module, which functions similarly to the command-line version of `touch`. * Added a -vvvv level, which will show SSH client debugging information in the event of a failure. * Includes now support the more standard syntax, similar to that of role includes and dependencies. * Changed the `user:` parameter on plays to `remote_user:` to prevent confusion with the module of the same name. Still backwards compatible on play parameters. * Added parameter to allow the fetch module to skip the md5 validation step ('validate_md5=false'). This is usefull when fetching files that are actively being written to, such as live log files. * Inventory hosts are used in the order they appear in the inventory. * in hosts: foo[2-5] type syntax, the iterators now are zero indexed and the last index is non-inclusive, to match Python standards. * There is now a way for a callback plugin to disable itself. See osx_say example code for an example. * Many bugfixes to modules of all types. * Complex arguments now can be used with async tasks * SSH ControlPath is now configurable in ansible.cfg. There is a limit to the lengths of these paths, see how to shorten them in ansible.cfg. * md5sum support on AIX with csum. * Extremely large documentation refactor into subchapters * Added 'append_privs' option to the mysql_user module * Can now update (temporarily change) host variables using the "add_host" module for existing hosts. * Fixes for IPv6 addresses in inventory text files * name of executable can be passed to pip/gem etc, for installing under *different* interpreters * copy of ./hacking/env-setup added for fish users, ./hacking/env-setup.fish * file module more tolerant of non-absolute paths in softlinks. * miscellaneous fixes/upgrades to async polling logic. * conditions on roles now pass to dependent roles * ansible_sudo_pass can be set in a host variable if desired * misc fixes for the pip an easy_install modules * support for running handlers that have parameterized names based on role parameters * added support for compressing MySQL dumps and extracting during import * Boto version compatibility fixes for the EC2 inventory script * in the EC2 inventory script, a group 'EC2' and 'RDS' contains EC2 and RDS hosts. * umask is enforced by the cron module * apt packages that are not-removed and not-upgraded do not count as changes * the assemble module can now use src files from the local server and copy them over dynamically * authorization code has been standardized between Amazon cloud modules * the wait_for module can now also wait for files to exist or a regex string to exist in a file * leading ranges are now allowed in ranged hostname patterns, ex: [000-250].example.com * pager support added to ansible-doc (so it will auto-invoke less, etc) * misc fixes to the cron module * get_url module now understands content-disposition headers for deciding filenames * it is possible to have subdirectories in between group_vars/ and host_vars/ and the final filename, like host_vars/rack42/asdf for the variables for host 'asdf'. The intermediate directories are ignored, and do not put a file in there twice. ## 1.3.4 "Top of the World" (reprise) - October 29, 2013 * Fixed a bug in the copy module, where a filename containing the string "raw" was handled incorrectly * Fixed a bug in accelerate mode, where copying a zero-length file out would fail ## 1.3.3 "Top of the World" (reprise) - October 9, 2013 Additional fixes for accelerate mode. ## 1.3.2 "Top of the World" (reprise) - September 19th, 2013 Multiple accelerate mode fixes: * Make packet reception less greedy, so multiple frames of data are not consumed by one call. * Adding two timeout values (one for connection and one for data reception timeout). * Added keepalive packets, so async mode is no longer required for long-running tasks. * Modified accelerate daemon to use the verbose logging level of the ansible command that started it. * Fixed bug where accelerate would not work in check-mode. * Added a -vvvv level, which will show SSH client debugging information in the event of a failure. * Fixed bug in apt_repository module where the repository cache was not being updated. * Fixed bug where "too many open files" errors would be encountered due to pseudo TTY's not being closed properly. ## 1.3.1 "Top of the World" (reprise) - September 16th, 2013 Fixing a bug in accelerate mode whereby the gather_facts step would always be run via sudo regardless of the play settings. ## 1.3 "Top of the World" - September 13th, 2013 Highlighted new features: * accelerated mode: An enhanced fireball mode that requires zero bootstrapping and fewer requirements plus adds capabilities like sudo commands. * role defaults: Allows roles to define a set of variables at the lowest priority. These variables can be overridden by any other variable. * new /etc/ansible/facts.d allows JSON or INI-style facts to be provided from the remote node, and supports executable fact programs in this dir. Files must end in *.fact. * added the ability to make undefined template variables raise errors (see ansible.cfg) * (DOCS PENDING) sudo: True/False and sudo_user: True/False can be set at include and role level * added changed_when: (expression) which allows overriding whether a result is changed or not and can work with registered expressions * --extra-vars can now take a file as input, e.g., "-e @filename" and can also be formatted as YAML * external inventory scripts may now return host variables in one pass, which allows them to be much more efficient for large numbers of hosts * if --forks exceeds the numbers of hosts, it will be automatically reduced. Set forks to 0 and you get "as many forks as I have hosts" out of the box. * enabled error_on_undefined_vars by default, which will make errors in playbooks more obvious * role dependencies -- one role can now pull in another, with parameters of its own. * added the ability to have tasks execute even during a check run (always_run). * added the ability to set the maximum failure percentage for a group of hosts. New modules: * notifications: datadog_event -- send data to datadog * cloud: digital_ocean -- module for DigitalOcean provisioning that also includes inventory support * cloud: rds -- Amazon Relational Database Service * cloud: linode -- modules for Linode provisioning that also includes inventory support * cloud: route53 -- manage Amazon DNS entries * cloud: ec2_ami -- manages (and creates!) ec2 AMIs * database: mysql_replication -- manages mysql replication settings for masters/slaves * database: mysql_variables -- manages mysql runtime variables * database: redis -- manages redis databases (slave mode and flushing data) * net_infrastructure: arista_interface * net_infrastructure: arista_lag * net_infrastructure: arista_l2interface * net_infrastructure: arista_vlan * system: stat -- reports on stat(istics) of remote files, for use with 'register' * web_infrastructure: htpasswd -- manipulate htpasswd files * packaging: rpm_key -- adds or removes RPM signing keys * packaging: apt_repository -- rewritten to remove dependencies * monitoring: boundary_meter -- adds or removes boundary.com meters * net_infrastructure: dnsmadeeasy - manipulate DNS Made Easy records * files: xattr -- manages extended attributes on files Misc changes: * return 3 when there are hosts that were unreachable during a run * the yum module now supports wildcard values for the enablerepo argument * added an inventory script to pull host information from Zabbix * async mode no longer allows with_* lookup plugins due to incompatibilities * Added OpenRC support (Gentoo) to the service module * ansible_ssh_user value is available to templates * added placement_group parameter to ec2 module * new sha256sum parameter added to get_url module for checksum validation * search for mount binaries in system path and sbin vs assuming path * allowed inventory file to be read from a pipe * added Solaris distribution facts * fixed bug along error path in quantum_network module * user password update mode is controllable in user module now (at creation vs. every time) * added check mode support to the OpenBSD package module * Fix for MySQL 5.6 compatibility * HP UX virtualization facts * fixed some executable bits in git * made rhn_register module compatible with EL5 * fix for setup module epoch time on Solaris * sudo_user is now expanded later, allowing it to be set at inventory scope * mongodb_user module changed to also support MongoDB 2.2 * new state=hard option added to the file module for hardlinks vs softlinks * fixes to apt module purging option behavior * fixes for device facts with multiple PCI domains * added "with_inventory_hostnames" lookup plugin, which can take a pattern and loop over hostnames matching the pattern and is great for use with delegate_to and so on * ec2 module supports adding to multiple security groups * cloudformation module includes fixes for the error path, and the 'wait_for' parameter was removed * added --only-if-changed to ansible-pull, which runs only if the repo has changes (not default) * added 'mandatory', a Jinja2 filter that checks if a variable is defined: {{ foo|mandatory }} * added support for multiple size formats to the lvol module * timing reporting on wait_for module now includes the delay time * IRC module can now send a server password * "~" now expanded on each component of configured plugin paths * fix for easy_install module when dealing with virtualenv * rackspace module now explicitly indicates rackspace vs vanilla openstack * add_host module does not report changed=True any longer * explanatory error message when using fireball with sudo has been improved * git module now automatically pulls down git submodules * negated patterns do not require "all:!foo", you can just say "!foo" now to select all not foos * fix for Debian services always reporting changed when toggling enablement bit * roles files now tolerate files named 'main.yaml' and 'main' in addition to main.yml * some help cleanup to command line flags on scripts * force option reinstated for file module so it can create symlinks to non-existent files, etc. * added termination support to ec2 module * --ask-sudo-pass or --sudo-user does not enable all options to use sudo in ansible-playbook * include/role conditionals are added ahead of task conditionals so they can short circuit properly * added pipes.quote in various places so paths with spaces are better tolerated * error handling while executing Jinja2 filters has been improved * upgrades to atomic replacement logic when copying files across partitions/etc * mysql user module can try to login before requiring explicit password * various additional options added to supervisorctl module * only add non unique parameter on group creation when required * allow rabbitmq_plugin to specify a non-standard RabbitMQ path * authentication fixes to keystone_user module * added IAM role support to EC2 module * fixes for OpenBSD package module to avoid shell expansion * git module upgrades to allow --depth and --version to be used together * new lookup plugin, "with_flattened" * extra vars (-e) variables can be used in playbook include paths * improved reporting for invalid sudo passwords * improved reporting for inability to find a suitable tmp location * require libselinux-python to perform file operations if SELinux is operational * ZFS module fixes for byte display constants and handling paths with spaces * setup module more tolerant of gathering facts against things it does not have permission to read * can specify name=* state=latest to update all yum modules * major speedups to the yum module for default cases * ec2_facts module will now run in check mode * sleep option on service module for sleeping between stop/restart * fix for IPv6 facts on BSD * added Jinja2 filters: skipped, whether a result was skipped * added Jinja2 filters: quote, quotes a string if it needs to be quoted * allow force=yes to affect apt upgrades * fix for saving conditionals in variable names * support for multiple host ranges in INI inventory, e.g., db[01:10:3]node-[01:10] * fixes/improvements to cron module * add user_install=no option to gem module to install gems system wide * added raw=yes to allow copying without python on remote machines * added with_indexed_items lookup plugin * Linode inventory plugin now significantly faster * added recurse=yes parameter to pacman module for package removal * apt_key module can now target specific keyrings (keyring=filename) * ec2 module change reporting improved * hg module now expands user paths (~) * SSH connection type known host checking now can process hashed known_host files * lvg module now checks for executables in more correct locations * copy module now works correctly with sudo_user * region parameter added to ec2_elb module * better default XMPP module message types * fixed conditional tests against raw booleans * mysql module grant removal is now smarter * apt-remove is now forced to be non-interactive * support ; comments in INI file module * fixes to callbacks WRT async output (fire and forget tasks now trigger callbacks!) * folder support for s3 module * added new example inventory plugin for Red Hat OpenShift * and other misc. bugfixes ## 1.2.3 "Hear About It Later" (reprise) -- Aug 21, 2013 * Local security fixes for predictable file locations for ControlPersist and retry file paths on shared machines on operating systems without kernel symlink/hardlink protections. ## 1.2.2 "Hear About It Later" (reprise) -- July 4, 2013 * Added a configuration file option [paramiko_connection] record_host_keys which allows the code that paramiko uses to update known_hosts to be disabled. This is done because paramiko can be very slow at doing this if you have a large number of hosts and some folks may not want this behavior. This can be toggled independently of host key checking and does not affect the ssh transport plugin. Use of the ssh transport plugin is preferred if you have ControlPersist capability, and Ansible by default in 1.2.1 and later will autodetect. ## 1.2.1 "Hear About It Later" -- July 4, 2013 * Connection default is now "smart", which discovers if the system openssh can support ControlPersist, and uses it if so, if not falls back to paramiko. * Host key checking is on by default. Disable it if you like by adding host_key_checking=False in the [default] section of /etc/ansible/ansible.cfg or ~/ansible.cfg or by exporting ANSIBLE_HOST_KEY_CHECKING=False * Paramiko now records host keys it was in contact with host key checking is on. It is somewhat sluggish when doing this, so switch to the 'ssh' transport if this concerns you. ## 1.2 "Right Now" -- June 10, 2013 Core Features: * capability to set 'all_errors_fatal: True' in a playbook to force any error to stop execution versus a whole group or serial block needing to fail usable, without breaking the ability to override in ansible * ability to use variables from {{ }} syntax in mainline playbooks, new 'when' conditional, as detailed in documentation. Can disable old style replacements in ansible.cfg if so desired, but are still active by default. * can set ansible_ssh_private_key_file as an inventory variable (similar to ansible_ssh_host, etc) * 'when' statement can be affixed to task includes to auto-affix the conditional to each task therein * cosmetic: "*****" banners in ansible-playbook output are now constant width * --limit can now be given a filename (--limit @filename) to constrain a run to a host list on disk * failed playbook runs will create a retry file in /var/tmp/ansible usable with --limit * roles allow easy arrangement of reusable tasks/handlers/files/templates * pre_tasks and post_tasks allow for separating tasks into blocks where handlers will fire around them automatically * "meta: flush_handler" task capability added for when you really need to force handlers to run * new --start-at-task option to ansible playbook allows starting at a specific task name in a long playbook * added a log file for ansible/ansible-playbook, set 'log_path' in the configuration file or ANSIBLE_LOG_PATH in environment * debug mode always outputs debug in playbooks, without needing to specify -v * external inventory script added for Spacewalk / Red Hat Satellite servers * It is now possible to feed JSON structures to --extra-vars. Pass in a JSON dictionary/hash to feed in complex data. * group_vars/ and host_vars/ directories can now be kept alongside the playbook as well as inventory (or both!) * more filters: ability to say {{ foo|success }} and {{ foo|failed }} and when: foo|success and when: foo|failed * more filters: {{ path|basename }} and {{ path|dirname }} * lookup plugins now use the basedir of the file they have included from, avoiding needs of ../../../ in places and increasing the ease at which things can be reorganized. Modules added: * cloud: rax: module for creating instances in the rackspace cloud (uses pyrax) * packages: npm: node.js package management * packages: pkgng: next-gen package manager for FreeBSD * packages: redhat_subscription: manage Red Hat subscription usage * packages: rhn_register: basic RHN registration * packages: zypper (SuSE) * database: postgresql_priv: manages postgresql priveledges * networking: bigip_pool: load balancing with F5s * networking: ec2_elb: add and remove machines from ec2 elastic load balancers * notification: hipchat: send notification events to hipchat * notification: flowdock: send messages to flowdock during playbook runs * notification: campfire: send messages to campfire during playbook runs * notification: mqtt: send messages to the Mosquitto message bus * notification: irc: send messages to IRC channels * notification: filesystem - a wrapper around mkfs * notification: jabber: send jabber chat messages * notification: osx_say: make OS X say things out loud * openstack: keystone_user * openstack: glance_image * openstack: nova_compute * openstack: nova_keypair * openstack: quantum_floating_ip * openstack: quantum_floating_ip_associate * openstack: quantum_network * openstack: quantum_router * openstack: quantum_router_gateway * openstack: quantum_router_interface * openstack: quantum_subnet * monitoring: newrelic_deployment: notifies newrelic of new deployments * monitoring: airbrake_deployment - notify airbrake of new deployments * monitoring: pingdom * monitoring: pagerduty * monitoring: monit * utility: set_fact: sets a variable, which can be the result of a template evaluation Modules removed * vagrant -- can't be compatible with both versions at once, just run things though the vagrant provisioner in vagrant core Bugfixes and Misc Changes: * service module happier if only enabled=yes|no specified and no state * mysql_db: use --password= instead of -p in dump/import so it doesn't go interactive if no pass set * when using -c ssh and the ansible user is the current user, don't pass a -o to allow SSH config to be * overwrite parameter added to the s3 module * private_ip parameter added to the ec2 module * $FILE and $PIPE now tolerate unicode * various plugin loading operations have been made more efficient * hostname now uses platform.node versus socket.gethostname to be more consistant with Unix 'hostname' * fix for SELinux operations on Unicode path names * inventory directory locations now ignore files with .ini extensions, making hybrid inventory easier * copy module in check-mode now reports back correct changed status when used with force=no * added avail. zone to ec2 module * fixes to the hash variable merging logic if so enabled in the main settings file (default is to replace, not merge hashes) * group_vars and host_vars files can now end in a .yaml or .yml extension, (previously required no extension, still favored) * ec2vol module improvements * if the user module is told to generate the ssh key, the key generated is now returned in the results * misc fixes to the Riak module * make template module slightly more efficient * base64encode / decode filters are now available to templates * libvirt module can now work with multiple different libvirt connecton URIs * fix for postgresql password escaping * unicode fix for shlex.split in some cases * apt module upgrade logic improved * URI module now can follow redirects * yum module can now install off http URLs * sudo password now defaults to ssh password if you ask for both and just hit enter on the second prompt * validate feature on copy and template module, for example, running visudo prior to copying the file over * network facts upgraded to return advanced configs (bonding, etc) * region support added to ec2 module * riak module gets a wait for ring option * improved check mode support in the file module * exception handling added to handle scenario when attempt to log to systemd journal fails * fix for upstart handling when toggling the enablement and running bits at the same time * when registering a task with a conditional attached, and the task is skipped by the conditional, the variable is still registered for the host, with the attribute skipped: True. * delegate_to tasks can look up ansible_ssh_private_key_file variable from inventory correctly now * s3 module takes a 'dest' parameter to change the destination for uploads * apt module gets a cache_valid_time option to avoid redundant cache updates * ec2 module better understands security groups * fix for postgresql codec usage * setup module now tolerant of OpenVZ interfaces * check mode reporting improved for files and directories * doc system now reports on module requirements * group_by module can now also make use of globally scoped variables * localhost and 127.0.0.1 are now fuzzy matched in inventory (are now more or less interchangeable) * AIX improvements/fixes for users, groups, facts * lineinfile now does atomic file replacements * fix to not pass PasswordAuthentication=no in the config file unneccessarily for SSH connection type * for for authorized_key on Debian Squeeze * fixes for apt_repository module reporting changed incorrectly on certain repository types * allow the virtualenv argument to the pip module to be a pathname * service pattern argument now correctly read for BSD services * fetch location can now be controlled more directly via the 'flat' parameter. * added basename and dirname as Jinja2 filters available to all templates * pip works better when sudoing from unpriveledged users * fix for user creation with groups specification reporting 'changed' incorrectly in some cases * fix for some unicode encoding errors in outputing some data in verbose mode * improved FreeBSD, NetBSD and Solaris facts * debug module always outputs data without having to specify -v * fix for sysctl module creating new keys (must specify checks=none) * NetBSD and OpenBSD support for the user and groups modules * Add encrypted password support to password lookup ## 1.1 "Mean Street" -- 4/2/2013 Core Features * added --check option for "dry run" mode * added --diff option to show how templates or copied files change, or might change * --list-tasks for the playbook will list the tasks without running them * able to set the environment by setting "environment:" as a dictionary on any task (go proxy support!) * added ansible_ssh_user and ansible_ssh_pass for per-host/group username and password * jinja2 extensions can now be loaded from the config file * support for complex arguments to modules (within reason) * can specify ansible_connection=X to define the connection type in inventory variables * a new chroot connection type * module common code now has basic type checking (and casting) capability * module common now supports a 'no_log' attribute to mark a field as not to be syslogged * inventory can now point to a directory containing multiple scripts/hosts files, if using this, put group_vars/host_vars directories inside this directory * added configurable crypt scheme for 'vars_prompt' * password generating lookup plugin -- $PASSWORD(path/to/save/data/in) * added --step option to ansible-playbook, works just like Linux interactive startup! Modules Added: * bzr (bazaar version control) * cloudformation * django-manage * gem (ruby gems) * homebrew * lvg (logical volume groups) * lvol (LVM logical volumes) * macports * mongodb_user * netscaler * okg * openbsd_pkg * rabbit_mq_plugin * rabbit_mq_user * rabbit_mq_vhost * rabbit_mq_parameter * rhn_channel * s3 -- allows putting file contents in buckets for sharing over s3 * uri module -- can get/put/post/etc * vagrant -- launching VMs with vagrant, this is different from existing vagrant plugin * zfs Bugfixes and Misc Changes: * stderr shown when commands fail to parse * uses yaml.safe_dump in filter plugins * authentication Q&A no longer happens before --syntax-check, but after * ability to get hostvars data for nodes not in the setup cache yet * SSH timeout now correctly passed to native SSH connection plugin * raise an error when multiple when_ statements are provided * --list-hosts applies host limit selections better * (internals) template engine specifications to use template_ds everywhere * better error message when your host file can not be found * end of line comments now work in the inventory file * directory destinations now work better with remote md5 code * lookup plugin macros like $FILE and $ENV now work without returning arrays in variable definitions/playbooks * uses yaml.safe_load everywhere * able to add EXAMPLES to documentation via EXAMPLES docstring, rather than just in main documentation YAML * can set ANSIBLE_COW_SELECTION to pick other cowsay types (including random) * to_nice_yaml and to_nice_json available as Jinja2 filters that indent and sort * cowsay able to run out of macports (very important!) * improved logging for fireball mode * nicer error message when talking to an older system that needs a JSON module installed * 'magic' variable 'inventory_dir' now gives path to inventory file * 'magic' variable 'vars' works like 'hostvars' but gives global scope variables, useful for debugging in templates mostly * conditionals can be used on plugins like add_host * developers: all callbacks now have access to a ".runner" and ".playbook", ".play", and ".task" object (use getattr, they may not always be set!) Facts: * block device facts for the setup module * facts for AIX * fact detection for OS type on Amazon Linux * device fact gathering stability improvements * ansible_os_family fact added * user_id (remote user name) * a whole series of current time information under the 'datetime' hash * more OS X facts * support for detecting Alpine Linux * added facts for OpenBSD Module Changes/Fixes: * ansible module common code (and ONLY that) which is mixed in with modules, is now BSD licensed. App remains GPLv3. * service code works better on platforms that mix upstart, systemd, and system-v * service enablement idempotence fixes for systemd and upstart * service status 4 is also 'not running' * supervisorctl restart fix * increased error handling for ec2 module * can recursively set permissions on directories * ec2: change to the way AMI tags are handled * cron module can now also manipulate cron.d files * virtualenv module can now inherit system site packages (or not) * lineinfile module now has an insertbefore option * NetBSD service module support * fixes to sysctl module where item has multiple values * AIX support for the user and group modules * able to specify a different hg repo to pull from than the original set * add_host module can set ports and other inventory variables * add_host module can add modules to multiple groups (groups=a,b,c), groups now alias for groupname * subnet ID can be set on EC2 module * MySQL module password handling improvements * added new virtualenv flags to pip and easy_install modules * various improvements to lineinfile module, now accepts common arguments from file * force= now replaces thirsty where used before, thirsty remains an alias * setup module can take a 'filter=' parameter to just return a few facts (not used by playbooks) * cron module works even if no crontab is present (for cron.d) * security group ID settable on EC2 module * misc fixes to sysctl module * fix to apt module so packages not in cache are still removable * charset fix to mail module * postresql db module now does not try to create the 'PUBLIC' user * SVN module now works correctly with self signed certs * apt module now has an upgrade parameter (values=yes, no, or 'dist') * nagios module gets new silence/unsilence commands * ability to disable proxy usage in get_url (use_proxy=no) * more OS X facts * added a 'fail_on_missing' (default no) option to fetch * added timeout to the uri module (default 30 seconds, adjustable) * ec2 now has a 'wait' parameter to wait for the instance to be active, eliminates need for separate wait_for call. * allow regex backreferences in lineinfile * id attribute on ec2 module can be used to set idempotent-do-not-recreate launches * icinga support for nagios module * fix default logins when no my.conf for MySQL module * option to create users with non-unique UIDs (user module) * macports module can enable/disable packages * quotes in my.cnf are stripped by the MySQL modules * Solaris Service management added * service module will attempt to auto-add unmanaged chkconfig services when needed * service module supports systemd service unit files Plugins: * added 'with_random_choice' filter plugin * fixed ~ expansion for fileglob * with_nested allows for nested loops (see examples in examples/playbooks) ## 1.0 "Eruption" -- Feb 1 2013 New modules: * new sysctl module * new pacman module (Arch linux) * new apt_key module * hg module now in core * new ec2_facts module * added pkgin module for Joyent SmartOS New config settings: * sudo_exe parameter can be set in config to use sudo alternatives * sudo_flags parameter can alter the flags used with sudo New playbook/language features: * added when_failed and when_changed * task includes can now be of infinite depth * when_set and when_unset can take more than one var (when_set: $a and $b and $c) * added the with_sequence lookup plugin * can override "connection:" on an indvidual task * parameterized playbook includes can now define complex variables (not just all on one line) * making inventory variables available for use in vars_files paths * messages when skipping plays are now more clear * --extra-vars now has maximum precedence (as intended) Module fixes and new flags: * ability to use raw module without python on remote system * fix for service status checking on Ubuntu * service module now responds to additional exit code for SERVICE_UNAVAILABLE * fix for raw module with '-c local' * various fixes to git module * ec2 module now reports the public DNS name * can pass executable= to the raw module to specify alternative shells * fix for postgres module when user contains a "-" * added additional template variables -- $template_fullpath and $template_run_date * raise errors on invalid arguments used with a task include statement * shell/command module takes a executable= parameter to specify a different shell than /bin/sh * added return code and error output to the raw module * added support for @reboot to the cron module * misc fixes to the pip module * nagios module can schedule downtime for all services on the host * various subversion module improvements * various mail module improvements * SELinux fix for files created by authorized_key module * "template override" ?? * get_url module can now send user/password authorization * ec2 module can now deploy multiple simultaneous instances * fix for apt_key modules stalling in some situations * fix to enable Jinja2 {% include %} to work again in template * ec2 module is now powered by Boto * setup module can now detect if package manager is using pacman * fix for yum module with enablerepo in use on EL 6 Core fixes and new behaviors: * various fixes for variable resolution in playbooks * fixes for handling of "~" in some paths * various fixes to DWIM'ing of relative paths * /bin/ansible now takes a --list-hosts just like ansible-playbook did * various patterns can now take a regex vs a glob if they start with "~" (need docs on which!) - also /usr/bin/ansible * allow intersecting host patterns by using "&" ("webservers:!debian:&datacenter1") * handle tilde shell character for --private-key * hash merging policy is now selectable in the config file, can choose to override or merge * environment variables now available for setting all plugin paths (ANSIBLE_CALLBACK_PLUGINS, etc) * added packaging file for macports (not upstreamed yet) * hacking/test-module script now uses /usr/bin/env properly * fixed error formatting for certain classes of playbook syntax errors * fix for processing returns with large volumes of output Inventory files/scripts: * hostname patterns in the inventory file can now use alphabetic ranges * whitespace is now allowed around group variables in the inventory file * inventory scripts can now define groups of groups and group vars (need example for docs?) ## 0.9 "Dreams" -- Nov 30 2012 Highlighted core changes: * various performance tweaks, ansible executes dramatically less SSH ops per unit of work * close paramiko SFTP connections less often on copy/template operations (speed increase) * change the way we use multiprocessing (speed/RAM usage improvements) * able to set default for asking password & sudo password in config file * ansible now installs nicely if running inside a virtualenv * flag to allow SSH connection to move files by scp vs sftp (in config file) * additional RPM subpackages for easily installing fireball mode deps (server and node) * group_vars/host_vars now available to ansible, not just playbooks * native ssh connection type (-c ssh) now supports passwords as well as keys * ansible-doc program to show details Other core changes: * fix for template calls when last character is '$' * if ansible_python_interpreter is set on a delegated host, it now works as intended * --limit can now take "," as separator as well as ";" or ":" * msg is now displaced with newlines when a task fails * if any with_ plugin has no results in a list (empty list for with_items, etc), the task is now skipped * various output formatting fixes/improvements * fix for Xen dom0/domU detection in default facts * 'ansible_domain' fact now available (ex value: example.com) * configured remote temp file location is now always used even for root * 'register'-ed variables are not recorded for skipped hosts (for example, using only_if/when) * duplicate host records for the same host can no longer result when a host is listed in multiple groups * ansible-pull now passes --limit to prevent running on multiple hosts when used with generic playbooks * remote md5sum check fixes for Solaris 10 * ability to configure syslog facility used by remote module calls * in templating, stray '$' characters are now handled more correctly Playbook changes: * relative paths now work for 'first_available_file' * various templating engine fixes * 'when' is an easier form of only if * --list-hosts on the playbook command now supports multiple playbooks on the same command line * playbook includes can now be parameterized Module additions: * (addhost) new module for adding a temporary host record (used for creating new guests) * (group_by) module allows partitioning hosts based on group data * (ec2) new module for creating ec2 hosts * (script) added 'script' module for pushing and running self-deleting remote scripts * (svr4pkg) solaris svr4pkg module Module changes: * (authorized key) module uses temp file now to prevent failure on full disk * (fetch) now uses the 'slurp' internal code to work as you would expect under sudo'ed accounts * (fetch) internal usage of md5 sums fixed for BSD * (get_url) thirsty is no longer required for directory destinations * (git) various git module improvements/tweaks * (group) now subclassed for various platforms, includes SunOS support * (lineinfile) create= option on lineinfile can create the file when it does not exist * (mysql_db) module takes new grant options * (postgresql_db) module now takes role_attr_flags * (service) further upgrades to service module service status reporting * (service) tweaks to get service module to play nice with BSD style service systems (rc.conf) * (service) possible to pass additional arguments to services * (shell) and command module now take an 'executable=' flag for specifying an alternate shell than /bin/sh * (user) ability to create SSH keys for users when using user module to create users * (user) atomic replacement of files preserves permissions of original file * (user) module can create SSH keys * (user) module now does Solaris and BSD * (yum) module takes enablerepo= and disablerepo= * (yum) misc yum module fixing for various corner cases Plugin changes: * EC2 inventory script now produces nicer failure message if AWS is down (or similar) * plugin loading code now more streamlined * lookup plugins for DNS text records, environment variables, and redis * added a template lookup plugin $TEMPLATE('filename.j2') * various tweaks to the EC2 inventory plugin * jinja2 filters are now pluggable so it's easy to write your own (to_json/etc, are now impl. as such) ## 0.8 "Cathedral" -- Oct 19, 2012 Highlighted Core Changes: * fireball mode -- ansible can bootstrap a ephemeral 0mq (zeromq) daemon that runs as a given user and expires after X period of time. It is very fast. * playbooks with errors now return 2 on failure. 1 indicates a more fatal syntax error. Similar for /usr/bin/ansible * server side action code (template, etc) are now fully pluggable * ability to write lookup plugins, like the code powering "with_fileglob" (see below) Other Core Changes: * ansible config file can also go in 'ansible.cfg' in cwd in addition to ~/.ansible.cfg and /etc/ansible/ansible.cfg * fix for inventory hosts at API level when hosts spec is a list and not a colon delimited string * ansible-pull example now sets up logrotate for the ansible-pull cron job log * negative host matching (!hosts) fixed for external inventory script usage * internals: os.executable check replaced with utils function so it plays nice on AIX * Debian packaging now includes ansible-pull manpage * magic variable 'ansible_ssh_host' can override the hostname (great for usage with tunnels) * date command usage in build scripts fixed for OS X * don't use SSH agent with paramiko if a password is specified * make output be cleaner on multi-line command/shell errors * /usr/bin/ansible now prints things when tasks are skipped, like when creates= is used with -m command and /usr/bin/ansible * when trying to async a module that is not a 'normal' asyncable module, ansible will now let you know * ability to access inventory variables via 'hostvars' for hosts not yet included in any play, using on demand lookups * merged ansible-plugins, ansible-resources, and ansible-docs into the main project * you can set ANSIBLE_NOCOWS=1 if you want to disable cowsay if it is installed. Though no one should ever want to do this! Cows are great! * you can set ANSIBLE_FORCE_COLOR=1 to force color mode even when running without a TTY * fatal errors are now properly colored red. * skipped messages are now cyan, to differentiate them from unchanged messages. * extensive documentation upgrades * delegate_action to localhost (aka local_action) will always use the local connection type Highlighted playbook changes: * is_set is available for use inside of an only_if expression: is_set('ansible_eth0'). We intend to further upgrade this with a 'when' keyword providing better options to 'only_if' in the next release. Also is_unset('ansible_eth0') * playbooks can import playbooks in other directories and then be able to import tasks relative to them * FILE($path) now allows access of contents of file in a path, very good for use with SSH keys * similarly PIPE($command) will run a local command and return the results of executing this command * if all hosts in a play fail, stop the playbook, rather than letting the console log spool on by * only_if using register variables that are booleans now works in a boolean way like you'd expect * task includes now work with with_items (such as: include: path/to/wordpress.yml user=$item) * when using a $list variable with $var or ${var} syntax it will automatically join with commas * setup is not run more than once when we know it is has already been run in a play that included another play, etc * can set/override sudo and sudo_user on individual tasks in a play, defaults to what is set in the play if not present * ability to use with_fileglob to iterate over local file patterns * templates now use Jinja2's 'trim_blocks=True' to avoid stray newlines, small changes to templates may be required in rare cases. Other playbook changes: * to_yaml and from_yaml are available as Jinja2 filters * $group and $group_names are now accessible in with_items * where 'stdout' is provided a new 'stdout_lines' variable (type == list) is now generated and usable with with_items * when local_action is used the transport is automatically overridden to the local type * output on failed playbook commands is now nicely split for stderr/stdout and syntax errors * if local_action is not used and delegate_to was 127.0.0.1 or localhost, use local connection regardless * when running a playbook, and the statement has changed, prints 'changed:' now versus 'ok:' so it is obvious without colored mode * variables now usable within vars_prompt (just not host/group vars) * setup facts are now retained across plays (dictionary just gets updated as needed) * --sudo-user now works with --extra-vars * fix for multi_line strings with only_if New Modules: * ini_file module for manipulating INI files * new LSB facts (release, distro, etc) * pause module -- (pause seconds=10) (pause minutes=1) (pause prompt=foo) -- it's an action plugin * a module for adding entries to the main crontab (though you may still wish to just drop template files into cron.d) * debug module can be used for outputing messages without using 'shell echo' * a fail module is now available for causing errors, you might want to use it with only_if to fail in certain conditions Other module Changes, Upgrades, and Fixes: * removes= exists on command just like creates= * postgresql modules now take an optional port= parameter * /proc/cmdline info is now available in Linux facts * public host key detection for OS X * lineinfile module now uses 'search' not exact 'match' in regexes, making it much more intuitive and not needing regex syntax most of the time * added force=yes|no (default no) option for file module, which allows transition between files to directories and so on * additional facts for SunOS virtualization * copy module is now atomic when used across volumes * url_get module now returns 'dest' with the location of the file saved * fix for yum module when using local RPMs vs downloading * cleaner error messages with copy if destination directory does not exist * setup module now still works if PATH is not set * service module status now correct for services with 'subsys locked' status * misc fixes/upgrades to the wait_for module * git module now expands any "~" in provided destination paths * ignore stop error code failure for service module with state=restarted, always try to start * inline documentation for modules allows documentation source to built without pull requests to the ansible-docs project, among other things * variable '$ansible_managed' is now great to include at the top of your templates and includes useful information and a warning that it will be replaced * "~" now expanded in command module when using creates/removes * mysql module can do dumps and imports * selinux policy is only required if setting to not disabled * various fixes for yum module when working with packages not in any present repo ## 0.7 "Panama" -- Sept 6 2012 Module changes: * login_unix_socket option for mysql user and database modules (see PR #781 for doc notes) * new modules -- pip, easy_install, apt_repository, supervisorctl * error handling for setup module when SELinux is in a weird state * misc yum module fixes * better changed=True/False detection in user module on older Linux distros * nicer errors from modules when arguments are not key=value * backup option on copy (backup=yes), as well as template, assemble, and lineinfile * file module will not recurse on directory properties * yum module now workable without having repoquery installed, but doesn't support comparisons or list= if so * setup module now detects interfaces with aliases * better handling of VM guest type detection in setup module * new module boilerplate code to check for mutually required arguments, arguments required together, exclusive args * add pattern= as a paramter to the service module (for init scripts that don't do status, or do poor status) * various fixes to mysql & postresql modules * added a thirsty= option (boolean, default no) to the get_url module to decide to download the file every time or not * added a wait_for module to poll for ports being open * added a nagios module for controlling outage windows and alert statuses * added a seboolean module for getsebool/setsebool type operations * added a selinux module for controlling overall SELinux policy * added a subversion module * added lineinfile for adding and removing lines from basic files * added facts for ARM-based CPUs * support for systemd in the service module * git moduleforce reset behavior is now controllable * file module can now operate on special files (block devices, etc) Core changes: * ansible --version will now give branch/SHA information if running from git * better sudo permissions when encountering different umasks * when using paramiko and SFTP is not accessible, do not traceback, but return a nice human readable msg * use -vvv for extreme debug levels. -v gives more playbook output as before * -vv shows module arguments to all module calls (and maybe some other things later) * don not pass "--" to sudo to work on older EL5 * make remote_md5 internal function work with non-bash shells * allow user to be passed in via --extra-vars (regression) * add --limit option, which can be used to further confine the pattern given in ansible-playbooks * adds ranged patterns like dbservers[0-49] for usage with patterns or --limit * -u and user: defaults to current user, rather than root, override as before * /etc/ansible/ansible.cfg and ~/ansible.cfg now available to set default values and other things * (developers) ANSIBLE_KEEP_REMOTE_FILES=1 can be used in debugging (envrionment variable) * (developers) connection types are now plugins * (developers) callbacks can now be extended via plugins * added FreeBSD ports packaging scripts * check for terminal properties prior to engaging color modes * explicitly disable password auth with -c ssh, as it is not used anyway Playbooks: * YAML syntax errors detected and show where the problem is * if you ctrl+c a playbook it will not traceback (usually) * vars_prompt now has encryption options (see examples/playbooks/prompts.yml) * allow variables in parameterized task include parameters (regression) * add ability to store the result of any command in a register (see examples/playbooks/register_logic.yml) * --list-hosts to show what hosts are included in each play of a playbook * fix a variable ordering issue that could affect vars_files with selective file source lists * adds 'delegate_to' for a task, which can be used to signal outage windows and load balancers on behalf of hosts * adds 'serial' to playbook, allowing you to specify how many hosts can be processing a playbook at one time (default 0=all) * adds 'local_action: ' as an alias to 'delegate_to: 127.0.0.1' ## 0.6 "Cabo" -- August 6, 2012 playbooks: * support to tag tasks and includes and use --tags in playbook CLI * playbooks can now include other playbooks (example/playbooks/nested_playbooks.yml) * vars_files now usable with with_items, provided file paths don't contain host specific facts * error reporting if with_items value is unbound * with_items no longer creates lots of tasks, creates one task that makes multiple calls * can use host_specific facts inside with_items (see above) * at the top level of a playbook, set 'gather_facts: no' to skip fact gathering * first_available_file and with_items used together will now raise an error * to catch typos, like 'var' for 'vars', playbooks and tasks now yell on invalid parameters * automatically load (directory_of_inventory_file)/group_vars/groupname and /host_vars/hostname in vars_files * playbook is now colorized, set ANSIBLE_NOCOLOR=1 if you do not like this, does not colorize if not a TTY * hostvars now preserved between plays (regression in 0.5 from 0.4), useful for sharing vars in multinode configs * ignore_errors: yes on a task can be used to allow a task to fail and not stop the play * with_items with the apt/yum module will install/remove/update everything in a single command inventory: * groups variable available as a hash to return the hosts in each group name * in YAML inventory, hosts can list their groups in inverted order now also (see tests/yaml_hosts) * YAML inventory is deprecated and will be removed in 0.7 * ec2 inventory script * support ranges of hosts in the host file, like www[001-100].example.com (supports leading zeros and also not) modules: * fetch module now does not fail a system when requesting file paths (ex: logs) that don't exist * apt module now takes an optional install-recommends=yes|no (default yes) * fixes to the return codes of the copy module * copy module takes a remote md5sum to avoid large file transfer * various user and group module fixes (error handling, etc) * apt module now takes an optional force parameter * slightly better psychic service status handling for the service module * fetch module fixes for SSH connection type * modules now consistently all take yes/no for boolean parameters (and DWIM on true/false/1/0/y/n/etc) * setup module no longer saves to disk, template module now only used in playbooks * setup module no longer needs to run twice per playbook * apt module now passes DEBIAN_FRONTEND=noninteractive * mount module (manages active mounts + fstab) * setup module fixes if no ipv6 support * internals: template in common module boilerplate, also causes less SSH operations when used * git module fixes * setup module overhaul, more modular * minor caching logic added to inventory to reduce hammering of inventory scripts. * MySQL and PostgreSQL modules for user and db management * vars_prompt now supports private password entry (see examples/playbooks/prompts.yml) * yum module modified to be more tolerant of plugins spewing random console messages (ex: RHN) internals: * when sudoing to root, still use /etc/ansible/setup as the metadata path, as if root * paramiko is now only imported if needed when running from source checkout * cowsay support on Ubuntu * various ssh connection fixes for old Ubuntu clients * ./hacking/test-module now supports options like ansible takes and has a debugger mode * sudoing to a user other than root now works more seamlessly (uses /tmp, avoids umask issues) ## 0.5 "Amsterdam" ------- July 04, 2012 * Service module gets more accurate service states when running with upstart * Jinja2 usage in playbooks (not templates), reinstated, supports %include directive * support for --connection ssh (supports Kerberos, bastion hosts, etc), requires ControlMaster * misc tracebacks replaced with error messages * various API/internals refactoring * vars can be built from other variables * support for exclusion of hosts/groups with "!groupname" * various changes to support md5 tool differences for FreeBSD nodes & OS X clients * "unparseable" command output shows in command output for easier debugging * mktemp is no longer required on remotes (not available on BSD) * support for older versions of python-apt in the apt module * a new "assemble" module, for constructing files from pieces of files (inspired by Puppet "fragments" idiom) * ability to override most default values with ANSIBLE_FOO environment variables * --module-path parameter can support multiple directories separated with the OS path separator * with_items can take a variable of type list * ansible_python_interpreter variable available for systems with more than one Python * BIOS and VMware "fact" upgrades * cowsay is used by ansible-playbook if installed to improve output legibility (try installing it) * authorized_key module * SELinux facts now sourced from the python selinux library * removed module debug option -D * added --verbose, which shows output from successful playbook operations * print the output of the raw command inside /usr/bin/ansible as with command/shell * basic setup module support for Solaris * ./library relative to the playbook is always in path so modules can be included in tarballs with playbooks ## 0.4 "Unchained" ------- May 23, 2012 Internals/Core * internal inventory API now more object oriented, parsers decoupled * async handling improvements * misc fixes for running ansible on OS X (overlord only) * sudo improvements, now works much more smoothly * sudo to a particular user with -U/--sudo-user, or using 'sudo_user: foo' in a playbook * --private-key CLI option to work with pem files Inventory * can use -i host1,host2,host3:port to specify hosts not in inventory (replaces --override-hosts) * ansible INI style format can do groups of groups [groupname:children] and group vars [groupname:vars] * groups and users module takes an optional system=yes|no on creation (default no) * list of hosts in playbooks can be expressed as a YAML list in addition to ; delimited Playbooks * variables can be replaced like ${foo.nested_hash_key.nested_subkey[array_index]} * unicode now ok in templates (assumes utf8) * able to pass host specifier or group name in to "hosts:" with --extra-vars * ansible-pull script and example playbook (extreme scaling, remediation) * inventory_hostname variable available that contains the value of the host as ansible knows it * variables in the 'all' section can be used to define other variables based on those values * 'group_names' is now a variable made available to templates * first_available_file feature, see selective_file_sources.yml in examples/playbooks for info * --extra-vars="a=2 b=3" etc, now available to inject parameters into playbooks from CLI Incompatible Changes * jinja2 is only usable in templates, not playbooks, use $foo instead * --override-hosts removed, can use -i with comma notation (-i "ahost,bhost") * modules can no longer include stderr output (paramiko limitation from sudo) Module Changes * tweaks to SELinux implementation for file module * fixes for yum module corner cases on EL5 * file module now correctly returns the mode in octal * fix for symlink handling in the file module * service takes an enable=yes|no which works with chkconfig or updates-rc.d as appropriate * service module works better on Ubuntu * git module now does resets and such to work more smoothly on updates * modules all now log to syslog * enabled=yes|no on a service can be used to toggle chkconfig & updates-rc.d states * git module supports branch= * service fixes to better detect status using return codes of the service script * custom facts provided by the setup module mean no dependency on Ruby, facter, or ohai * service now has a state=reloaded * raw module for bootstrapping and talking to routers w/o Python, etc Misc Bugfixes * fixes for variable parsing in only_if lines * misc fixes to key=value parsing * variables with mixed case now legal * fix to internals of hacking/test-module development script ## 0.3 "Baluchitherium" -- April 23, 2012 * Packaging for Debian, Gentoo, and Arch * Improvements to the apt and yum modules * A virt module * SELinux support for the file module * Ability to use facts from other systems in templates (aka exported resources like support) * Built in Ansible facts so you don't need ohai, facter, or Ruby * tempdir selections that work with noexec mounted /tmp * templates happen locally, not remotely, so no dependency on python-jinja2 for remote computers * advanced inventory format in YAML allows more control over variables per host and per group * variables in playbooks can be structured/nested versus just a flat namespace * manpage upgrades (docs) * various bugfixes * can specify a default --user for playbooks rather than specifying it in the playbook file * able to specify ansible port in ansible host file (see docs) * refactored Inventory API to make it easier to write scripts using Ansible * looping capability for playbooks (with_items) * support for using sudo with a password * module arguments can be unicode * A local connection type, --connection=local, for use with cron or in kickstarts * better module debugging with -D * fetch module for pulling in files from remote hosts * command task supports creates=foo for idempotent semantics, won't run if file foo already exists ## 0.0.2 and 0.0.1 * Initial stages of project ansible-1.7.2/CODING_GUIDELINES.md000066400000000000000000000241301241061774000161350ustar00rootroot00000000000000Coding Guidelines ================= Hi! Thanks for interest in contributing to Ansible. Here are some guidelines for contributing code. The purpose of this document are to establish what we're looking for in code contributions, and to make sure new contributions know some of the conventions that we've been using. We don't think much of this should be too strange to readers familiar with contributing to Python projects, though it helps if we all get on the same page. Language ======== * While not all components of Ansible must be in Python, core contributions to the Ansible repo must be written in Python. This is to maximize the ability of everyone to contribute. * If you want to write non-Python ansible modules or inventory scripts, that's fine, but they are not going to get merged in most likely. Sorry!! PEP8 and basic style checks =========================== * PEP8 is a great Python style guide, which you should read. * PEP8 must not be strictly followed in all aspects, but most of it is good advice * In particular, we don't really care about line lengths. Buy a bigger monitor! * To run checks for things we care about, run "make pep8" * Similarly, additional checks can be made with "make pyflakes" * There is no need to submit code changes for pep8 and pyflake fixes, as these break attribution history. Project leadership will make these periodically. * Do not submit pull requests that simply adjust whitespace in the code Testing ======= * Much of ansible's testing needs are in integration, not unit tests. Add module tests there. * That being said, there are unit tests too! * Code written must absolutely pass tests (i.e. "make tests") * You should anticipate any error paths in your code and test down those error paths. * Additions to tests for core code is welcome, but not always possible. Be sure things are at least well tested manually in that case. Whitespace ========== * Four space indent is strictly required * Include meaningful whitespace between lines of code Shebang Lines ============= * /usr/bin/scripts should start with '/usr/bin/env python' * module code should still use '/usr/bin/python' as this is replaced automatically by 'ansible_python_interpreter', see the FAQ in the docs for more info. Comments ======== * Readability is one of the most important goals for this project * Comment any non-trivial code where someone might not know why you are doing something in a particular way * Though if something should be commented, that's often a sign someone should write a function * All new functions must have a basic docstring comment * Commenting above a line is preferable to commenting at the end of a line Classes ======= * With the exception of module code (where inline is better), it is desirable to see classes in their own files. * Classes should generally not cause side effects as soon as they are instantiated, move meaningful behavior to methods rather than constructors. Functions and Methods ===================== * In general, functions should not be 'too long' and should describe a meaningful amount of work * When code gets too nested, that's usually the sign the loop body could benefit from being a function * Parts of our existing code are not the best examples of this at times. * Functions should have names that describe what they do, along with docstrings * Functions should be named with_underscores * "Don't repeat yourself" is generally a good philosophy Variables ========= * Use descriptive variable names instead of variables like 'x', unless x is a obvious loop index * Ansible python code uses identifiers like 'ClassesLikeThis and variables_like_this * Module parameters should also use_underscores and not runtogether Module Security =============== * Modules must take steps to avoid passing user input from the shell and always check return codes * always use module.run_command instead of subprocess or Popen or os.system -- this is mandatory * if you use need the shell you must pass use_unsafe_shell=True to module.run_command * if you do not need the shell, avoid using the shell * any variables that can come from the user input with use_unsafe_shell=True must be wrapped by pipes.quote(x) * downloads of https:// resource urls must import module_utils.urls and use the fetch_url method Misc Preferences ================ Use the dict constructor where possible when allocating dictionaries: # not this: foo = { 'a' : 12, 'b' : 34 } # this: foo = dict( a = 12, b = 34 ) Line up variables # not this a = 12 foosball = 34 xyz = 'dog' # this a = 12 foosball = 34 xyz = 'dog' Don't use line continuations: # no if (this_is_a_very_long_line and foo and \ i_am_going_to_continue_it): bar() # better: if (this_is_a_very_long_line and foo and i_am_going_to_continue_it): bar() Spacing: # no x=[1,2,3] # no x = [1,2,3] # yes x = [ 1, 2, 3 ] Spacing continued: # no x=foo(12) # no x = foo( 12 ) # yes x = foo(12) Licenses ======== Every file should have a license header, including the copyright of the original author. Major additions to the module are allowed to add an additional copyright line, and this is especially true of rewrites, but original authorship copyright messages should be preserved. All contributions to the core repo should preserve original licenses and new contributions must include the GPLv3 header. Module Documentation ==================== All module pull requests must include a DOCUMENTATION docstring (YAML format, see other modules for examples) as well as an EXAMPLES docstring, which is free form. When adding new modules, any new parameter must have a "version_added" attribute. When submitting a new module, the module should have a "version_added" attribute in the pull request as well, set to the current development version. Be sure to check grammar and spelling. It's frequently the case that modules get submitted with YAML that isn't valid, so you can run "make webdocs" from the checkout to preview your module's documentation. If it fails to build, take a look at your DOCUMENTATION string or you might have a Python syntax error in there too. Python Imports ============== To make it clear what a module is importing, imports should not be sprinkled throughout the code. Python Imports should happen at the top of the file, exempting code from module_utils. When a conditional runtime import is required, do so something like this instead: HAS_FOO = False try: import foo HAS_FOO = True except ImportError: pass ... if not HAS_FOO: raise Exception("the foo library is required") This makes it clear what optional dependencies are but allows this to be deferred until runtime. In the case of module code, the raising of the Exception will be replaced with a "module.exit_json" call. Exceptions ========== In the main body of the code, use typed exceptions where possible: # not this raise Exception("panic!") # this from ansible import errors ... raise errors.AnsibleError("panic!") Similarly, exception checking should be fine grained: # not this try: foo() except: bar() # but this try: foo() except SomeTypedException: bar() List Comprehensions =================== In general list comprehensions are always preferred to map() and filter() calls. However, they can be abused. Optimize for readability, and avoid nesting them too deeply. Regexes ======= There is a time and place for them, but here's an illustrative joke. "A developer had a problem, and used a regular expression to solve it. Now the developer had two problems". Often regexes are difficult to maintain, and a trusty call to other string operations can be a great solution, faster, and more readable. File Conventions ================ If a piece of code looks for a named YAML file in a directory, it should assume it can take no extension, or an extension of '.yml' or '.yaml'. This should be true against all code that loads files. Any code that uses directories should consider the possibility that the directory may be symlink. New Ansible language parameters =============================== If adding a new parameter, like 'can_fizzbuzz: True/False' be sure the value of the parameter is templated somewhere in the Runner code, as if anything can be parameterized in Ansible, there is a user that will try to parameterize it. String Find =========== Use 'in': # not this: if x.find('foo') != -1: # this: if 'foo' in x: String checks ============= To test if something is a string, consider that it may be unicode. # no if type(x) == str: # yes if isinstance(x, basestring): Cleverness ========== Ansible's code is intended to be read by as many people as possible, so we don't particularly encourage clever or heavily idiomatic code. In particular, metaclasses are probably not appropriate, however entertaining they may be to add. Git Practices ============= Pull requests cannot be accepted that contain merge commits. Always do "git pull --rebase" and "git rebase" vs "git pull" or "git merge". Always create a new branch for each pull request to avoid intertwingling different features or fixes on the same branch. Python Version Compliance ========================= All code in Ansible core must support a minimum version of Python 2.6. Module code must support a minimum of Python 2.4, with occasional exception for modules that require code that themselves require 2.6 and later. A quick reminder is that list comprehensions in Python 2.4 are not as fully fleshed out, there are no 'dict' comprehensions, and there is no 'with' statement. But otherwise it's pretty much all the same. The End ======= This was not meant to be a scary document, so we hope it wasn't, but we also hope this helps you write code that is easier to maintain by others in the future. If you have questions about this document, please ask on the ansible-devel mailing list. Thank you! ansible-1.7.2/CONTRIBUTING.md000066400000000000000000000277221241061774000154030ustar00rootroot00000000000000Ansible Community Information ============================== The purpose of the Ansible community is to unite developers, system administrators, operations, and IT managers to share and build great automation solutions. This document contains all sorts of information about how to contribute and interact with Ansible. Welcome! Ways to Interact ================ There are a lot of ways to join and be a part of the Ansible community, such as: Sharing Ansible with Others --------------------------- You can help share Ansible with others by telling friends and colleagues, writing a blog post, or presenting at user groups (like DevOps groups or the local LUG or BUG). You are also welcome to share slides on speakerdeck, sign up for a free account and tag it “Ansibleâ€. On Twitter, you can also share things with #ansible and may wish to follow [@Ansible](https://twitter.com/ansible). Sharing Content and Tips ------------------------ Join the [Ansible project mailing list](https://groups.google.com/forum/#!forum/ansible-project) and you can share playbooks you may have written and other interesting implementation stories. Put your Ansible content up on places like github to share with others. Sharing A Feature Idea ---------------------- Ideas are very welcome and the best place to share them is the [Ansible project mailing list](https://groups.google.com/forum/#!forum/ansible-project) ([Subscribe](https://groups.google.com/forum/#!forum/ansible-project/join)) or #ansible on irc.freenode.net. While you can file a feature request on GitHub, pull requests are a much better way to get your feature added than submitting a feature request. Open source is all about itch scratching, and it's less likely that someone else will have the same itches as yourself. We keep code reasonably simple on purpose so it's easy to dive in and make additions, but be sure to read the "Contributing Code" section below too -- as it doesn't hurt to have a discussion about a feature first -- we're inclined to have preferences about how incoming features might be implemented, and that can save confusion later. Helping with Documentation -------------------------- Ansible documentation is a community project too! If you would like to help with the documentation, whether correcting a typo or improving a section, or maybe even documenting a new feature, submit a github pull request to the code that lives in the “docsite/rst†subdirectory of the project. Docs are in restructured text format. If you aren’t comfortable with restructured text, you can also open a ticket on github about any errors you spot or sections you would like to see added. For more information on creating pull requests, please refer to the [github help guide](https://help.github.com/articles/using-pull-requests). Contributing Code (Features or Bugfixes) ---------------------------------------- The Ansible project keeps it’s source on github at [github.com/ansible/ansible](http://github.com/ansible/ansible) and takes contributions through [github pull requests](https://help.github.com/articles/using-pull-requests). It is usually a good idea to join the ansible-devel list to discuss any large features prior to submission, and this especially helps in avoiding duplicate work or efforts where we decide, upon seeing a pull request for the first time, that revisions are needed. (This is not usually needed for module development) Note that we do keep Ansible to a particular aesthetic, so if you are unclear about whether a feature is a good fit or not, having the discussion on the development list is often a lot easier than having to modify a pull request later. When submitting patches, be sure to run the unit tests first “make tests†and always use “git rebase†vs “git merge†(aliasing git pull to git pull --rebase is a great idea) to avoid merge commits in your submissions. There are also integration tests that can be run in the "tests/integration" directory. In order to keep the history clean and better audit incoming code, we will require resubmission of pull requests that contain merge commits. Use "git pull --rebase" vs "git pull" and "git rebase" vs "git merge". Also be sure to use topic branches to keep your additions on different branches, such that they won't pick up stray commits later. We’ll then review your contributions and engage with you about questions and so on. As we have a very large and active community, so it may take awhile to get your contributions in! See the notes about priorities in a later section for understanding our work queue. Patches should be made against the 'devel' branch. Contributions can be for new features like modules, or to fix bugs you or others have found. If you are interested in writing new modules to be included in the core Ansible distribution, please refer to the [Module Developers documentation on our website](http://docs.ansible.com/developing_modules.html). Ansible's aesthetic encourages simple, readable code and consistent, conservatively extending, backwards-compatible improvements. Code developed for Ansible needs to support Python 2.6+, while code in modules must run under Python 2.4 or higher. Please also use a 4-space indent and no tabs. Tip: To easily run from a checkout, source "./hacking/env-setup" and that's it -- no install required. You're now live! Reporting A Bug --------------- Ansible practices responsible disclosure - if this is a security related bug, email security@ansible.com instead of filing a ticket or posting to the Google Group and you will receive a prompt response. Bugs should be reported to [github.com/ansible/ansible](http://github.com/ansible/ansible) after signing up for a free github account. Before reporting a bug, please use the bug/issue search to see if the issue has already been reported. When filing a bug, please use the [issue template](https://raw2.github.com/ansible/ansible/devel/examples/issues/ISSUE_TEMPLATE.md) to provide all relevant information. Do not use the issue tracker for "how do I do this" type questions. These are great candidates for IRC or the mailing list instead where things are likely to be more of a discussion. To be respectful of reviewers time and allow us to help everyone efficiently, please provide minimal well-reduced and well-commented examples versus sharing your entire production playbook. Include playbook snippets and output where possible. Content in the GitHub bug tracker can be indented four spaces to preserve formatting. For multiple-file content, we encourage use of gist.github.com. Online pastebin content can expire. If you are not sure if something is a bug yet, you are welcome to ask about something on the mailing list or IRC first. As we are a very high volume project, if you determine that you do have a bug, please be sure to open the issue yourself to ensure we have a record of it. Don’t rely on someone else in the community to file the bug report for you. It may take some time to get to your report, see "A Note About Priorities" below. A Note About Priorities ======================= Ansible was one of the top 5 projects with the most OSS contributors on GitHub in 2013, and well over 600 people have added code to the project. As a result, we have a LOT of incoming activity to process. In the interest of transparency, we're telling you how we do this. In our bug tracker you'll notice some labels - P1, P2, P3, P4, and P5. These are our internal priority orders that we use to sort tickets. With some exceptions for easy merges (like documentation typos for instance), we're going to spend most of our time working on P1 and P2 items first, including pull requests. These usually relate to important bugs or features affecting large segments of the userbase. So if you see something categorized "P3 or P4", and it's not appearing to get a lot of immediate attention, this is why. These labels don't really have definition - they are a simple ordering. However something affecting a major module (yum, apt, etc) is likely to be prioritized higher than a module affecting a smaller number of users. Since we place a strong emphasis on testing and code review, it may take a few months for a minor feature to get merged. Don't worry though -- we'll also take periodic sweeps through the lower priority queues and give them some attention as well, particularly in the area of new module changes. So it doesn't neccessarily mean that we'll be exhausting all of the higher-priority queues before getting to your ticket. Release Numbering ================= Releases ending in ".0" are major releases and this is where all new features land. Releases ending in another integer, like "0.X.1" and "0.X.2" are dot releases, and these are only going to contain bugfixes. Typically we don't do dot releases for minor releases, but may occasionally decide to cut dot releases containing a large number of smaller fixes if it's still a fairly long time before the next release comes out. Online Resources ================ Documentation ------------- The main ansible documentation can be found at [docs.ansible.com](http://docs.ansible.com). As mentioned above this is an open source project, so we accept contributions to the documentation. You can also find some best practices examples that we recommend reading at [ansible-examples](http://github.com/ansible/ansible-examples). Mailing lists ------------- Ansible has several mailing lists. Your first post to the mailing list will be moderated (to reduce spam), so please allow a day or less for your first post. [ansible-announce](https://groups.google.com/forum/#!forum/ansible-announce) is for release announcements and major news. It is a low traffic read-only list and you should only get a few emails a month. [ansible-project](https://groups.google.com/forum/#!forum/ansible-project) is the main list, and is used for sharing cool projects you may have built, talking about Ansible ideas, and for users to ask questions or to help other users. [ansible-devel](https://groups.google.com/forum/#!forum/ansible-devel) is a technical list for developers working on Ansible and Ansible modules. Join here to discuss how to build modules, prospective feature implementations, or technical challenges. To subscribe to a group from a non-google account, you can email the subscription address, for example ansible-devel+subscribe@googlegroups.com. IRC --- Ansible has a general purpose IRC channel available at #ansible on irc.freenode.net. Use this channel for all types of conversations, including sharing tips, coordinating development work, or getting help from other users. Miscellaneous Information ========================= Staff ----- Ansible, Inc is a company supporting Ansible and building additional solutions based on Ansible. We also do services and support for those that are interested. Our most important task however is enabling all the great things that happen in the Ansible community, including organizing software releases of Ansible. For more information about any of these things, contact info@ansible.com On IRC, you can find us as mdehaan, jimi_c, Tybstar, and others. On the mailing list, we post with an @ansible.com address. Community Code of Conduct ------------------------- Ansible’s community welcomes users of all types, backgrounds, and skill levels. Please treat others as you expect to be treated, keep discussions positive, and avoid discrimination, profanity, allegations of Cthulhu worship, or engaging in controversial debates (except vi vs emacs is cool). Posts to mailing lists should remain focused around Ansible and IT automation. Abuse of these community guidelines will not be tolerated and may result in banning from community resources. Contributors License Agreement ------------------------------ By contributing you agree that these contributions are your own (or approved by your employer) and you grant a full, complete, irrevocable copyright license to all users and developers of the project, present and future, pursuant to the license of the project. ansible-1.7.2/COPYING000066400000000000000000001045141241061774000142000ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ansible-1.7.2/MANIFEST.in000066400000000000000000000005011241061774000146720ustar00rootroot00000000000000include README.md packaging/rpm/ansible.spec COPYING include examples/hosts include examples/ansible.cfg graft examples/playbooks include packaging/distutils/setup.py include lib/ansible/module_utils/powershell.ps1 recursive-include docs * recursive-include library * include Makefile include VERSION include MANIFEST.in ansible-1.7.2/Makefile000066400000000000000000000202671241061774000146070ustar00rootroot00000000000000#!/usr/bin/make # WARN: gmake syntax ######################################################## # Makefile for Ansible # # useful targets: # make sdist ---------------- produce a tarball # make srpm ----------------- produce a SRPM # make rpm ----------------- produce RPMs # make deb-src -------------- produce a DEB source # make deb ------------------ produce a DEB # make docs ----------------- rebuild the manpages (results are checked in) # make tests ---------------- run the tests # make pyflakes, make pep8 -- source code checks ######################################################## # variable section NAME = ansible OS = $(shell uname -s) # Manpages are currently built with asciidoc -- would like to move to markdown # This doesn't evaluate until it's called. The -D argument is the # directory of the target file ($@), kinda like `dirname`. MANPAGES := docs/man/man1/ansible.1 docs/man/man1/ansible-playbook.1 docs/man/man1/ansible-pull.1 docs/man/man1/ansible-doc.1 docs/man/man1/ansible-galaxy.1 docs/man/man1/ansible-vault.1 ifneq ($(shell which a2x 2>/dev/null),) ASCII2MAN = a2x -D $(dir $@) -d manpage -f manpage $< ASCII2HTMLMAN = a2x -D docs/html/man/ -d manpage -f xhtml else ASCII2MAN = @echo "ERROR: AsciiDoc 'a2x' command is not installed but is required to build $(MANPAGES)" && exit 1 endif PYTHON=python SITELIB = $(shell $(PYTHON) -c "from distutils.sysconfig import get_python_lib; print get_python_lib()") # VERSION file provides one place to update the software version VERSION := $(shell cat VERSION) # Get the branch information from git ifneq ($(shell which git),) GIT_DATE := $(shell git log -n 1 --format="%ai") endif ifeq ($(shell echo $(OS) | egrep -c 'Darwin|FreeBSD|OpenBSD'),1) DATE := $(shell date -j -r $(shell git log -n 1 --format="%at") +%Y%m%d%H%M) else DATE := $(shell date --utc --date="$(GIT_DATE)" +%Y%m%d%H%M) endif # DEB build parameters DEBUILD_BIN ?= debuild DEBUILD_OPTS = --source-option="-I" DPUT_BIN ?= dput DPUT_OPTS ?= ifeq ($(OFFICIAL),yes) DEB_RELEASE = 1ppa # Sign OFFICIAL builds using 'DEBSIGN_KEYID' # DEBSIGN_KEYID is required when signing ifneq ($(DEBSIGN_KEYID),) DEBUILD_OPTS += -k$(DEBSIGN_KEYID) endif else DEB_RELEASE = 0.git$(DATE) # Do not sign unofficial builds DEBUILD_OPTS += -uc -us DPUT_OPTS += -u endif DEBUILD = $(DEBUILD_BIN) $(DEBUILD_OPTS) DEB_PPA ?= ppa # Choose the desired Ubuntu release: lucid precise saucy trusty DEB_DIST ?= unstable # RPM build parameters RPMSPECDIR= packaging/rpm RPMSPEC = $(RPMSPECDIR)/ansible.spec RPMDIST = $(shell rpm --eval '%{?dist}') RPMRELEASE = 1 ifneq ($(OFFICIAL),yes) RPMRELEASE = 0.git$(DATE) endif RPMNVR = "$(NAME)-$(VERSION)-$(RPMRELEASE)$(RPMDIST)" # MOCK build parameters MOCK_BIN ?= mock MOCK_CFG ?= NOSETESTS ?= nosetests ######################################################## all: clean python tests: PYTHONPATH=./lib ANSIBLE_LIBRARY=./library $(NOSETESTS) -d -w test/units -v authors: sh hacking/authors.sh # Regenerate %.1.asciidoc if %.1.asciidoc.in has been modified more # recently than %.1.asciidoc. %.1.asciidoc: %.1.asciidoc.in sed "s/%VERSION%/$(VERSION)/" $< > $@ # Regenerate %.1 if %.1.asciidoc or VERSION has been modified more # recently than %.1. (Implicitly runs the %.1.asciidoc recipe) %.1: %.1.asciidoc VERSION $(ASCII2MAN) loc: sloccount lib library bin pep8: @echo "#############################################" @echo "# Running PEP8 Compliance Tests" @echo "#############################################" -pep8 -r --ignore=E501,E221,W291,W391,E302,E251,E203,W293,E231,E303,E201,E225,E261,E241 lib/ bin/ -pep8 -r --ignore=E501,E221,W291,W391,E302,E251,E203,W293,E231,E303,E201,E225,E261,E241 --filename "*" library/ pyflakes: pyflakes lib/ansible/*.py lib/ansible/*/*.py bin/* clean: @echo "Cleaning up distutils stuff" rm -rf build rm -rf dist @echo "Cleaning up byte compiled python stuff" find . -type f -regex ".*\.py[co]$$" -delete @echo "Cleaning up editor backup files" find . -type f \( -name "*~" -or -name "#*" \) -delete find . -type f \( -name "*.swp" \) -delete @echo "Cleaning up manpage stuff" find ./docs/man -type f -name "*.xml" -delete find ./docs/man -type f -name "*.asciidoc" -delete find ./docs/man/man3 -type f -name "*.3" -delete @echo "Cleaning up output from test runs" rm -rf test/test_data @echo "Cleaning up RPM building stuff" rm -rf MANIFEST rpm-build @echo "Cleaning up Debian building stuff" rm -rf debian rm -rf deb-build rm -rf docs/json rm -rf docs/js @echo "Cleaning up authors file" rm -f AUTHORS.TXT python: $(PYTHON) setup.py build install: $(PYTHON) setup.py install sdist: clean docs $(PYTHON) setup.py sdist rpmcommon: $(MANPAGES) sdist @mkdir -p rpm-build @cp dist/*.gz rpm-build/ @sed -e 's#^Version:.*#Version: $(VERSION)#' -e 's#^Release:.*#Release: $(RPMRELEASE)%{?dist}#' $(RPMSPEC) >rpm-build/$(NAME).spec mock-srpm: /etc/mock/$(MOCK_CFG).cfg rpmcommon $(MOCK_BIN) -r $(MOCK_CFG) --resultdir rpm-build/ --buildsrpm --spec rpm-build/$(NAME).spec --sources rpm-build/ @echo "#############################################" @echo "Ansible SRPM is built:" @echo rpm-build/*.src.rpm @echo "#############################################" mock-rpm: /etc/mock/$(MOCK_CFG).cfg mock-srpm $(MOCK_BIN) -r $(MOCK_CFG) --resultdir rpm-build/ --rebuild rpm-build/$(NAME)-*.src.rpm @echo "#############################################" @echo "Ansible RPM is built:" @echo rpm-build/*.noarch.rpm @echo "#############################################" srpm: rpmcommon @rpmbuild --define "_topdir %(pwd)/rpm-build" \ --define "_builddir %{_topdir}" \ --define "_rpmdir %{_topdir}" \ --define "_srcrpmdir %{_topdir}" \ --define "_specdir $(RPMSPECDIR)" \ --define "_sourcedir %{_topdir}" \ -bs rpm-build/$(NAME).spec @rm -f rpm-build/$(NAME).spec @echo "#############################################" @echo "Ansible SRPM is built:" @echo " rpm-build/$(RPMNVR).src.rpm" @echo "#############################################" rpm: rpmcommon @rpmbuild --define "_topdir %(pwd)/rpm-build" \ --define "_builddir %{_topdir}" \ --define "_rpmdir %{_topdir}" \ --define "_srcrpmdir %{_topdir}" \ --define "_specdir $(RPMSPECDIR)" \ --define "_sourcedir %{_topdir}" \ --define "_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \ --define "__python `which $(PYTHON)`" \ -ba rpm-build/$(NAME).spec @rm -f rpm-build/$(NAME).spec @echo "#############################################" @echo "Ansible RPM is built:" @echo " rpm-build/$(RPMNVR).noarch.rpm" @echo "#############################################" debian: sdist @for DIST in $(DEB_DIST) ; do \ mkdir -p deb-build/$${DIST} ; \ tar -C deb-build/$${DIST} -xvf dist/$(NAME)-$(VERSION).tar.gz ; \ cp -a packaging/debian deb-build/$${DIST}/$(NAME)-$(VERSION)/ ; \ sed -ie "s#^$(NAME) (\([^)]*\)) \([^;]*\);#ansible (\1-$(DEB_RELEASE)~$${DIST}) $${DIST};#" deb-build/$${DIST}/$(NAME)-$(VERSION)/debian/changelog ; \ done deb: debian @for DIST in $(DEB_DIST) ; do \ (cd deb-build/$${DIST}/$(NAME)-$(VERSION)/ && $(DEBUILD) -b) ; \ done @echo "#############################################" @echo "Ansible DEB artifacts:" @for DIST in $(DEB_DIST) ; do \ echo deb-build/$${DIST}/$(NAME)_$(VERSION)-$(DEB_RELEASE)~$${DIST}_amd64.changes ; \ done @echo "#############################################" deb-src: debian @for DIST in $(DEB_DIST) ; do \ (cd deb-build/$${DIST}/$(NAME)-$(VERSION)/ && $(DEBUILD) -S) ; \ done @echo "#############################################" @echo "Ansible DEB artifacts:" @for DIST in $(DEB_DIST) ; do \ echo deb-build/$${DIST}/$(NAME)_$(VERSION)-$(DEB_RELEASE)~$${DIST}_source.changes ; \ done @echo "#############################################" deb-upload: deb @for DIST in $(DEB_DIST) ; do \ $(DPUT_BIN) $(DPUT_OPTS) $(DEB_PPA) deb-build/$${DIST}/$(NAME)_$(VERSION)-$(DEB_RELEASE)~$${DIST}_amd64.changes ; \ done deb-src-upload: deb-src @for DIST in $(DEB_DIST) ; do \ $(DPUT_BIN) $(DPUT_OPTS) $(DEB_PPA) deb-build/$${DIST}/$(NAME)_$(VERSION)-$(DEB_RELEASE)~$${DIST}_source.changes ; \ done # for arch or gentoo, read instructions in the appropriate 'packaging' subdirectory directory webdocs: $(MANPAGES) (cd docsite/; make docs) docs: $(MANPAGES) ansible-1.7.2/README.md000066400000000000000000000050771241061774000144300ustar00rootroot00000000000000[![PyPI version](https://badge.fury.io/py/ansible.png)](http://badge.fury.io/py/ansible) [![PyPI downloads](https://pypip.in/d/ansible/badge.png)](https://pypi.python.org/pypi/ansible) Ansible ======= Ansible is a radically simple configuration-management, application deployment, task-execution, and multinode orchestration engine. Read the documentation and more at http://ansible.com/ Many users run straight from the development branch (it's generally fine to do so), but you might also wish to consume a release. You can find instructions [here](http://docs.ansible.com/intro_getting_started.html) for a variety of platforms. If you want a tarball of the last release, go to [releases.ansible.com](http://releases.ansible.com/ansible) and you can also install with pip. Design Principles ================= * Have a dead simple setup process and a minimal learning curve * Be super fast & parallel by default * Require no server or client daemons; use existing SSHd * Use a language that is both machine and human friendly * Focus on security and easy auditability/review/rewriting of content * Manage remote machines instantly, without bootstrapping * Allow module development in any dynamic language, not just Python * Be usable as non-root * Be the easiest IT automation system to use, ever. Get Involved ============ * Read [Contributing.md](https://github.com/ansible/ansible/blob/devel/CONTRIBUTING.md) for all kinds of ways to contribute to and interact with the project, including mailing list information and how to submit bug reports and code to Ansible. * All code submissions are done through pull requests. Take care to make sure no merge commits are in the submission, and use "git rebase" vs "git merge" for this reason. If submitting a large code change (other than modules), it's probably a good idea to join ansible-devel and talk about what you would like to do or add first and to avoid duplicate efforts. This not only helps everyone know what's going on, it also helps save time and effort if we decide some changes are needed. * irc.freenode.net: #ansible Branch Info =========== * Releases are named after Van Halen songs. * The devel branch corresponds to the release actively under development. * Various release-X.Y branches exist for previous releases * We'd love to have your contributions, read "CONTRIBUTING.md" for process notes. Author ====== Ansible was created by Michael DeHaan (michael@ansible.com) and has contributions from over 700 users (and growing). Thanks everyone! [Ansible, Inc](http://ansible.com) ansible-1.7.2/RELEASES.txt000066400000000000000000000040241241061774000151040ustar00rootroot00000000000000Ansible Releases at a Glance ============================ Active Development ++++++++++++++++++ 1.8 "You Really Got Me" ---- FALL 2014 1.7.2 "Summer Nights" -------- 09-24-2014 1.7.1 "Summer Nights" -------- 08-14-2014 1.7 "Summer Nights" -------- 08-06-2014 1.6.10 "The Cradle Will Rock" - 07-25-2014 1.6.9 "The Cradle Will Rock" - 07-24-2014 1.6.8 "The Cradle Will Rock" - 07-22-2014 1.6.7 "The Cradle Will Rock" - 07-21-2014 1.6.6 "The Cradle Will Rock" - 07-01-2014 1.6.5 "The Cradle Will Rock" - 06-25-2014 1.6.4 "The Cradle Will Rock" - 06-25-2014 1.6.3 "The Cradle Will Rock" - 06-09-2014 1.6.2 "The Cradle Will Rock" - 05-23-2014 1.6.1 "The Cradle Will Rock" - 05-07-2014 1.6 "The Cradle Will Rock" - 05-05-2014 1.5.5 "Love Walks In" -------- 04-18-2014 1.5.4 "Love Walks In" -------- 04-01-2014 1.5.3 "Love Walks In" -------- 03-13-2014 1.5.2 "Love Walks In" -------- 03-11-2014 1.5.1 "Love Walks In" -------- 03-10-2014 1.5 "Love Walks In" -------- 02-28-2014 1.4.5 "Could This Be Magic?" - 02-12-2014 1.4.4 "Could This Be Magic?" - 01-06-2014 1.4.3 "Could This Be Magic?" - 12-20-2013 1.4.2 "Could This Be Magic?" - 12-18-2013 1.4.1 "Could This Be Magic?" - 11-27-2013 1.4 "Could This Be Magic?" - 11-21-2013 1.3.4 "Top of the World" ----- 10-29-2013 1.3.3 "Top of the World" ----- 10-09-2013 1.3.2 "Top of the World" ----- 09-19-2013 1.3.1 "Top of the World" ----- 09-16-2013 1.3 "Top of the World" ----- 09-13-2013 1.2.3 "Hear About It Later" -- 08-21-2013 1.2.2 "Hear About It Later" -- 07-05-2013 1.2.1 "Hear About It Later" -- 07-04-2013 1.2 "Right Now" ------------ 06-10-2013 1.1 "Mean Street" ---------- 04-02-2013 1.0 "Eruption" ------------- 02-01-2013 0.9 "Dreams" --------------- 11-30-2012 0.8 "Cathedral" ------------ 10-19-2012 0.7 "Panama" --------------- 09-06-2012 0.6 "Cabo" ----------------- 08-06-2012 0.5 "Amsterdam" ------------ 07-04-2012 0.4 "Unchained" ------------ 05-23-2012 0.3 "Baluchitherium" ------- 04-23-2012 0.0.2 Untitled 0.0.1 Untitled ansible-1.7.2/VERSION000066400000000000000000000000061241061774000142040ustar00rootroot000000000000001.7.2 ansible-1.7.2/bin/000077500000000000000000000000001241061774000137105ustar00rootroot00000000000000ansible-1.7.2/bin/ansible000077500000000000000000000175751241061774000152720ustar00rootroot00000000000000#!/usr/bin/env python # (c) 2012, Michael DeHaan # # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . ######################################################## import os import sys from ansible.runner import Runner import ansible.constants as C from ansible import utils from ansible import errors from ansible import callbacks from ansible import inventory ######################################################## class Cli(object): ''' code behind bin/ansible ''' # ---------------------------------------------- def __init__(self): self.stats = callbacks.AggregateStats() self.callbacks = callbacks.CliRunnerCallbacks() # ---------------------------------------------- def parse(self): ''' create an options parser for bin/ansible ''' parser = utils.base_parser( constants=C, runas_opts=True, subset_opts=True, async_opts=True, output_opts=True, connect_opts=True, check_opts=True, diff_opts=False, usage='%prog [options]' ) parser.add_option('-a', '--args', dest='module_args', help="module arguments", default=C.DEFAULT_MODULE_ARGS) parser.add_option('-m', '--module-name', dest='module_name', help="module name to execute (default=%s)" % C.DEFAULT_MODULE_NAME, default=C.DEFAULT_MODULE_NAME) options, args = parser.parse_args() self.callbacks.options = options if len(args) == 0 or len(args) > 1: parser.print_help() sys.exit(1) # su and sudo command line arguments need to be mutually exclusive if (options.su or options.su_user or options.ask_su_pass) and \ (options.sudo or options.sudo_user or options.ask_sudo_pass): parser.error("Sudo arguments ('--sudo', '--sudo-user', and '--ask-sudo-pass') " "and su arguments ('-su', '--su-user', and '--ask-su-pass') are " "mutually exclusive") if (options.ask_vault_pass and options.vault_password_file): parser.error("--ask-vault-pass and --vault-password-file are mutually exclusive") return (options, args) # ---------------------------------------------- def run(self, options, args): ''' use Runner lib to do SSH things ''' pattern = args[0] """ inventory_manager = inventory.Inventory(options.inventory) if options.subset: inventory_manager.subset(options.subset) hosts = inventory_manager.list_hosts(pattern) if len(hosts) == 0: callbacks.display("No hosts matched", stderr=True) sys.exit(0) if options.listhosts: for host in hosts: callbacks.display(' %s' % host) sys.exit(0) if ((options.module_name == 'command' or options.module_name == 'shell') and not options.module_args): callbacks.display("No argument passed to %s module" % options.module_name, color='red', stderr=True) sys.exit(1) """ sshpass = None sudopass = None su_pass = None vault_pass = None options.ask_pass = options.ask_pass or C.DEFAULT_ASK_PASS # Never ask for an SSH password when we run with local connection if options.connection == "local": options.ask_pass = False options.ask_sudo_pass = options.ask_sudo_pass or C.DEFAULT_ASK_SUDO_PASS options.ask_su_pass = options.ask_su_pass or C.DEFAULT_ASK_SU_PASS options.ask_vault_pass = options.ask_vault_pass or C.DEFAULT_ASK_VAULT_PASS (sshpass, sudopass, su_pass, vault_pass) = utils.ask_passwords(ask_pass=options.ask_pass, ask_sudo_pass=options.ask_sudo_pass, ask_su_pass=options.ask_su_pass, ask_vault_pass=options.ask_vault_pass) # read vault_pass from a file if not options.ask_vault_pass and options.vault_password_file: vault_pass = utils.read_vault_file(options.vault_password_file) inventory_manager = inventory.Inventory(options.inventory, vault_password=vault_pass) if options.subset: inventory_manager.subset(options.subset) hosts = inventory_manager.list_hosts(pattern) if len(hosts) == 0: callbacks.display("No hosts matched", stderr=True) sys.exit(0) if options.listhosts: for host in hosts: callbacks.display(' %s' % host) sys.exit(0) if ((options.module_name == 'command' or options.module_name == 'shell') and not options.module_args): callbacks.display("No argument passed to %s module" % options.module_name, color='red', stderr=True) sys.exit(1) if options.su_user or options.ask_su_pass: options.su = True options.sudo_user = options.sudo_user or C.DEFAULT_SUDO_USER options.su_user = options.su_user or C.DEFAULT_SU_USER if options.tree: utils.prepare_writeable_dir(options.tree) runner = Runner( module_name=options.module_name, module_path=options.module_path, module_args=options.module_args, remote_user=options.remote_user, remote_pass=sshpass, inventory=inventory_manager, timeout=options.timeout, private_key_file=options.private_key_file, forks=options.forks, pattern=pattern, callbacks=self.callbacks, sudo=options.sudo, sudo_pass=sudopass, sudo_user=options.sudo_user, transport=options.connection, subset=options.subset, check=options.check, diff=options.check, su=options.su, su_pass=su_pass, su_user=options.su_user, vault_pass=vault_pass ) if options.seconds: callbacks.display("background launch...\n\n", color='cyan') results, poller = runner.run_async(options.seconds) results = self.poll_while_needed(poller, options) else: results = runner.run() return (runner, results) # ---------------------------------------------- def poll_while_needed(self, poller, options): ''' summarize results from Runner ''' # BACKGROUND POLL LOGIC when -B and -P are specified if options.seconds and options.poll_interval > 0: poller.wait(options.seconds, options.poll_interval) return poller.results ######################################################## if __name__ == '__main__': callbacks.display("", log_only=True) callbacks.display(" ".join(sys.argv), log_only=True) callbacks.display("", log_only=True) cli = Cli() (options, args) = cli.parse() try: (runner, results) = cli.run(options, args) for result in results['contacted'].values(): if 'failed' in result or result.get('rc', 0) != 0: sys.exit(2) if results['dark']: sys.exit(3) except errors.AnsibleError, e: # Generic handler for ansible specific errors callbacks.display("ERROR: %s" % str(e), stderr=True, color='red') sys.exit(1) ansible-1.7.2/bin/ansible-doc000077500000000000000000000225061241061774000160230ustar00rootroot00000000000000#!/usr/bin/env python # (c) 2012, Jan-Piet Mens # # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . # import os import sys import textwrap import re import optparse import datetime import subprocess from ansible import utils from ansible.utils import module_docs import ansible.constants as C from ansible.utils import version import traceback MODULEDIR = C.DEFAULT_MODULE_PATH BLACKLIST_EXTS = ('.swp', '.bak', '~', '.rpm') _ITALIC = re.compile(r"I\(([^)]+)\)") _BOLD = re.compile(r"B\(([^)]+)\)") _MODULE = re.compile(r"M\(([^)]+)\)") _URL = re.compile(r"U\(([^)]+)\)") _CONST = re.compile(r"C\(([^)]+)\)") PAGER = 'less' LESS_OPTS = 'FRSX' # -F (quit-if-one-screen) -R (allow raw ansi control chars) # -S (chop long lines) -X (disable termcap init and de-init) def pager_print(text): ''' just print text ''' print text def pager_pipe(text, cmd): ''' pipe text through a pager ''' if 'LESS' not in os.environ: os.environ['LESS'] = LESS_OPTS try: cmd = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=sys.stdout) cmd.communicate(input=text) except IOError: pass except KeyboardInterrupt: pass def pager(text): ''' find reasonable way to display text ''' # this is a much simpler form of what is in pydoc.py if not sys.stdout.isatty(): pager_print(text) elif 'PAGER' in os.environ: if sys.platform == 'win32': pager_print(text) else: pager_pipe(text, os.environ['PAGER']) elif hasattr(os, 'system') and os.system('(less) 2> /dev/null') == 0: pager_pipe(text, 'less') else: pager_print(text) def tty_ify(text): t = _ITALIC.sub("`" + r"\1" + "'", text) # I(word) => `word' t = _BOLD.sub("*" + r"\1" + "*", t) # B(word) => *word* t = _MODULE.sub("[" + r"\1" + "]", t) # M(word) => [word] t = _URL.sub(r"\1", t) # U(word) => word t = _CONST.sub("`" + r"\1" + "'", t) # C(word) => `word' return t def get_man_text(doc): opt_indent=" " text = [] text.append("> %s\n" % doc['module'].upper()) desc = "".join(doc['description']) text.append("%s\n" % textwrap.fill(tty_ify(desc), initial_indent=" ", subsequent_indent=" ")) if 'option_keys' in doc and len(doc['option_keys']) > 0: text.append("Options (= is mandatory):\n") for o in sorted(doc['option_keys']): opt = doc['options'][o] if opt.get('required', False): opt_leadin = "=" else: opt_leadin = "-" text.append("%s %s" % (opt_leadin, o)) desc = "".join(opt['description']) if 'choices' in opt: choices = ", ".join(str(i) for i in opt['choices']) desc = desc + " (Choices: " + choices + ")" if 'default' in opt: default = str(opt['default']) desc = desc + " [Default: " + default + "]" text.append("%s\n" % textwrap.fill(tty_ify(desc), initial_indent=opt_indent, subsequent_indent=opt_indent)) if 'notes' in doc and len(doc['notes']) > 0: notes = "".join(doc['notes']) text.append("Notes:%s\n" % textwrap.fill(tty_ify(notes), initial_indent=" ", subsequent_indent=opt_indent)) if 'requirements' in doc and doc['requirements'] is not None and len(doc['requirements']) > 0: req = ", ".join(doc['requirements']) text.append("Requirements:%s\n" % textwrap.fill(tty_ify(req), initial_indent=" ", subsequent_indent=opt_indent)) if 'examples' in doc and len(doc['examples']) > 0: text.append("Example%s:\n" % ('' if len(doc['examples']) < 2 else 's')) for ex in doc['examples']: text.append("%s\n" % (ex['code'])) if 'plainexamples' in doc and doc['plainexamples'] is not None: text.append(doc['plainexamples']) text.append('') return "\n".join(text) def get_snippet_text(doc): text = [] desc = tty_ify("".join(doc['short_description'])) text.append("- name: %s" % (desc)) text.append(" action: %s" % (doc['module'])) for o in sorted(doc['options'].keys()): opt = doc['options'][o] desc = tty_ify("".join(opt['description'])) if opt.get('required', False): s = o + "=" else: s = o text.append(" %-20s # %s" % (s, desc)) text.append('') return "\n".join(text) def get_module_list_text(module_list): text = [] for module in sorted(set(module_list)): if module in module_docs.BLACKLIST_MODULES: continue filename = utils.plugins.module_finder.find_plugin(module) if filename is None: continue if filename.endswith(".ps1"): continue if os.path.isdir(filename): continue try: doc, plainexamples = module_docs.get_docstring(filename) desc = tty_ify(doc.get('short_description', '?')) if len(desc) > 55: desc = desc + '...' text.append("%-20s %-60.60s" % (module, desc)) except: traceback.print_exc() sys.stderr.write("ERROR: module %s has a documentation error formatting or is missing documentation\n" % module) return "\n".join(text) def main(): p = optparse.OptionParser( version=version("%prog"), usage='usage: %prog [options] [module...]', description='Show Ansible module documentation', ) p.add_option("-M", "--module-path", action="store", dest="module_path", default=MODULEDIR, help="Ansible modules/ directory") p.add_option("-l", "--list", action="store_true", default=False, dest='list_dir', help='List available modules') p.add_option("-s", "--snippet", action="store_true", default=False, dest='show_snippet', help='Show playbook snippet for specified module(s)') p.add_option('-v', action='version', help='Show version number and exit') (options, args) = p.parse_args() if options.module_path is not None: for i in options.module_path.split(os.pathsep): utils.plugins.module_finder.add_directory(i) if options.list_dir: # list all modules paths = utils.plugins.module_finder._get_paths() module_list = [] for path in paths: # os.system("ls -C %s" % (path)) if os.path.isdir(path): for module in os.listdir(path): if any(module.endswith(x) for x in BLACKLIST_EXTS): continue module_list.append(module) pager(get_module_list_text(module_list)) sys.exit() if len(args) == 0: p.print_help() def print_paths(finder): ''' Returns a string suitable for printing of the search path ''' # Uses a list to get the order right ret = [] for i in finder._get_paths(): if i not in ret: ret.append(i) return os.pathsep.join(ret) text = '' for module in args: filename = utils.plugins.module_finder.find_plugin(module) if filename is None: sys.stderr.write("module %s not found in %s\n" % (module, print_paths(utils.plugins.module_finder))) continue if any(filename.endswith(x) for x in BLACKLIST_EXTS): continue try: doc, plainexamples = module_docs.get_docstring(filename) except: traceback.print_exc() sys.stderr.write("ERROR: module %s has a documentation error formatting or is missing documentation\n" % module) continue if doc is not None: all_keys = [] for (k,v) in doc['options'].iteritems(): all_keys.append(k) all_keys = sorted(all_keys) doc['option_keys'] = all_keys doc['filename'] = filename doc['docuri'] = doc['module'].replace('_', '-') doc['now_date'] = datetime.date.today().strftime('%Y-%m-%d') doc['plainexamples'] = plainexamples if options.show_snippet: text += get_snippet_text(doc) else: text += get_man_text(doc) else: # this typically means we couldn't even parse the docstring, not just that the YAML is busted, # probably a quoting issue. sys.stderr.write("ERROR: module %s missing documentation (or could not parse documentation)\n" % module) pager(text) if __name__ == '__main__': main() ansible-1.7.2/bin/ansible-galaxy000077500000000000000000000735331241061774000165510ustar00rootroot00000000000000#!/usr/bin/env python ######################################################################## # # (C) 2013, James Cammarata # # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . # ######################################################################## import datetime import json import os import os.path import shutil import sys import tarfile import tempfile import urllib import urllib2 import yaml from collections import defaultdict from distutils.version import LooseVersion from jinja2 import Environment from optparse import OptionParser import ansible.constants as C default_meta_template = """--- galaxy_info: author: {{ author }} description: {{description}} company: {{ company }} # Some suggested licenses: # - BSD (default) # - MIT # - GPLv2 # - GPLv3 # - Apache # - CC-BY license: {{ license }} min_ansible_version: {{ min_ansible_version }} # # Below are all platforms currently available. Just uncomment # the ones that apply to your role. If you don't see your # platform on this list, let us know and we'll get it added! # #platforms: {%- for platform,versions in platforms.iteritems() %} #- name: {{ platform }} # versions: # - all {%- for version in versions %} # - {{ version }} {%- endfor %} {%- endfor %} # # Below are all categories currently available. Just as with # the platforms above, uncomment those that apply to your role. # #categories: {%- for category in categories %} #- {{ category.name }} {%- endfor %} dependencies: [] # List your role dependencies here, one per line. Only # dependencies available via galaxy should be listed here. # Be sure to remove the '[]' above if you add dependencies # to this list. {% for dependency in dependencies %} #- {{ dependency }} {% endfor %} """ default_readme_template = """Role Name ========= A brief description of the role goes here. Requirements ------------ Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. Role Variables -------------- A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. Dependencies ------------ A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. Example Playbook ---------------- Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: - hosts: servers roles: - { role: username.rolename, x: 42 } License ------- BSD Author Information ------------------ An optional section for the role authors to include contact information, or a website (HTML is not allowed). """ #------------------------------------------------------------------------------------- # Utility functions for parsing actions/options #------------------------------------------------------------------------------------- VALID_ACTIONS = ("init", "info", "install", "list", "remove") def get_action(args): """ Get the action the user wants to execute from the sys argv list. """ for i in range(0,len(args)): arg = args[i] if arg in VALID_ACTIONS: del args[i] return arg return None def build_option_parser(action): """ Builds an option parser object based on the action the user wants to execute. """ usage = "usage: %%prog [%s] [--help] [options] ..." % "|".join(VALID_ACTIONS) epilog = "\nSee '%s --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0]) OptionParser.format_epilog = lambda self, formatter: self.epilog parser = OptionParser(usage=usage, epilog=epilog) if not action: parser.print_help() sys.exit() # options for all actions # - none yet # options specific to actions if action == "info": parser.set_usage("usage: %prog info [options] role_name[,version]") elif action == "init": parser.set_usage("usage: %prog init [options] role_name") parser.add_option( '-p', '--init-path', dest='init_path', default="./", help='The path in which the skeleton role will be created. ' 'The default is the current working directory.') elif action == "install": parser.set_usage("usage: %prog install [options] [-r FILE | role_name(s)[,version] | tar_file(s)]") parser.add_option( '-i', '--ignore-errors', dest='ignore_errors', action='store_true', default=False, help='Ignore errors and continue with the next specified role.') parser.add_option( '-n', '--no-deps', dest='no_deps', action='store_true', default=False, help='Don\'t download roles listed as dependencies') parser.add_option( '-r', '--role-file', dest='role_file', help='A file containing a list of roles to be imported') elif action == "remove": parser.set_usage("usage: %prog remove role1 role2 ...") elif action == "list": parser.set_usage("usage: %prog list [role_name]") # options that apply to more than one action if action != "init": parser.add_option( '-p', '--roles-path', dest='roles_path', default=C.DEFAULT_ROLES_PATH, help='The path to the directory containing your roles. ' 'The default is the roles_path configured in your ' 'ansible.cfg file (/etc/ansible/roles if not configured)') if action in ("info","init","install"): parser.add_option( '-s', '--server', dest='api_server', default="galaxy.ansible.com", help='The API server destination') if action in ("init","install"): parser.add_option( '-f', '--force', dest='force', action='store_true', default=False, help='Force overwriting an existing role') # done, return the parser return parser def get_opt(options, k, defval=""): """ Returns an option from an Optparse values instance. """ try: data = getattr(options, k) except: return defval if k == "roles_path": if os.pathsep in data: data = data.split(os.pathsep)[0] return data def exit_without_ignore(options, rc=1): """ Exits with the specified return code unless the option --ignore-errors was specified """ if not get_opt(options, "ignore_errors", False): print 'You can use --ignore-errors to skip failed roles.' sys.exit(rc) #------------------------------------------------------------------------------------- # Galaxy API functions #------------------------------------------------------------------------------------- def api_get_config(api_server): """ Fetches the Galaxy API current version to ensure the API server is up and reachable. """ try: url = 'https://%s/api/' % api_server data = json.load(urllib2.urlopen(url)) if not data.get("current_version",None): return None else: return data except: return None def api_lookup_role_by_name(api_server, role_name): """ Uses the Galaxy API to do a lookup on the role owner/name. """ role_name = urllib.quote(role_name) try: parts = role_name.split(".") user_name = ".".join(parts[0:-1]) role_name = parts[-1] print " downloading role '%s', owned by %s" % (role_name, user_name) except: parser.print_help() print "Invalid role name (%s). You must specify username.rolename" % role_name sys.exit(1) url = 'https://%s/api/v1/roles/?owner__username=%s&name=%s' % (api_server,user_name,role_name) try: data = json.load(urllib2.urlopen(url)) if len(data["results"]) == 0: return None else: return data["results"][0] except: return None def api_fetch_role_related(api_server, related, role_id): """ Uses the Galaxy API to fetch the list of related items for the given role. The url comes from the 'related' field of the role. """ try: url = 'https://%s/api/v1/roles/%d/%s/?page_size=50' % (api_server, int(role_id), related) data = json.load(urllib2.urlopen(url)) results = data['results'] done = (data.get('next', None) == None) while not done: url = 'https://%s%s' % (api_server, data['next']) print url data = json.load(urllib2.urlopen(url)) results += data['results'] done = (data.get('next', None) == None) return results except: return None def api_get_list(api_server, what): """ Uses the Galaxy API to fetch the list of items specified. """ try: url = 'https://%s/api/v1/%s/?page_size' % (api_server, what) data = json.load(urllib2.urlopen(url)) if "results" in data: results = data['results'] else: results = data done = True if "next" in data: done = (data.get('next', None) == None) while not done: url = 'https://%s%s' % (api_server, data['next']) print url data = json.load(urllib2.urlopen(url)) results += data['results'] done = (data.get('next', None) == None) return results except: print " - failed to download the %s list" % what return None #------------------------------------------------------------------------------------- # Role utility functions #------------------------------------------------------------------------------------- def get_role_path(role_name, options): """ Returns the role path based on the roles_path option and the role name. """ roles_path = get_opt(options,'roles_path') roles_path = os.path.join(roles_path, role_name) roles_path = os.path.expanduser(roles_path) return roles_path def get_role_metadata(role_name, options): """ Returns the metadata as YAML, if the file 'meta/main.yml' exists in the specified role_path """ role_path = os.path.join(get_role_path(role_name, options), 'meta/main.yml') try: if os.path.isfile(role_path): f = open(role_path, 'r') meta_data = yaml.safe_load(f) f.close() return meta_data else: return None except: return None def get_galaxy_install_info(role_name, options): """ Returns the YAML data contained in 'meta/.galaxy_install_info', if it exists. """ try: info_path = os.path.join(get_role_path(role_name, options), 'meta/.galaxy_install_info') if os.path.isfile(info_path): f = open(info_path, 'r') info_data = yaml.safe_load(f) f.close() return info_data else: return None except: return None def write_galaxy_install_info(role_name, role_version, options): """ Writes a YAML-formatted file to the role's meta/ directory (named .galaxy_install_info) which contains some information we can use later for commands like 'list' and 'info'. """ info = dict( version = role_version, install_date = datetime.datetime.utcnow().strftime("%c"), ) try: info_path = os.path.join(get_role_path(role_name, options), 'meta/.galaxy_install_info') f = open(info_path, 'w+') info_data = yaml.safe_dump(info, f) f.close() except: return False return True def remove_role(role_name, options): """ Removes the specified role from the roles path. There is a sanity check to make sure there's a meta/main.yml file at this path so the user doesn't blow away random directories """ if get_role_metadata(role_name, options): role_path = get_role_path(role_name, options) shutil.rmtree(role_path) return True else: return False def fetch_role(role_name, target, role_data, options): """ Downloads the archived role from github to a temp location, extracts it, and then copies the extracted role to the role library path. """ # first grab the file and save it to a temp location archive_url = 'https://github.com/%s/%s/archive/%s.tar.gz' % (role_data["github_user"], role_data["github_repo"], target) print " - downloading role from %s" % archive_url try: url_file = urllib2.urlopen(archive_url) temp_file = tempfile.NamedTemporaryFile(delete=False) data = url_file.read() while data: temp_file.write(data) data = url_file.read() temp_file.close() return temp_file.name except Exception, e: # TODO: better urllib2 error handling for error # messages that are more exact print "Error: failed to download the file." return False def install_role(role_name, role_version, role_filename, options): # the file is a tar, so open it that way and extract it # to the specified (or default) roles directory if not tarfile.is_tarfile(role_filename): print "Error: the file downloaded was not a tar.gz" return False else: role_tar_file = tarfile.open(role_filename, "r:gz") # verify the role's meta file meta_file = None members = role_tar_file.getmembers() # next find the metadata file for member in members: if "/meta/main.yml" in member.name: meta_file = member break if not meta_file: print "Error: this role does not appear to have a meta/main.yml file." return False else: try: meta_file_data = yaml.safe_load(role_tar_file.extractfile(meta_file)) except: print "Error: this role does not appear to have a valid meta/main.yml file." return False # we strip off the top-level directory for all of the files contained within # the tar file here, since the default is 'github_repo-target', and change it # to the specified role's name role_path = os.path.join(get_opt(options, 'roles_path', '/etc/ansible/roles'), role_name) role_path = os.path.expanduser(role_path) print " - extracting %s to %s" % (role_name, role_path) try: if os.path.exists(role_path): if not os.path.isdir(role_path): print "Error: the specified roles path exists and is not a directory." return False elif not get_opt(options, "force", False): print "Error: the specified role %s appears to already exist. Use --force to replace it." % role_name return False else: # using --force, remove the old path if not remove_role(role_name, options): print "Error: %s doesn't appear to contain a role." % role_path print "Please remove this directory manually if you really want to put the role here." return False else: os.makedirs(role_path) # now we do the actual extraction to the role_path for member in members: # we only extract files, and remove any relative path # bits that might be in the file for security purposes # and drop the leading directory, as mentioned above if member.isreg(): parts = member.name.split("/")[1:] final_parts = [] for part in parts: if part != '..' and '~' not in part and '$' not in part: final_parts.append(part) member.name = os.path.join(*final_parts) role_tar_file.extract(member, role_path) # write out the install info file for later use write_galaxy_install_info(role_name, role_version, options) except OSError, e: print "Error: you do not have permission to modify files in %s" % role_path return False # return the parsed yaml metadata print "%s was installed successfully" % role_name return meta_file_data #------------------------------------------------------------------------------------- # Action functions #------------------------------------------------------------------------------------- def execute_init(args, options, parser): """ Executes the init action, which creates the skeleton framework of a role that complies with the galaxy metadata format. """ init_path = get_opt(options, 'init_path', './') api_server = get_opt(options, "api_server", "galaxy.ansible.com") force = get_opt(options, 'force', False) api_config = api_get_config(api_server) if not api_config: print "The API server (%s) is not responding, please try again later." % api_server sys.exit(1) try: role_name = args.pop(0).strip() if role_name == "": raise Exception("") role_path = os.path.join(init_path, role_name) if os.path.exists(role_path): if os.path.isfile(role_path): print "The path %s already exists, but is a file - aborting" % role_path sys.exit(1) elif not force: print "The directory %s already exists." % role_path print "" print "You can use --force to re-initialize this directory,\n" + \ "however it will reset any main.yml files that may have\n" + \ "been modified there already." sys.exit(1) except Exception, e: parser.print_help() print "No role name specified for init" sys.exit(1) ROLE_DIRS = ('defaults','files','handlers','meta','tasks','templates','vars') # create the default README.md if not os.path.exists(role_path): os.makedirs(role_path) readme_path = os.path.join(role_path, "README.md") f = open(readme_path, "wb") f.write(default_readme_template) f.close for dir in ROLE_DIRS: dir_path = os.path.join(init_path, role_name, dir) main_yml_path = os.path.join(dir_path, 'main.yml') # create the directory if it doesn't exist already if not os.path.exists(dir_path): os.makedirs(dir_path) # now create the main.yml file for that directory if dir == "meta": # create a skeleton meta/main.yml with a valid galaxy_info # datastructure in place, plus with all of the available # tags/platforms included (but commented out) and the # dependencies section platforms = api_get_list(api_server, "platforms") if not platforms: platforms = [] categories = api_get_list(api_server, "categories") if not categories: categories = [] # group the list of platforms from the api based # on their names, with the release field being # appended to a list of versions platform_groups = defaultdict(list) for platform in platforms: platform_groups[platform['name']].append(platform['release']) platform_groups[platform['name']].sort() inject = dict( author = 'your name', company = 'your company (optional)', license = 'license (GPLv2, CC-BY, etc)', min_ansible_version = '1.2', platforms = platform_groups, categories = categories, ) rendered_meta = Environment().from_string(default_meta_template).render(inject) f = open(main_yml_path, 'w') f.write(rendered_meta) f.close() pass elif dir not in ('files','templates'): # just write a (mostly) empty YAML file for main.yml f = open(main_yml_path, 'w') f.write('---\n# %s file for %s\n' % (dir,role_name)) f.close() print "%s was created successfully" % role_name def execute_info(args, options, parser): """ Executes the info action. This action prints out detailed information about an installed role as well as info available from the galaxy API. """ pass def execute_install(args, options, parser): """ Executes the installation action. The args list contains the roles to be installed, unless -f was specified. The list of roles can be a name (which will be downloaded via the galaxy API and github), or it can be a local .tar.gz file. """ role_file = get_opt(options, "role_file", None) api_server = get_opt(options, "api_server", "galaxy.ansible.com") no_deps = get_opt(options, "no_deps", False) if len(args) == 0 and not role_file: # the user needs to specify one of either --role-file # or specify a single user/role name parser.print_help() print "You must specify a user/role name or a roles file" sys.exit() elif len(args) == 1 and role_file: # using a role file is mutually exclusive of specifying # the role name on the command line parser.print_help() print "Please specify a user/role name, or a roles file, but not both" sys.exit(1) api_config = api_get_config(api_server) if not api_config: print "The API server (%s) is not responding, please try again later." % api_server sys.exit(1) roles_done = [] if role_file: # roles listed in a file, one per line # so we'll go through and grab them all f = open(role_file, 'r') roles_left = f.readlines() f.close() else: # roles were specified directly, so we'll just go out grab them # (and their dependencies, unless the user doesn't want us to). roles_left = args while len(roles_left) > 0: # query the galaxy API for the role data role_name = roles_left.pop(0).strip() role_version = None if role_name == "" or role_name.startswith("#"): continue elif ',' in role_name: role_name,role_version = role_name.split(',',1) role_name = role_name.strip() role_version = role_version.strip() if os.path.isfile(role_name): # installing a local tar.gz tar_file = role_name role_name = os.path.basename(role_name).replace('.tar.gz','') if tarfile.is_tarfile(tar_file): print " - installing %s as %s" % (tar_file, role_name) if not install_role(role_name, role_version, tar_file, options): exit_without_ignore(options) else: print "%s (%s) was NOT installed successfully." % (role_name,tar_file) exit_without_ignore(options) else: # installing remotely role_data = api_lookup_role_by_name(api_server, role_name) if not role_data: print "Sorry, %s was not found on %s." % (role_name, api_server) continue role_versions = api_fetch_role_related(api_server, 'versions', role_data['id']) if not role_version: # convert the version names to LooseVersion objects # and sort them to get the latest version. If there # are no versions in the list, we'll grab the head # of the master branch if len(role_versions) > 0: loose_versions = [LooseVersion(a.get('name',None)) for a in role_versions] loose_versions.sort() role_version = str(loose_versions[-1]) else: role_version = 'master' print " no version specified, installing %s" % role_version else: if role_versions and role_version not in [a.get('name',None) for a in role_versions]: print "The specified version (%s) was not found in the list of available versions." % role_version exit_without_ignore(options) continue # download the role. if --no-deps was specified, we stop here, # otherwise we recursively grab roles and all of their deps. tmp_file = fetch_role(role_name, role_version, role_data, options) if tmp_file and install_role(role_name, role_version, tmp_file, options): # we're done with the temp file, clean it up os.unlink(tmp_file) # install dependencies, if we want them if not no_deps: role_dependencies = role_data['summary_fields']['dependencies'] # api_fetch_role_related(api_server, 'dependencies', role_data['id']) for dep_name in role_dependencies: #dep_name = "%s.%s" % (dep['owner'], dep['name']) if not get_role_metadata(dep_name, options): print ' adding dependency: %s' % dep_name roles_left.append(dep_name) else: print ' dependency %s is already installed, skipping.' % dep_name else: if tmp_file: os.unlink(tmp_file) print "%s was NOT installed successfully." % role_name exit_without_ignore(options) sys.exit(0) def execute_remove(args, options, parser): """ Executes the remove action. The args list contains the list of roles to be removed. This list can contain more than one role. """ if len(args) == 0: parser.print_help() print 'You must specify at least one role to remove.' sys.exit() for role in args: if get_role_metadata(role, options): if remove_role(role, options): print 'successfully removed %s' % role else: print "failed to remove role: %s" % role else: print '%s is not installed, skipping.' % role sys.exit(0) def execute_list(args, options, parser): """ Executes the list action. The args list can contain zero or one role. If one is specified, only that role will be shown, otherwise all roles in the specified directory will be shown. """ if len(args) > 1: print "Please specify only one role to list, or specify no roles to see a full list" sys.exit(1) if len(args) == 1: # show only the request role, if it exists role_name = args[0] metadata = get_role_metadata(role_name, options) if metadata: install_info = get_galaxy_install_info(role_name, options) version = None if install_info: version = install_info.get("version", None) if not version: version = "(unknown version)" # show some more info about single roles here print " %s, %s" % (role_name, version) else: print "The role %s was not found" % role_name else: # show all valid roles in the roles_path directory roles_path = get_opt(options, 'roles_path') roles_path = os.path.expanduser(roles_path) if not os.path.exists(roles_path): parser.print_help() print "The path %s does not exist. Please specify a valid path with --roles-path" % roles_path sys.exit(1) elif not os.path.isdir(roles_path): print "%s exists, but it is not a directory. Please specify a valid path with --roles-path" % roles_path parser.print_help() sys.exit(1) path_files = os.listdir(roles_path) for path_file in path_files: if get_role_metadata(path_file, options): install_info = get_galaxy_install_info(path_file, options) version = None if install_info: version = install_info.get("version", None) if not version: version = "(unknown version)" print " %s, %s" % (path_file, version) sys.exit(0) #------------------------------------------------------------------------------------- # The main entry point #------------------------------------------------------------------------------------- def main(): # parse the CLI options action = get_action(sys.argv) parser = build_option_parser(action) (options, args) = parser.parse_args() # execute the desired action if 1: #try: fn = globals()["execute_%s" % action] fn(args, options, parser) #except KeyError, e: # print "Error: %s is not a valid action. Valid actions are: %s" % (action, ", ".join(VALID_ACTIONS)) # sys.exit(1) if __name__ == "__main__": main() ansible-1.7.2/bin/ansible-playbook000077500000000000000000000301741241061774000170760ustar00rootroot00000000000000#!/usr/bin/env python # (C) 2012, Michael DeHaan, # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . ####################################################### #__requires__ = ['ansible'] #import pkg_resources import sys import os import stat import ansible.playbook import ansible.constants as C import ansible.utils.template from ansible import errors from ansible import callbacks from ansible import utils from ansible.color import ANSIBLE_COLOR, stringc from ansible.callbacks import display def colorize(lead, num, color): """ Print 'lead' = 'num' in 'color' """ if num != 0 and ANSIBLE_COLOR and color is not None: return "%s%s%-15s" % (stringc(lead, color), stringc("=", color), stringc(str(num), color)) else: return "%s=%-4s" % (lead, str(num)) def hostcolor(host, stats, color=True): if ANSIBLE_COLOR and color: if stats['failures'] != 0 or stats['unreachable'] != 0: return "%-37s" % stringc(host, 'red') elif stats['changed'] != 0: return "%-37s" % stringc(host, 'yellow') else: return "%-37s" % stringc(host, 'green') return "%-26s" % host def main(args): ''' run ansible-playbook operations ''' # create parser for CLI options parser = utils.base_parser( constants=C, usage = "%prog playbook.yml", connect_opts=True, runas_opts=True, subset_opts=True, check_opts=True, diff_opts=True ) #parser.add_option('--vault-password', dest="vault_password", # help="password for vault encrypted files") parser.add_option('-e', '--extra-vars', dest="extra_vars", action="append", help="set additional variables as key=value or YAML/JSON", default=[]) parser.add_option('-t', '--tags', dest='tags', default='all', help="only run plays and tasks tagged with these values") parser.add_option('--skip-tags', dest='skip_tags', help="only run plays and tasks whose tags do not match these values") parser.add_option('--syntax-check', dest='syntax', action='store_true', help="perform a syntax check on the playbook, but do not execute it") parser.add_option('--list-tasks', dest='listtasks', action='store_true', help="list all tasks that would be executed") parser.add_option('--step', dest='step', action='store_true', help="one-step-at-a-time: confirm each task before running") parser.add_option('--start-at-task', dest='start_at', help="start the playbook at the task matching this name") parser.add_option('--force-handlers', dest='force_handlers', action='store_true', help="run handlers even if a task fails") options, args = parser.parse_args(args) if len(args) == 0: parser.print_help(file=sys.stderr) return 1 # su and sudo command line arguments need to be mutually exclusive if (options.su or options.su_user or options.ask_su_pass) and \ (options.sudo or options.sudo_user or options.ask_sudo_pass): parser.error("Sudo arguments ('--sudo', '--sudo-user', and '--ask-sudo-pass') " "and su arguments ('-su', '--su-user', and '--ask-su-pass') are " "mutually exclusive") if (options.ask_vault_pass and options.vault_password_file): parser.error("--ask-vault-pass and --vault-password-file are mutually exclusive") sshpass = None sudopass = None su_pass = None vault_pass = None options.ask_vault_pass = options.ask_vault_pass or C.DEFAULT_ASK_VAULT_PASS if options.listhosts or options.syntax or options.listtasks: (_, _, _, vault_pass) = utils.ask_passwords(ask_vault_pass=options.ask_vault_pass) else: options.ask_pass = options.ask_pass or C.DEFAULT_ASK_PASS # Never ask for an SSH password when we run with local connection if options.connection == "local": options.ask_pass = False options.ask_sudo_pass = options.ask_sudo_pass or C.DEFAULT_ASK_SUDO_PASS options.ask_su_pass = options.ask_su_pass or C.DEFAULT_ASK_SU_PASS (sshpass, sudopass, su_pass, vault_pass) = utils.ask_passwords(ask_pass=options.ask_pass, ask_sudo_pass=options.ask_sudo_pass, ask_su_pass=options.ask_su_pass, ask_vault_pass=options.ask_vault_pass) options.sudo_user = options.sudo_user or C.DEFAULT_SUDO_USER options.su_user = options.su_user or C.DEFAULT_SU_USER # read vault_pass from a file if not options.ask_vault_pass and options.vault_password_file: vault_pass = utils.read_vault_file(options.vault_password_file) extra_vars = {} for extra_vars_opt in options.extra_vars: if extra_vars_opt.startswith("@"): # Argument is a YAML file (JSON is a subset of YAML) extra_vars = utils.combine_vars(extra_vars, utils.parse_yaml_from_file(extra_vars_opt[1:], vault_password=vault_pass)) elif extra_vars_opt and extra_vars_opt[0] in '[{': # Arguments as YAML extra_vars = utils.combine_vars(extra_vars, utils.parse_yaml(extra_vars_opt)) else: # Arguments as Key-value extra_vars = utils.combine_vars(extra_vars, utils.parse_kv(extra_vars_opt)) only_tags = options.tags.split(",") skip_tags = options.skip_tags if options.skip_tags is not None: skip_tags = options.skip_tags.split(",") for playbook in args: if not os.path.exists(playbook): raise errors.AnsibleError("the playbook: %s could not be found" % playbook) if not (os.path.isfile(playbook) or stat.S_ISFIFO(os.stat(playbook).st_mode)): raise errors.AnsibleError("the playbook: %s does not appear to be a file" % playbook) inventory = ansible.inventory.Inventory(options.inventory, vault_password=vault_pass) inventory.subset(options.subset) if len(inventory.list_hosts()) == 0: raise errors.AnsibleError("provided hosts list is empty") # run all playbooks specified on the command line for playbook in args: stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) if options.step: playbook_cb.step = options.step if options.start_at: playbook_cb.start_at = options.start_at runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY) pb = ansible.playbook.PlayBook( playbook=playbook, module_path=options.module_path, inventory=inventory, forks=options.forks, remote_user=options.remote_user, remote_pass=sshpass, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, timeout=options.timeout, transport=options.connection, sudo=options.sudo, sudo_user=options.sudo_user, sudo_pass=sudopass, extra_vars=extra_vars, private_key_file=options.private_key_file, only_tags=only_tags, skip_tags=skip_tags, check=options.check, diff=options.diff, su=options.su, su_pass=su_pass, su_user=options.su_user, vault_password=vault_pass, force_handlers=options.force_handlers ) if options.listhosts or options.listtasks or options.syntax: print '' print 'playbook: %s' % playbook print '' playnum = 0 for (play_ds, play_basedir) in zip(pb.playbook, pb.play_basedirs): playnum += 1 play = ansible.playbook.Play(pb, play_ds, play_basedir, vault_password=pb.vault_password) label = play.name hosts = pb.inventory.list_hosts(play.hosts) # Filter all tasks by given tags if pb.only_tags != 'all': if options.subset and not hosts: continue matched_tags, unmatched_tags = play.compare_tags(pb.only_tags) # Remove skipped tasks matched_tags = matched_tags - set(pb.skip_tags) unmatched_tags.discard('all') unknown_tags = ((set(pb.only_tags) | set(pb.skip_tags)) - (matched_tags | unmatched_tags)) if unknown_tags: continue if options.listhosts: print ' play #%d (%s): host count=%d' % (playnum, label, len(hosts)) for host in hosts: print ' %s' % host if options.listtasks: print ' play #%d (%s):' % (playnum, label) for task in play.tasks(): if (set(task.tags).intersection(pb.only_tags) and not set(task.tags).intersection(pb.skip_tags)): if getattr(task, 'name', None) is not None: # meta tasks have no names print ' %s' % task.name print '' continue if options.syntax: # if we've not exited by now then we are fine. print 'Playbook Syntax is fine' return 0 failed_hosts = [] unreachable_hosts = [] try: pb.run() hosts = sorted(pb.stats.processed.keys()) display(callbacks.banner("PLAY RECAP")) playbook_cb.on_stats(pb.stats) for h in hosts: t = pb.stats.summarize(h) if t['failures'] > 0: failed_hosts.append(h) if t['unreachable'] > 0: unreachable_hosts.append(h) retries = failed_hosts + unreachable_hosts if len(retries) > 0: filename = pb.generate_retry_inventory(retries) if filename: display(" to retry, use: --limit @%s\n" % filename) for h in hosts: t = pb.stats.summarize(h) display("%s : %s %s %s %s" % ( hostcolor(h, t), colorize('ok', t['ok'], 'green'), colorize('changed', t['changed'], 'yellow'), colorize('unreachable', t['unreachable'], 'red'), colorize('failed', t['failures'], 'red')), screen_only=True ) display("%s : %s %s %s %s" % ( hostcolor(h, t, False), colorize('ok', t['ok'], None), colorize('changed', t['changed'], None), colorize('unreachable', t['unreachable'], None), colorize('failed', t['failures'], None)), log_only=True ) print "" if len(failed_hosts) > 0: return 2 if len(unreachable_hosts) > 0: return 3 except errors.AnsibleError, e: display("ERROR: %s" % e, color='red') return 1 return 0 if __name__ == "__main__": display(" ", log_only=True) display(" ".join(sys.argv), log_only=True) display(" ", log_only=True) try: sys.exit(main(sys.argv[1:])) except errors.AnsibleError, e: display("ERROR: %s" % e, color='red', stderr=True) sys.exit(1) except KeyboardInterrupt, ke: display("ERROR: interrupted", color='red', stderr=True) sys.exit(1) ansible-1.7.2/bin/ansible-pull000077500000000000000000000210401241061774000162220ustar00rootroot00000000000000#!/usr/bin/env python # (c) 2012, Stephen Fromm # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . # # ansible-pull is a script that runs ansible in local mode # after checking out a playbooks directory from source repo. There is an # example playbook to bootstrap this script in the examples/ dir which # installs ansible and sets it up to run on cron. # usage: # ansible-pull -d /var/lib/ansible \ # -U http://example.net/content.git [-C production] \ # [path/playbook.yml] # # the -d and -U arguments are required; the -C argument is optional. # # ansible-pull accepts an optional argument to specify a playbook # location underneath the workdir and then searches the source repo # for playbooks in the following order, stopping at the first match: # # 1. $workdir/path/playbook.yml, if specified # 2. $workdir/$fqdn.yml # 3. $workdir/$hostname.yml # 4. $workdir/local.yml # # the source repo must contain at least one of these playbooks. import os import shutil import subprocess import sys import datetime import socket import random import time from ansible import utils from ansible.utils import cmd_functions from ansible import errors DEFAULT_REPO_TYPE = 'git' DEFAULT_PLAYBOOK = 'local.yml' PLAYBOOK_ERRORS = {1: 'File does not exist', 2: 'File is not readable'} VERBOSITY=0 def increment_debug(option, opt, value, parser): global VERBOSITY VERBOSITY += 1 def try_playbook(path): if not os.path.exists(path): return 1 if not os.access(path, os.R_OK): return 2 return 0 def select_playbook(path, args): playbook = None if len(args) > 0 and args[0] is not None: playbook = "%s/%s" % (path, args[0]) rc = try_playbook(playbook) if rc != 0: print >>sys.stderr, "%s: %s" % (playbook, PLAYBOOK_ERRORS[rc]) return None return playbook else: fqdn = socket.getfqdn() hostpb = "%s/%s.yml" % (path, fqdn) shorthostpb = "%s/%s.yml" % (path, fqdn.split('.')[0]) localpb = "%s/%s" % (path, DEFAULT_PLAYBOOK) errors = [] for pb in [hostpb, shorthostpb, localpb]: rc = try_playbook(pb) if rc == 0: playbook = pb break else: errors.append("%s: %s" % (pb, PLAYBOOK_ERRORS[rc])) if playbook is None: print >>sys.stderr, "\n".join(errors) return playbook def main(args): """ Set up and run a local playbook """ usage = "%prog [options] [playbook.yml]" parser = utils.SortedOptParser(usage=usage) parser.add_option('--purge', default=False, action='store_true', help='purge checkout after playbook run') parser.add_option('-o', '--only-if-changed', dest='ifchanged', default=False, action='store_true', help='only run the playbook if the repository has been updated') parser.add_option('-s', '--sleep', dest='sleep', default=None, help='sleep for random interval (between 0 and n number of seconds) before starting. this is a useful way to disperse git requests') parser.add_option('-f', '--force', dest='force', default=False, action='store_true', help='run the playbook even if the repository could ' 'not be updated') parser.add_option('-d', '--directory', dest='dest', default=None, help='directory to checkout repository to') #parser.add_option('-l', '--live', default=True, action='store_live', # help='Print the ansible-playbook output while running') parser.add_option('-U', '--url', dest='url', default=None, help='URL of the playbook repository') parser.add_option('-C', '--checkout', dest='checkout', help='branch/tag/commit to checkout. ' 'Defaults to behavior of repository module.') parser.add_option('-i', '--inventory-file', dest='inventory', help="location of the inventory host file") parser.add_option('-e', '--extra-vars', dest="extra_vars", action="append", help="set additional variables as key=value or YAML/JSON", default=[]) parser.add_option('-v', '--verbose', default=False, action="callback", callback=increment_debug, help='Pass -vvvv to ansible-playbook') parser.add_option('-m', '--module-name', dest='module_name', default=DEFAULT_REPO_TYPE, help='Module name used to check out repository. ' 'Default is %s.' % DEFAULT_REPO_TYPE) parser.add_option('--vault-password-file', dest='vault_password_file', help="vault password file") parser.add_option('-K', '--ask-sudo-pass', default=False, dest='ask_sudo_pass', action='store_true', help='ask for sudo password') options, args = parser.parse_args(args) hostname = socket.getfqdn() if not options.dest: # use a hostname dependent directory, in case of $HOME on nfs options.dest = utils.prepare_writeable_dir('~/.ansible/pull/%s' % hostname) options.dest = os.path.abspath(options.dest) if not options.url: parser.error("URL for repository not specified, use -h for help") return 1 now = datetime.datetime.now() print >>sys.stderr, now.strftime("Starting ansible-pull at %F %T") if not options.inventory: inv_opts = 'localhost,' else: inv_opts = options.inventory limit_opts = 'localhost:%s:127.0.0.1' % hostname repo_opts = "name=%s dest=%s" % (options.url, options.dest) if VERBOSITY == 0: base_opts = '-c local --limit "%s"' % limit_opts elif VERBOSITY > 0: debug_level = ''.join([ "v" for x in range(0, VERBOSITY) ]) base_opts = '-%s -c local --limit "%s"' % (debug_level, limit_opts) if options.checkout: repo_opts += ' version=%s' % options.checkout path = utils.plugins.module_finder.find_plugin(options.module_name) if path is None: sys.stderr.write("module '%s' not found.\n" % options.module_name) return 1 cmd = 'ansible all -i "%s" %s -m %s -a "%s"' % ( inv_opts, base_opts, options.module_name, repo_opts ) if options.sleep: try: secs = random.randint(0,int(options.sleep)); except ValueError: parser.error("%s is not a number." % options.sleep) return 1 print >>sys.stderr, "Sleeping for %d seconds..." % secs time.sleep(secs); # RUN THe CHECKOUT COMMAND rc, out, err = cmd_functions.run_cmd(cmd, live=True) if rc != 0: if options.force: print "Unable to update repository. Continuing with (forced) run of playbook." else: return rc elif options.ifchanged and '"changed": true' not in out: print "Repository has not changed, quitting." return 0 playbook = select_playbook(options.dest, args) if playbook is None: print >>sys.stderr, "Could not find a playbook to run." return 1 cmd = 'ansible-playbook %s %s' % (base_opts, playbook) if options.vault_password_file: cmd += " --vault-password-file=%s" % options.vault_password_file if options.inventory: cmd += ' -i "%s"' % options.inventory for ev in options.extra_vars: cmd += ' -e "%s"' % ev if options.ask_sudo_pass: cmd += ' -K' os.chdir(options.dest) # RUN THE PLAYBOOK COMMAND rc, out, err = cmd_functions.run_cmd(cmd, live=True) if options.purge: os.chdir('/') try: shutil.rmtree(options.dest) except Exception, e: print >>sys.stderr, "Failed to remove %s: %s" % (options.dest, str(e)) return rc if __name__ == '__main__': try: sys.exit(main(sys.argv[1:])) except KeyboardInterrupt, e: print >>sys.stderr, "Exit on user request.\n" sys.exit(1) ansible-1.7.2/bin/ansible-vault000077500000000000000000000155001241061774000164050ustar00rootroot00000000000000#!/usr/bin/env python # (c) 2014, James Tanner # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . # # ansible-pull is a script that runs ansible in local mode # after checking out a playbooks directory from source repo. There is an # example playbook to bootstrap this script in the examples/ dir which # installs ansible and sets it up to run on cron. #__requires__ = ['ansible'] #import pkg_resources import os import sys import traceback import ansible.constants as C from ansible import utils from ansible import errors from ansible.utils.vault import VaultEditor from optparse import OptionParser #------------------------------------------------------------------------------------- # Utility functions for parsing actions/options #------------------------------------------------------------------------------------- VALID_ACTIONS = ("create", "decrypt", "edit", "encrypt", "rekey") def build_option_parser(action): """ Builds an option parser object based on the action the user wants to execute. """ usage = "usage: %%prog [%s] [--help] [options] file_name" % "|".join(VALID_ACTIONS) epilog = "\nSee '%s --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0]) OptionParser.format_epilog = lambda self, formatter: self.epilog parser = OptionParser(usage=usage, epilog=epilog) if not action: parser.print_help() sys.exit() # options for all actions #parser.add_option('-c', '--cipher', dest='cipher', default="AES256", help="cipher to use") parser.add_option('--debug', dest='debug', action="store_true", help="debug") parser.add_option('--vault-password-file', dest='password_file', help="vault password file", default=C.DEFAULT_VAULT_PASSWORD_FILE) # options specific to actions if action == "create": parser.set_usage("usage: %prog create [options] file_name") elif action == "decrypt": parser.set_usage("usage: %prog decrypt [options] file_name") elif action == "edit": parser.set_usage("usage: %prog edit [options] file_name") elif action == "encrypt": parser.set_usage("usage: %prog encrypt [options] file_name") elif action == "rekey": parser.set_usage("usage: %prog rekey [options] file_name") # done, return the parser return parser def get_action(args): """ Get the action the user wants to execute from the sys argv list. """ for i in range(0,len(args)): arg = args[i] if arg in VALID_ACTIONS: del args[i] return arg return None def get_opt(options, k, defval=""): """ Returns an option from an Optparse values instance. """ try: data = getattr(options, k) except: return defval if k == "roles_path": if os.pathsep in data: data = data.split(os.pathsep)[0] return data #------------------------------------------------------------------------------------- # Command functions #------------------------------------------------------------------------------------- def execute_create(args, options, parser): if len(args) > 1: raise errors.AnsibleError("'create' does not accept more than one filename") if not options.password_file: password, new_password = utils.ask_vault_passwords(ask_vault_pass=True, confirm_vault=True) else: password = utils.read_vault_file(options.password_file) cipher = 'AES256' if hasattr(options, 'cipher'): cipher = options.cipher this_editor = VaultEditor(cipher, password, args[0]) this_editor.create_file() def execute_decrypt(args, options, parser): if not options.password_file: password, new_password = utils.ask_vault_passwords(ask_vault_pass=True) else: password = utils.read_vault_file(options.password_file) cipher = 'AES256' if hasattr(options, 'cipher'): cipher = options.cipher for f in args: this_editor = VaultEditor(cipher, password, f) this_editor.decrypt_file() print "Decryption successful" def execute_edit(args, options, parser): if len(args) > 1: raise errors.AnsibleError("create does not accept more than one filename") if not options.password_file: password, new_password = utils.ask_vault_passwords(ask_vault_pass=True) else: password = utils.read_vault_file(options.password_file) cipher = None for f in args: this_editor = VaultEditor(cipher, password, f) this_editor.edit_file() def execute_encrypt(args, options, parser): if not options.password_file: password, new_password = utils.ask_vault_passwords(ask_vault_pass=True, confirm_vault=True) else: password = utils.read_vault_file(options.password_file) cipher = 'AES256' if hasattr(options, 'cipher'): cipher = options.cipher for f in args: this_editor = VaultEditor(cipher, password, f) this_editor.encrypt_file() print "Encryption successful" def execute_rekey(args, options, parser): if not options.password_file: password, __ = utils.ask_vault_passwords(ask_vault_pass=True) else: password = utils.read_vault_file(options.password_file) __, new_password = utils.ask_vault_passwords(ask_vault_pass=False, ask_new_vault_pass=True, confirm_new=True) cipher = None for f in args: this_editor = VaultEditor(cipher, password, f) this_editor.rekey_file(new_password) print "Rekey successful" #------------------------------------------------------------------------------------- # MAIN #------------------------------------------------------------------------------------- def main(): action = get_action(sys.argv) parser = build_option_parser(action) (options, args) = parser.parse_args() if not len(args): raise errors.AnsibleError( "The '%s' command requires a filename as the first argument" % action ) # execute the desired action try: fn = globals()["execute_%s" % action] fn(args, options, parser) except Exception, err: if options.debug: print traceback.format_exc() print "ERROR:",err sys.exit(1) if __name__ == "__main__": main() ansible-1.7.2/docs/000077500000000000000000000000001241061774000140705ustar00rootroot00000000000000ansible-1.7.2/docs/man/000077500000000000000000000000001241061774000146435ustar00rootroot00000000000000ansible-1.7.2/docs/man/.gitignore000066400000000000000000000000211241061774000166240ustar00rootroot00000000000000*.xml *.asciidoc ansible-1.7.2/docs/man/man1/000077500000000000000000000000001241061774000154775ustar00rootroot00000000000000ansible-1.7.2/docs/man/man1/ansible-doc.1000066400000000000000000000052551241061774000177500ustar00rootroot00000000000000'\" t .\" Title: ansible-doc .\" Author: :doctype:manpage .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 05/26/2014 .\" Manual: System administration commands .\" Source: Ansible 1.7 .\" Language: English .\" .TH "ANSIBLE\-DOC" "1" "05/26/2014" "Ansible 1\&.7" "System administration commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ansible-doc \- show documentation on Ansible modules .SH "SYNOPSIS" .sp ansible\-doc [\-M module_path] [\-l] [\-s] [module\&...] .SH "DESCRIPTION" .sp \fBansible\-doc\fR displays information on modules installed in Ansible libraries\&. It displays a terse listing of modules and their short descriptions, provides a printout of their DOCUMENTATION strings, and it can create a short "snippet" which can be pasted into a playbook\&. .SH "OPTIONS" .PP \fB\-M\fR \fIdirectory\fR, \fB\-\-module\-path=\fR\fIdirectory\fR .RS 4 Add an additional directory to the default path for finding module libraries\&. .RE .PP \fB\-s\fR, \fB\-\-snippet=\fR .RS 4 Produce a snippet which can be copied into a playbook for modification, like a kind of task template\&. .RE .PP \fB\-l\fR, \fB\-\-list=\fR .RS 4 Produce a terse listing of modules and a short description of each\&. .RE .SH "AUTHOR" .sp ansible\-doc was originally written by Jan\-Piet Mens\&. See the AUTHORS file for a complete list of contributors\&. .SH "COPYRIGHT" .sp Copyright \(co 2012, Jan\-Piet Mens .sp Ansible is released under the terms of the GPLv3 License\&. .SH "SEE ALSO" .sp \fBansible\-playbook\fR(1), \fBansible\fR(1), \fBansible\-pull\fR(1) .sp Extensive documentation is available in the documentation site: http://docs\&.ansible\&.com\&. IRC and mailing list info can be found in file CONTRIBUTING\&.md, available in: https://github\&.com/ansible/ansible .SH "AUTHOR" .PP \fB:doctype:manpage\fR .RS 4 Author. .RE ansible-1.7.2/docs/man/man1/ansible-doc.1.asciidoc.in000066400000000000000000000026621241061774000221310ustar00rootroot00000000000000ansible-doc(1) ============== :doctype:manpage :man source: Ansible :man version: %VERSION% :man manual: System administration commands NAME ---- ansible-doc - show documentation on Ansible modules SYNOPSIS -------- ansible-doc [-M module_path] [-l] [-s] [module...] DESCRIPTION ----------- *ansible-doc* displays information on modules installed in Ansible libraries. It displays a terse listing of modules and their short descriptions, provides a printout of their DOCUMENTATION strings, and it can create a short "snippet" which can be pasted into a playbook. OPTIONS ------- *-M* 'directory', *--module-path=*'directory':: Add an additional directory to the default path for finding module libraries. *-s*, *--snippet=*:: Produce a snippet which can be copied into a playbook for modification, like a kind of task template. *-l*, *--list=*:: Produce a terse listing of modules and a short description of each. AUTHOR ------ ansible-doc was originally written by Jan-Piet Mens. See the AUTHORS file for a complete list of contributors. COPYRIGHT --------- Copyright © 2012, Jan-Piet Mens Ansible is released under the terms of the GPLv3 License. SEE ALSO -------- *ansible-playbook*(1), *ansible*(1), *ansible-pull*(1) Extensive documentation is available in the documentation site: . IRC and mailing list info can be found in file CONTRIBUTING.md, available in: ansible-1.7.2/docs/man/man1/ansible-galaxy.1000066400000000000000000000130771241061774000204710ustar00rootroot00000000000000'\" t .\" Title: ansible-galaxy .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 05/26/2014 .\" Manual: System administration commands .\" Source: Ansible 1.7 .\" Language: English .\" .TH "ANSIBLE\-GALAXY" "1" "05/26/2014" "Ansible 1\&.7" "System administration commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ansible-galaxy \- manage roles using galaxy\&.ansible\&.com .SH "SYNOPSIS" .sp ansible\-galaxy [init|info|install|list|remove] [\-\-help] [options] \&... .SH "DESCRIPTION" .sp \fBAnsible Galaxy\fR is a shared repository for Ansible roles (added in ansible version 1\&.2)\&. The ansible\-galaxy command can be used to manage these roles, or by creating a skeleton framework for roles you\(cqd like to upload to Galaxy\&. .SH "COMMON OPTIONS" .PP \fB\-h\fR, \fB\-\-help\fR .RS 4 Show a help message related to the given sub\-command\&. .RE .SH "INSTALL" .sp The \fBinstall\fR sub\-command is used to install roles\&. .SS "USAGE" .sp $ ansible\-galaxy install [options] [\-r FILE | role_name(s)[,version] | tar_file(s)] .sp Roles can be installed in several different ways: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} A username\&.rolename[,version] \- this will install a single role\&. The Galaxy API will be contacted to provide the information about the role, and the corresponding \&.tar\&.gz will be downloaded from \fBgithub\&.com\fR\&. If the version is omitted, the most recent version available will be installed\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} A file name, using \fB\-r\fR \- this will install multiple roles listed one per line\&. The format of each line is the same as above: username\&.rolename[,version] .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} A \&.tar\&.gz of a valid role you\(cqve downloaded directly from \fBgithub\&.com\fR\&. This is mainly useful when the system running Ansible does not have access to the Galaxy API, for instance when behind a firewall or proxy\&. .RE .SS "OPTIONS" .PP \fB\-f\fR, \fB\-\-force\fR .RS 4 Force overwriting an existing role\&. .RE .PP \fB\-i\fR, \fB\-\-ignore\-errors\fR .RS 4 Ignore errors and continue with the next specified role\&. .RE .PP \fB\-n\fR, \fB\-\-no\-deps\fR .RS 4 Don\(cqt download roles listed as dependencies\&. .RE .PP \fB\-p\fR \fIROLES_PATH\fR, \fB\-\-roles\-path=\fR\fIROLES_PATH\fR .RS 4 The path to the directory containing your roles\&. The default is the \fBroles_path\fR configured in your \fBansible\&.cfg\fR file (/etc/ansible/roles if not configured) .RE .PP \fB\-r\fR \fIROLE_FILE\fR, \fB\-\-role\-file=\fR\fIROLE_FILE\fR .RS 4 A file containing a list of roles to be imported, as specified above\&. This option cannot be used if a rolename or \&.tar\&.gz have been specified\&. .RE .SH "REMOVE" .sp The \fBremove\fR sub\-command is used to remove one or more roles\&. .SS "USAGE" .sp $ ansible\-galaxy remove role1 role2 \&... .SS "OPTIONS" .PP \fB\-p\fR \fIROLES_PATH\fR, \fB\-\-roles\-path=\fR\fIROLES_PATH\fR .RS 4 The path to the directory containing your roles\&. The default is the \fBroles_path\fR configured in your \fBansible\&.cfg\fR file (/etc/ansible/roles if not configured) .RE .SH "INIT" .sp The \fBinit\fR command is used to create an empty role suitable for uploading to https://galaxy\&.ansible\&.com (or for roles in general)\&. .SS "USAGE" .sp $ ansible\-galaxy init [options] role_name .SS "OPTIONS" .PP \fB\-f\fR, \fB\-\-force\fR .RS 4 Force overwriting an existing role\&. .RE .PP \fB\-p\fR \fIINIT_PATH\fR, \fB\-\-init\-path=\fR\fIINIT_PATH\fR .RS 4 The path in which the skeleton role will be created\&.The default is the current working directory\&. .RE .SH "LIST" .sp The \fBlist\fR sub\-command is used to show what roles are currently instaled\&. You can specify a role name, and if installed only that role will be shown\&. .SS "USAGE" .sp $ ansible\-galaxy list [role_name] .SS "OPTIONS" .PP \fB\-p\fR \fIROLES_PATH\fR, \fB\-\-roles\-path=\fR\fIROLES_PATH\fR .RS 4 The path to the directory containing your roles\&. The default is the \fBroles_path\fR configured in your \fBansible\&.cfg\fR file (/etc/ansible/roles if not configured) .RE .SH "AUTHOR" .sp Ansible was originally written by Michael DeHaan\&. See the AUTHORS file for a complete list of contributors\&. .SH "COPYRIGHT" .sp Copyright \(co 2014, Michael DeHaan .sp Ansible is released under the terms of the GPLv3 License\&. .SH "SEE ALSO" .sp \fBansible\fR(1), \fBansible\-pull\fR(1), \fBansible\-doc\fR(1) .sp Extensive documentation is available in the documentation site: http://docs\&.ansible\&.com\&. IRC and mailing list info can be found in file CONTRIBUTING\&.md, available in: https://github\&.com/ansible/ansible ansible-1.7.2/docs/man/man1/ansible-galaxy.1.asciidoc.in000066400000000000000000000075341241061774000226540ustar00rootroot00000000000000ansible-galaxy(1) =================== :doctype: manpage :man source: Ansible :man version: %VERSION% :man manual: System administration commands NAME ---- ansible-galaxy - manage roles using galaxy.ansible.com SYNOPSIS -------- ansible-galaxy [init|info|install|list|remove] [--help] [options] ... DESCRIPTION ----------- *Ansible Galaxy* is a shared repository for Ansible roles (added in ansible version 1.2). The ansible-galaxy command can be used to manage these roles, or by creating a skeleton framework for roles you'd like to upload to Galaxy. COMMON OPTIONS -------------- *-h*, *--help*:: Show a help message related to the given sub-command. INSTALL ------- The *install* sub-command is used to install roles. USAGE ~~~~~ $ ansible-galaxy install [options] [-r FILE | role_name(s)[,version] | tar_file(s)] Roles can be installed in several different ways: * A username.rolename[,version] - this will install a single role. The Galaxy API will be contacted to provide the information about the role, and the corresponding .tar.gz will be downloaded from *github.com*. If the version is omitted, the most recent version available will be installed. * A file name, using *-r* - this will install multiple roles listed one per line. The format of each line is the same as above: username.rolename[,version] * A .tar.gz of a valid role you've downloaded directly from *github.com*. This is mainly useful when the system running Ansible does not have access to the Galaxy API, for instance when behind a firewall or proxy. OPTIONS ~~~~~~~ *-f*, *--force*:: Force overwriting an existing role. *-i*, *--ignore-errors*:: Ignore errors and continue with the next specified role. *-n*, *--no-deps*:: Don't download roles listed as dependencies. *-p* 'ROLES_PATH', *--roles-path=*'ROLES_PATH':: The path to the directory containing your roles. The default is the *roles_path* configured in your *ansible.cfg* file (/etc/ansible/roles if not configured) *-r* 'ROLE_FILE', *--role-file=*'ROLE_FILE':: A file containing a list of roles to be imported, as specified above. This option cannot be used if a rolename or .tar.gz have been specified. REMOVE ------ The *remove* sub-command is used to remove one or more roles. USAGE ~~~~~ $ ansible-galaxy remove role1 role2 ... OPTIONS ~~~~~~~ *-p* 'ROLES_PATH', *--roles-path=*'ROLES_PATH':: The path to the directory containing your roles. The default is the *roles_path* configured in your *ansible.cfg* file (/etc/ansible/roles if not configured) INIT ---- The *init* command is used to create an empty role suitable for uploading to https://galaxy.ansible.com (or for roles in general). USAGE ~~~~~ $ ansible-galaxy init [options] role_name OPTIONS ~~~~~~~ *-f*, *--force*:: Force overwriting an existing role. *-p* 'INIT_PATH', *--init-path=*'INIT_PATH':: The path in which the skeleton role will be created.The default is the current working directory. LIST ---- The *list* sub-command is used to show what roles are currently instaled. You can specify a role name, and if installed only that role will be shown. USAGE ~~~~~ $ ansible-galaxy list [role_name] OPTIONS ~~~~~~~ *-p* 'ROLES_PATH', *--roles-path=*'ROLES_PATH':: The path to the directory containing your roles. The default is the *roles_path* configured in your *ansible.cfg* file (/etc/ansible/roles if not configured) AUTHOR ------ Ansible was originally written by Michael DeHaan. See the AUTHORS file for a complete list of contributors. COPYRIGHT --------- Copyright © 2014, Michael DeHaan Ansible is released under the terms of the GPLv3 License. SEE ALSO -------- *ansible*(1), *ansible-pull*(1), *ansible-doc*(1) Extensive documentation is available in the documentation site: . IRC and mailing list info can be found in file CONTRIBUTING.md, available in: ansible-1.7.2/docs/man/man1/ansible-playbook.1000066400000000000000000000127411241061774000210210ustar00rootroot00000000000000'\" t .\" Title: ansible-playbook .\" Author: :doctype:manpage .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 05/26/2014 .\" Manual: System administration commands .\" Source: Ansible 1.7 .\" Language: English .\" .TH "ANSIBLE\-PLAYBOOK" "1" "05/26/2014" "Ansible 1\&.7" "System administration commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ansible-playbook \- run an ansible playbook .SH "SYNOPSIS" .sp ansible\-playbook \&... [options] .SH "DESCRIPTION" .sp \fBAnsible playbooks\fR are a configuration and multinode deployment system\&. Ansible\-playbook is the tool used to run them\&. See the project home page (link below) for more information\&. .SH "ARGUMENTS" .PP \fBfilename\&.yml\fR .RS 4 The names of one or more YAML format files to run as ansible playbooks\&. .RE .SH "OPTIONS" .PP \fB\-v\fR, \fB\-\-verbose\fR .RS 4 Verbose mode, more output from successful actions will be shown\&. Give up to three times for more output\&. .RE .PP \fB\-i\fR \fIPATH\fR, \fB\-\-inventory=\fR\fIPATH\fR .RS 4 The \fIPATH\fR to the inventory hosts file, which defaults to \fI/etc/ansible/hosts\fR\&. .RE .PP \fB\-M\fR \fIDIRECTORY\fR, \fB\-\-module\-path=\fR\fIDIRECTORY\fR .RS 4 The \fIDIRECTORY\fR search path to load modules from\&. The default is \fI/usr/share/ansible\fR\&. This can also be set with the ANSIBLE_LIBRARY environment variable\&. .RE .PP \fB\-e\fR \fIVARS\fR, \fB\-\-extra\-vars=\fR\fIVARS\fR .RS 4 Extra variables to inject into a playbook, in key=value key=value format or as quoted JSON (hashes and arrays)\&. .RE .PP \fB\-f\fR \fINUM\fR, \fB\-\-forks=\fR\fINUM\fR .RS 4 Level of parallelism\&. \fINUM\fR is specified as an integer, the default is 5\&. .RE .PP \fB\-k\fR, \fB\-\-ask\-pass\fR .RS 4 Prompt for the SSH password instead of assuming key\-based authentication with ssh\-agent\&. .RE .PP \fB\-K\fR, \fB\-\-ask\-sudo\-pass\fR .RS 4 Prompt for the password to use for playbook plays that request sudo access, if any\&. .RE .PP \fB\-U\fR, \fISUDO_USER\fR, \fB\-\-sudo\-user=\fR\fISUDO_USER\fR .RS 4 Desired sudo user (default=root)\&. .RE .PP \fB\-t\fR, \fITAGS\fR, \fB\-\-tags=\fR\fITAGS\fR .RS 4 Only run plays and tasks tagged with these values\&. .RE .PP \fB\-\-skip\-tags=\fR\fISKIP_TAGS\fR .RS 4 Only run plays and tasks whose tags do not match these values\&. .RE .PP \fB\-\-syntax\-check\fR .RS 4 Look for syntax errors in the playbook, but don\(cqt run anything .RE .PP \fB\-\-check\fR .RS 4 Do not make any changes on the remote system, but test resources to see what might have changed\&. Note this can not scan all possible resource types and is only a simulation\&. .RE .PP \fB\-\-diff\fR .RS 4 When changing any templated files, show the unified diffs of how they changed\&. When used with \-\-check, shows how the files would have changed if \-\-check were not used\&. .RE .PP \fB\-T\fR \fISECONDS\fR, \fB\-\-timeout=\fR\fISECONDS\fR .RS 4 Connection timeout to use when trying to talk to hosts, in \fISECONDS\fR\&. .RE .PP \fB\-s\fR, \fB\-\-sudo\fR .RS 4 Force all plays to use sudo, even if not marked as such\&. .RE .PP \fB\-u\fR \fIUSERNAME\fR, \fB\-\-user=\fR\fIUSERNAME\fR .RS 4 Use this remote user name on playbook steps that do not indicate a user name to run as\&. .RE .PP \fB\-c\fR \fICONNECTION\fR, \fB\-\-connection=\fR\fICONNECTION\fR .RS 4 Connection type to use\&. Possible options are \fIparamiko\fR (SSH), \fIssh\fR, and \fIlocal\fR\&. \fIlocal\fR is mostly useful for crontab or kickstarts\&. .RE .PP \fB\-l\fR \fISUBSET\fR, \fB\-\-limit=\fR\fISUBSET\fR .RS 4 Further limits the selected host/group patterns\&. .RE .SH "ENVIRONMENT" .sp The following environment variables may be specified\&. .sp ANSIBLE_HOSTS \(em Override the default ansible hosts file .sp ANSIBLE_LIBRARY \(em Override the default ansible module library path .SH "FILES" .sp /etc/ansible/hosts \(em Default inventory file .sp /usr/share/ansible/ \(em Default module library .sp /etc/ansible/ansible\&.cfg \(em Config file, used if present .sp ~/\&.ansible\&.cfg \(em User config file, overrides the default config if present .SH "AUTHOR" .sp Ansible was originally written by Michael DeHaan\&. See the AUTHORS file for a complete list of contributors\&. .SH "COPYRIGHT" .sp Copyright \(co 2012, Michael DeHaan .sp Ansible is released under the terms of the GPLv3 License\&. .SH "SEE ALSO" .sp \fBansible\fR(1), \fBansible\-pull\fR(1), \fBansible\-doc\fR(1) .sp Extensive documentation is available in the documentation site: http://docs\&.ansible\&.com\&. IRC and mailing list info can be found in file CONTRIBUTING\&.md, available in: https://github\&.com/ansible/ansible .SH "AUTHOR" .PP \fB:doctype:manpage\fR .RS 4 Author. .RE ansible-1.7.2/docs/man/man1/ansible-playbook.1.asciidoc.in000066400000000000000000000073601241061774000232040ustar00rootroot00000000000000ansible-playbook(1) =================== :doctype:manpage :man source: Ansible :man version: %VERSION% :man manual: System administration commands NAME ---- ansible-playbook - run an ansible playbook SYNOPSIS -------- ansible-playbook ... [options] DESCRIPTION ----------- *Ansible playbooks* are a configuration and multinode deployment system. Ansible-playbook is the tool used to run them. See the project home page (link below) for more information. ARGUMENTS --------- *filename.yml*:: The names of one or more YAML format files to run as ansible playbooks. OPTIONS ------- *-v*, *--verbose*:: Verbose mode, more output from successful actions will be shown. Give up to three times for more output. *-i* 'PATH', *--inventory=*'PATH':: The 'PATH' to the inventory hosts file, which defaults to '/etc/ansible/hosts'. *-M* 'DIRECTORY', *--module-path=*'DIRECTORY':: The 'DIRECTORY' search path to load modules from. The default is '/usr/share/ansible'. This can also be set with the ANSIBLE_LIBRARY environment variable. *-e* 'VARS', *--extra-vars=*'VARS':: Extra variables to inject into a playbook, in key=value key=value format or as quoted JSON (hashes and arrays). *-f* 'NUM', *--forks=*'NUM':: Level of parallelism. 'NUM' is specified as an integer, the default is 5. *-k*, *--ask-pass*:: Prompt for the SSH password instead of assuming key-based authentication with ssh-agent. *-K*, *--ask-sudo-pass*:: Prompt for the password to use for playbook plays that request sudo access, if any. *-U*, 'SUDO_USER', *--sudo-user=*'SUDO_USER':: Desired sudo user (default=root). *-t*, 'TAGS', *--tags=*'TAGS':: Only run plays and tasks tagged with these values. *--skip-tags=*'SKIP_TAGS':: Only run plays and tasks whose tags do not match these values. *--syntax-check*:: Look for syntax errors in the playbook, but don't run anything *--check*:: Do not make any changes on the remote system, but test resources to see what might have changed. Note this can not scan all possible resource types and is only a simulation. *--diff*:: When changing any templated files, show the unified diffs of how they changed. When used with --check, shows how the files would have changed if --check were not used. *-T* 'SECONDS', *--timeout=*'SECONDS':: Connection timeout to use when trying to talk to hosts, in 'SECONDS'. *-s*, *--sudo*:: Force all plays to use sudo, even if not marked as such. *-u* 'USERNAME', *--user=*'USERNAME':: Use this remote user name on playbook steps that do not indicate a user name to run as. *-c* 'CONNECTION', *--connection=*'CONNECTION':: Connection type to use. Possible options are 'paramiko' (SSH), 'ssh', and 'local'. 'local' is mostly useful for crontab or kickstarts. *-l* 'SUBSET', *--limit=*'SUBSET':: Further limits the selected host/group patterns. ENVIRONMENT ----------- The following environment variables may be specified. ANSIBLE_HOSTS -- Override the default ansible hosts file ANSIBLE_LIBRARY -- Override the default ansible module library path FILES ----- /etc/ansible/hosts -- Default inventory file /usr/share/ansible/ -- Default module library /etc/ansible/ansible.cfg -- Config file, used if present ~/.ansible.cfg -- User config file, overrides the default config if present AUTHOR ------ Ansible was originally written by Michael DeHaan. See the AUTHORS file for a complete list of contributors. COPYRIGHT --------- Copyright © 2012, Michael DeHaan Ansible is released under the terms of the GPLv3 License. SEE ALSO -------- *ansible*(1), *ansible-pull*(1), *ansible-doc*(1) Extensive documentation is available in the documentation site: . IRC and mailing list info can be found in file CONTRIBUTING.md, available in: ansible-1.7.2/docs/man/man1/ansible-pull.1000066400000000000000000000103731241061774000201540ustar00rootroot00000000000000'\" t .\" Title: ansible .\" Author: :doctype:manpage .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 05/26/2014 .\" Manual: System administration commands .\" Source: Ansible 1.7 .\" Language: English .\" .TH "ANSIBLE" "1" "05/26/2014" "Ansible 1\&.7" "System administration commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ansible-pull \- set up a remote copy of ansible on each managed node .SH "SYNOPSIS" .sp ansible \-d DEST \-U URL [options] [ ] .SH "DESCRIPTION" .sp \fBAnsible\fR is an extra\-simple tool/framework/API for doing \*(Aqremote things\*(Aq over SSH\&. .sp Use ansible\-pull to set up a remote copy of ansible on each managed node, each set to run via cron and update playbook source via a source repository\&. This inverts the default \fBpush\fR architecture of ansible into a \fBpull\fR architecture, which has near\-limitless scaling potential\&. .sp The setup playbook can be tuned to change the cron frequency, logging locations, and parameters to ansible\-pull\&. .sp This is useful both for extreme scale\-out as well as periodic remediation\&. Usage of the \fIfetch\fR module to retrieve logs from ansible\-pull runs would be an excellent way to gather and analyze remote logs from ansible\-pull\&. .SH "OPTIONAL ARGUMENT" .PP \fBfilename\&.yml\fR .RS 4 The name of one the YAML format files to run as an ansible playbook\&. This can be a relative path within the checkout\&. If not provided, ansible\-pull will look for a playbook based on the host\(cqs fully\-qualified domain name, on the host hostname and finally a playbook named \fBlocal\&.yml\fR\&. .RE .SH "OPTIONS" .PP \fB\-d\fR \fIDEST\fR, \fB\-\-directory=\fR\fIDEST\fR .RS 4 Directory to checkout repository into\&. If not provided, a subdirectory of ~/\&.ansible/pull/ will be used\&. .RE .PP \fB\-U\fR \fIURL\fR, \fB\-\-url=\fR\fIURL\fR .RS 4 URL of the playbook repository to checkout\&. .RE .PP \fB\-C\fR \fICHECKOUT\fR, \fB\-\-checkout=\fR\fICHECKOUT\fR .RS 4 Branch/Tag/Commit to checkout\&. If not provided, uses default behavior of module used to check out playbook repository\&. .RE .PP \fB\-f\fR, \fB\-\-force\fR .RS 4 Force running of playbook even if unable to update playbook repository\&. This can be useful, for example, to enforce run\-time state when a network connection may not always be up or possible\&. .RE .PP \fB\-i\fR \fIPATH\fR, \fB\-\-inventory=\fR\fIPATH\fR .RS 4 The \fIPATH\fR to the inventory hosts file\&. This can be a relative path within the checkout\&. .RE .PP \fB\-\-purge\fR .RS 4 Purge the checkout after the playbook is run\&. .RE .PP \fB\-m\fR \fINAME\fR, \fB\-\-module\-name=\fR\fINAME\fR .RS 4 Module used to checkout playbook repository\&. Defaults to git\&. .RE .PP \fB\-o\fR, \fB\-\-only\-if\-changed\fR .RS 4 Run the playbook only if the repository has changed .RE .SH "AUTHOR" .sp Ansible was originally written by Michael DeHaan\&. See the AUTHORS file for a complete list of contributors\&. .SH "COPYRIGHT" .sp Copyright \(co 2012, Michael DeHaan .sp Ansible is released under the terms of the GPLv3 License\&. .SH "SEE ALSO" .sp \fBansible\fR(1), \fBansible\-playbook\fR(1), \fBansible\-doc\fR(1) .sp Extensive documentation is available in the documentation site: http://docs\&.ansible\&.com\&. IRC and mailing list info can be found in file CONTRIBUTING\&.md, available in: https://github\&.com/ansible/ansible .SH "AUTHOR" .PP \fB:doctype:manpage\fR .RS 4 Author. .RE ansible-1.7.2/docs/man/man1/ansible-pull.1.asciidoc.in000066400000000000000000000054571241061774000223450ustar00rootroot00000000000000ansible(1) ========= :doctype:manpage :man source: Ansible :man version: %VERSION% :man manual: System administration commands NAME ---- ansible-pull - set up a remote copy of ansible on each managed node SYNOPSIS -------- ansible -d DEST -U URL [options] [ ] DESCRIPTION ----------- *Ansible* is an extra-simple tool/framework/API for doing \'remote things' over SSH. Use ansible-pull to set up a remote copy of ansible on each managed node, each set to run via cron and update playbook source via a source repository. This inverts the default *push* architecture of ansible into a *pull* architecture, which has near-limitless scaling potential. The setup playbook can be tuned to change the cron frequency, logging locations, and parameters to ansible-pull. This is useful both for extreme scale-out as well as periodic remediation. Usage of the 'fetch' module to retrieve logs from ansible-pull runs would be an excellent way to gather and analyze remote logs from ansible-pull. OPTIONAL ARGUMENT ----------------- *filename.yml*:: The name of one the YAML format files to run as an ansible playbook. This can be a relative path within the checkout. If not provided, ansible-pull will look for a playbook based on the host's fully-qualified domain name, on the host hostname and finally a playbook named *local.yml*. OPTIONS ------- *-d* 'DEST', *--directory=*'DEST':: Directory to checkout repository into. If not provided, a subdirectory of ~/.ansible/pull/ will be used. *-U* 'URL', *--url=*'URL':: URL of the playbook repository to checkout. *-C* 'CHECKOUT', *--checkout=*'CHECKOUT':: Branch/Tag/Commit to checkout. If not provided, uses default behavior of module used to check out playbook repository. *-f*, *--force*:: Force running of playbook even if unable to update playbook repository. This can be useful, for example, to enforce run-time state when a network connection may not always be up or possible. *-i* 'PATH', *--inventory=*'PATH':: The 'PATH' to the inventory hosts file. This can be a relative path within the checkout. *--purge*:: Purge the checkout after the playbook is run. *-m* 'NAME', *--module-name=*'NAME':: Module used to checkout playbook repository. Defaults to git. *-o*, *--only-if-changed*:: Run the playbook only if the repository has changed AUTHOR ------ Ansible was originally written by Michael DeHaan. See the AUTHORS file for a complete list of contributors. COPYRIGHT --------- Copyright © 2012, Michael DeHaan Ansible is released under the terms of the GPLv3 License. SEE ALSO -------- *ansible*(1), *ansible-playbook*(1), *ansible-doc*(1) Extensive documentation is available in the documentation site: . IRC and mailing list info can be found in file CONTRIBUTING.md, available in: ansible-1.7.2/docs/man/man1/ansible-vault.1000066400000000000000000000115201241061774000203260ustar00rootroot00000000000000'\" t .\" Title: ansible-vault .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 05/26/2014 .\" Manual: System administration commands .\" Source: Ansible 1.7 .\" Language: English .\" .TH "ANSIBLE\-VAULT" "1" "05/26/2014" "Ansible 1\&.7" "System administration commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ansible-vault \- manage encrypted YAML data\&. .SH "SYNOPSIS" .sp ansible\-vault [create|decrypt|edit|encrypt|rekey] [\-\-help] [options] file_name .SH "DESCRIPTION" .sp \fBansible\-vault\fR can encrypt any structured data file used by Ansible\&. This can include \fBgroup_vars/\fR or \fBhost_vars/\fR inventory variables, variables loaded by \fBinclude_vars\fR or \fBvars_files\fR, or variable files passed on the ansible\-playbook command line with \fB\-e @file\&.yml\fR or \fB\-e @file\&.json\fR\&. Role variables and defaults are also included! .sp Because Ansible tasks, handlers, and so on are also data, these can also be encrypted with vault\&. If you\(cqd like to not betray what variables you are even using, you can go as far to keep an individual task file entirely encrypted\&. .SH "COMMON OPTIONS" .sp The following options are available to all sub\-commands: .PP \fB\-\-vault\-password\-file=\fR\fIFILE\fR .RS 4 A file containing the vault password to be used during the encryption/decryption steps\&. Be sure to keep this file secured if it is used\&. .RE .PP \fB\-h\fR, \fB\-\-help\fR .RS 4 Show a help message related to the given sub\-command\&. .RE .PP \fB\-\-debug\fR .RS 4 Enable debugging output for troubleshooting\&. .RE .SH "CREATE" .sp \fB$ ansible\-vault create [options] FILE\fR .sp The \fBcreate\fR sub\-command is used to initialize a new encrypted file\&. .sp First you will be prompted for a password\&. The password used with vault currently must be the same for all files you wish to use together at the same time\&. .sp After providing a password, the tool will launch whatever editor you have defined with $EDITOR, and defaults to vim\&. Once you are done with the editor session, the file will be saved as encrypted data\&. .sp The default cipher is AES (which is shared\-secret based)\&. .SH "EDIT" .sp \fB$ ansible\-vault edit [options] FILE\fR .sp The \fBedit\fR sub\-command is used to modify a file which was previously encrypted using ansible\-vault\&. .sp This command will decrypt the file to a temporary file and allow you to edit the file, saving it back when done and removing the temporary file\&. .SH "REKEY" .sp *$ ansible\-vault rekey [options] FILE_1 [FILE_2, \&..., FILE_N] .sp The \fBrekey\fR command is used to change the password on a vault\-encrypted files\&. This command can update multiple files at once, and will prompt for both the old and new passwords before modifying any data\&. .SH "ENCRYPT" .sp *$ ansible\-vault encrypt [options] FILE_1 [FILE_2, \&..., FILE_N] .sp The \fBencrypt\fR sub\-command is used to encrypt pre\-existing data files\&. As with the \fBrekey\fR command, you can specify multiple files in one command\&. .SH "DECRYPT" .sp *$ ansible\-vault decrypt [options] FILE_1 [FILE_2, \&..., FILE_N] .sp The \fBdecrypt\fR sub\-command is used to remove all encryption from data files\&. The files will be stored as plain\-text YAML once again, so be sure that you do not run this command on data files with active passwords or other sensitive data\&. In most cases, users will want to use the \fBedit\fR sub\-command to modify the files securely\&. .SH "AUTHOR" .sp Ansible was originally written by Michael DeHaan\&. See the AUTHORS file for a complete list of contributors\&. .SH "COPYRIGHT" .sp Copyright \(co 2014, Michael DeHaan .sp Ansible is released under the terms of the GPLv3 License\&. .SH "SEE ALSO" .sp \fBansible\fR(1), \fBansible\-pull\fR(1), \fBansible\-doc\fR(1) .sp Extensive documentation is available in the documentation site: http://docs\&.ansible\&.com\&. IRC and mailing list info can be found in file CONTRIBUTING\&.md, available in: https://github\&.com/ansible/ansible ansible-1.7.2/docs/man/man1/ansible-vault.1.asciidoc.in000066400000000000000000000070111241061774000225100ustar00rootroot00000000000000ansible-vault(1) ================ :doctype: manpage :man source: Ansible :man version: %VERSION% :man manual: System administration commands NAME ---- ansible-vault - manage encrypted YAML data. SYNOPSIS -------- ansible-vault [create|decrypt|edit|encrypt|rekey] [--help] [options] file_name DESCRIPTION ----------- *ansible-vault* can encrypt any structured data file used by Ansible. This can include *group_vars/* or *host_vars/* inventory variables, variables loaded by *include_vars* or *vars_files*, or variable files passed on the ansible-playbook command line with *-e @file.yml* or *-e @file.json*. Role variables and defaults are also included! Because Ansible tasks, handlers, and so on are also data, these can also be encrypted with vault. If you’d like to not betray what variables you are even using, you can go as far to keep an individual task file entirely encrypted. COMMON OPTIONS -------------- The following options are available to all sub-commands: *--vault-password-file=*'FILE':: A file containing the vault password to be used during the encryption/decryption steps. Be sure to keep this file secured if it is used. *-h*, *--help*:: Show a help message related to the given sub-command. *--debug*:: Enable debugging output for troubleshooting. CREATE ------ *$ ansible-vault create [options] FILE* The *create* sub-command is used to initialize a new encrypted file. First you will be prompted for a password. The password used with vault currently must be the same for all files you wish to use together at the same time. After providing a password, the tool will launch whatever editor you have defined with $EDITOR, and defaults to vim. Once you are done with the editor session, the file will be saved as encrypted data. The default cipher is AES (which is shared-secret based). EDIT ---- *$ ansible-vault edit [options] FILE* The *edit* sub-command is used to modify a file which was previously encrypted using ansible-vault. This command will decrypt the file to a temporary file and allow you to edit the file, saving it back when done and removing the temporary file. REKEY ----- *$ ansible-vault rekey [options] FILE_1 [FILE_2, ..., FILE_N] The *rekey* command is used to change the password on a vault-encrypted files. This command can update multiple files at once, and will prompt for both the old and new passwords before modifying any data. ENCRYPT ------- *$ ansible-vault encrypt [options] FILE_1 [FILE_2, ..., FILE_N] The *encrypt* sub-command is used to encrypt pre-existing data files. As with the *rekey* command, you can specify multiple files in one command. DECRYPT ------- *$ ansible-vault decrypt [options] FILE_1 [FILE_2, ..., FILE_N] The *decrypt* sub-command is used to remove all encryption from data files. The files will be stored as plain-text YAML once again, so be sure that you do not run this command on data files with active passwords or other sensitive data. In most cases, users will want to use the *edit* sub-command to modify the files securely. AUTHOR ------ Ansible was originally written by Michael DeHaan. See the AUTHORS file for a complete list of contributors. COPYRIGHT --------- Copyright © 2014, Michael DeHaan Ansible is released under the terms of the GPLv3 License. SEE ALSO -------- *ansible*(1), *ansible-pull*(1), *ansible-doc*(1) Extensive documentation is available in the documentation site: . IRC and mailing list info can be found in file CONTRIBUTING.md, available in: ansible-1.7.2/docs/man/man1/ansible.1000066400000000000000000000137131241061774000172030ustar00rootroot00000000000000'\" t .\" Title: ansible .\" Author: :doctype:manpage .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 05/26/2014 .\" Manual: System administration commands .\" Source: Ansible 1.7 .\" Language: English .\" .TH "ANSIBLE" "1" "05/26/2014" "Ansible 1\&.7" "System administration commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ansible \- run a command somewhere else .SH "SYNOPSIS" .sp ansible [\-f forks] [\-m module_name] [\-a args] .SH "DESCRIPTION" .sp \fBAnsible\fR is an extra\-simple tool/framework/API for doing \*(Aqremote things\*(Aq over SSH\&. .SH "ARGUMENTS" .PP \fBhost\-pattern\fR .RS 4 A name of a group in the inventory file, a shell\-like glob selecting hosts in inventory file, or any combination of the two separated by semicolons\&. .RE .SH "OPTIONS" .PP \fB\-v\fR, \fB\-\-verbose\fR .RS 4 Verbose mode, more output from successful actions will be shown\&. Give up to three times for more output\&. .RE .PP \fB\-i\fR \fIPATH\fR, \fB\-\-inventory=\fR\fIPATH\fR .RS 4 The \fIPATH\fR to the inventory hosts file, which defaults to \fI/etc/ansible/hosts\fR\&. .RE .PP \fB\-f\fR \fINUM\fR, \fB\-\-forks=\fR\fINUM\fR .RS 4 Level of parallelism\&. \fINUM\fR is specified as an integer, the default is 5\&. .RE .PP \fB\-\-private\-key=\fR\fIPRIVATE_KEY_FILE\fR .RS 4 Use this file to authenticate the connection\&. .RE .PP \fB\-m\fR \fINAME\fR, \fB\-\-module\-name=\fR\fINAME\fR .RS 4 Execute the module called \fINAME\fR\&. .RE .PP \fB\-M\fR \fIDIRECTORY\fR, \fB\-\-module\-path=\fR\fIDIRECTORY\fR .RS 4 The \fIDIRECTORY\fR search path to load modules from\&. The default is \fI/usr/share/ansible\fR\&. This can also be set with the ANSIBLE_LIBRARY environment variable\&. .RE .PP \fB\-a\fR \*(Aq\fIARGUMENTS\fR\*(Aq, \fB\-\-args=\fR\*(Aq\fIARGUMENTS\fR\*(Aq .RS 4 The \fIARGUMENTS\fR to pass to the module\&. .RE .PP \fB\-k\fR, \fB\-\-ask\-pass\fR .RS 4 Prompt for the SSH password instead of assuming key\-based authentication with ssh\-agent\&. .RE .PP \fB\-K\fR, \fB\-\-ask\-sudo\-pass\fR .RS 4 Prompt for the password to use with \-\-sudo, if any .RE .PP \fB\-o\fR, \fB\-\-one\-line\fR .RS 4 Try to output everything on one line\&. .RE .PP \fB\-s\fR, \fB\-\-sudo\fR .RS 4 Run the command as the user given by \-u and sudo to root\&. .RE .PP \fB\-t\fR \fIDIRECTORY\fR, \fB\-\-tree=\fR\fIDIRECTORY\fR .RS 4 Save contents in this output \fIDIRECTORY\fR, with the results saved in a file named after each host\&. .RE .PP \fB\-T\fR \fISECONDS\fR, \fB\-\-timeout=\fR\fISECONDS\fR .RS 4 Connection timeout to use when trying to talk to hosts, in \fISECONDS\fR\&. .RE .PP \fB\-B\fR \fINUM\fR, \fB\-\-background=\fR\fINUM\fR .RS 4 Run commands in the background, killing the task after \fINUM\fR seconds\&. .RE .PP \fB\-P\fR \fINUM\fR, \fB\-\-poll=\fR\fINUM\fR .RS 4 Poll a background job every \fINUM\fR seconds\&. Requires \fB\-B\fR\&. .RE .PP \fB\-u\fR \fIUSERNAME\fR, \fB\-\-user=\fR\fIUSERNAME\fR .RS 4 Use this remote \fIUSERNAME\fR instead of the current user\&. .RE .PP \fB\-U\fR \fISUDO_USERNAME\fR, \fB\-\-sudo\-user=\fR\fISUDO_USERNAME\fR .RS 4 Sudo to \fISUDO_USERNAME\fR instead of root\&. Implies \-\-sudo\&. .RE .PP \fB\-c\fR \fICONNECTION\fR, \fB\-\-connection=\fR\fICONNECTION\fR .RS 4 Connection type to use\&. Possible options are \fIparamiko\fR (SSH), \fIssh\fR, and \fIlocal\fR\&. \fIlocal\fR is mostly useful for crontab or kickstarts\&. .RE .PP \fB\-l\fR \fISUBSET\fR, \fB\-\-limit=\fR\fISUBSET\fR .RS 4 Further limits the selected host/group patterns\&. .RE .PP \fB\-l\fR \fI~REGEX\fR, \fB\-\-limit=\fR\fI~REGEX\fR .RS 4 Further limits hosts with a regex pattern\&. .RE .SH "INVENTORY" .sp Ansible stores the hosts it can potentially operate on in an inventory file\&. The syntax is one host per line\&. Groups headers are allowed and are included on their own line, enclosed in square brackets that start the line\&. .sp Ranges of hosts are also supported\&. For more information and additional options, see the documentation on http://docs\&.ansible\&.com/\&. .SH "FILES" .sp /etc/ansible/hosts \(em Default inventory file .sp /usr/share/ansible/ \(em Default module library .sp /etc/ansible/ansible\&.cfg \(em Config file, used if present .sp ~/\&.ansible\&.cfg \(em User config file, overrides the default config if present .SH "ENVIRONMENT" .sp The following environment variables may be specified\&. .sp ANSIBLE_HOSTS \(em Override the default ansible hosts file .sp ANSIBLE_LIBRARY \(em Override the default ansible module library path .sp ANSIBLE_CONFIG \(em Override the default ansible config file .SH "AUTHOR" .sp Ansible was originally written by Michael DeHaan\&. See the AUTHORS file for a complete list of contributors\&. .SH "COPYRIGHT" .sp Copyright \(co 2012, Michael DeHaan .sp Ansible is released under the terms of the GPLv3 License\&. .SH "SEE ALSO" .sp \fBansible\-playbook\fR(1), \fBansible\-pull\fR(1), \fBansible\-doc\fR(1) .sp Extensive documentation is available in the documentation site: http://docs\&.ansible\&.com\&. IRC and mailing list info can be found in file CONTRIBUTING\&.md, available in: https://github\&.com/ansible/ansible .SH "AUTHOR" .PP \fB:doctype:manpage\fR .RS 4 Author. .RE ansible-1.7.2/docs/man/man1/ansible.1.asciidoc.in000066400000000000000000000100661241061774000213630ustar00rootroot00000000000000ansible(1) ========= :doctype:manpage :man source: Ansible :man version: %VERSION% :man manual: System administration commands NAME ---- ansible - run a command somewhere else SYNOPSIS -------- ansible [-f forks] [-m module_name] [-a args] DESCRIPTION ----------- *Ansible* is an extra-simple tool/framework/API for doing \'remote things' over SSH. ARGUMENTS --------- *host-pattern*:: A name of a group in the inventory file, a shell-like glob selecting hosts in inventory file, or any combination of the two separated by semicolons. OPTIONS ------- *-v*, *--verbose*:: Verbose mode, more output from successful actions will be shown. Give up to three times for more output. *-i* 'PATH', *--inventory=*'PATH':: The 'PATH' to the inventory hosts file, which defaults to '/etc/ansible/hosts'. *-f* 'NUM', *--forks=*'NUM':: Level of parallelism. 'NUM' is specified as an integer, the default is 5. *--private-key=*'PRIVATE_KEY_FILE':: Use this file to authenticate the connection. *-m* 'NAME', *--module-name=*'NAME':: Execute the module called 'NAME'. *-M* 'DIRECTORY', *--module-path=*'DIRECTORY':: The 'DIRECTORY' search path to load modules from. The default is '/usr/share/ansible'. This can also be set with the ANSIBLE_LIBRARY environment variable. *-a* \'_ARGUMENTS_', *--args=*\'_ARGUMENTS_':: The 'ARGUMENTS' to pass to the module. *-k*, *--ask-pass*:: Prompt for the SSH password instead of assuming key-based authentication with ssh-agent. *-K*, *--ask-sudo-pass*:: Prompt for the password to use with --sudo, if any *-o*, *--one-line*:: Try to output everything on one line. *-s*, *--sudo*:: Run the command as the user given by -u and sudo to root. *-t* 'DIRECTORY', *--tree=*'DIRECTORY':: Save contents in this output 'DIRECTORY', with the results saved in a file named after each host. *-T* 'SECONDS', *--timeout=*'SECONDS':: Connection timeout to use when trying to talk to hosts, in 'SECONDS'. *-B* 'NUM', *--background=*'NUM':: Run commands in the background, killing the task after 'NUM' seconds. *-P* 'NUM', *--poll=*'NUM':: Poll a background job every 'NUM' seconds. Requires *-B*. *-u* 'USERNAME', *--user=*'USERNAME':: Use this remote 'USERNAME' instead of the current user. *-U* 'SUDO_USERNAME', *--sudo-user=*'SUDO_USERNAME':: Sudo to 'SUDO_USERNAME' instead of root. Implies --sudo. *-c* 'CONNECTION', *--connection=*'CONNECTION':: Connection type to use. Possible options are 'paramiko' (SSH), 'ssh', and 'local'. 'local' is mostly useful for crontab or kickstarts. *-l* 'SUBSET', *--limit=*'SUBSET':: Further limits the selected host/group patterns. *-l* '\~REGEX', *--limit=*'~REGEX':: Further limits hosts with a regex pattern. INVENTORY --------- Ansible stores the hosts it can potentially operate on in an inventory file. The syntax is one host per line. Groups headers are allowed and are included on their own line, enclosed in square brackets that start the line. Ranges of hosts are also supported. For more information and additional options, see the documentation on http://docs.ansible.com/. FILES ----- /etc/ansible/hosts -- Default inventory file /usr/share/ansible/ -- Default module library /etc/ansible/ansible.cfg -- Config file, used if present ~/.ansible.cfg -- User config file, overrides the default config if present ENVIRONMENT ----------- The following environment variables may be specified. ANSIBLE_HOSTS -- Override the default ansible hosts file ANSIBLE_LIBRARY -- Override the default ansible module library path ANSIBLE_CONFIG -- Override the default ansible config file AUTHOR ------ Ansible was originally written by Michael DeHaan. See the AUTHORS file for a complete list of contributors. COPYRIGHT --------- Copyright © 2012, Michael DeHaan Ansible is released under the terms of the GPLv3 License. SEE ALSO -------- *ansible-playbook*(1), *ansible-pull*(1), *ansible-doc*(1) Extensive documentation is available in the documentation site: . IRC and mailing list info can be found in file CONTRIBUTING.md, available in: ansible-1.7.2/docs/man/man3/000077500000000000000000000000001241061774000155015ustar00rootroot00000000000000ansible-1.7.2/docs/man/man3/.gitdir000066400000000000000000000000001241061774000167520ustar00rootroot00000000000000ansible-1.7.2/docsite/000077500000000000000000000000001241061774000145725ustar00rootroot00000000000000ansible-1.7.2/docsite/.gitignore000066400000000000000000000003171241061774000165630ustar00rootroot00000000000000# Old compiled python stuff *.py[co] # package building stuff build # Emacs backup files... *~ .\#* .doctrees # Generated docs stuff ansible*.xml .buildinfo objects.inv .doctrees rst/modules/*.rst *.min.css ansible-1.7.2/docsite/.nojekyll000066400000000000000000000000001241061774000164100ustar00rootroot00000000000000ansible-1.7.2/docsite/Makefile000066400000000000000000000025231241061774000162340ustar00rootroot00000000000000#!/usr/bin/make SITELIB = $(shell python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()") FORMATTER=../hacking/module_formatter.py all: clean docs docs: clean modules staticmin ./build-site.py -(cp *.ico htmlout/) -(cp *.jpg htmlout/) -(cp *.png htmlout/) variables: (mkdir -p htmlout/) dot variables.dot -Tpng -o htmlout/variables.png viewdocs: clean staticmin ./build-site.py view htmldocs: staticmin ./build-site.py rst clean: -rm -rf htmlout -rm -f .buildinfo -rm -f *.inv -rm -rf *.doctrees @echo "Cleaning up minified css files" find . -type f -name "*.min.css" -delete @echo "Cleaning up byte compiled python stuff" find . -regex ".*\.py[co]$$" -delete @echo "Cleaning up editor backup files" find . -type f \( -name "*~" -or -name "#*" \) -delete find . -type f \( -name "*.swp" \) -delete @echo "Cleaning up generated rst" -rm rst/list_of_*.rst -rm rst/*_by_category.rst -rm rst/*_module.rst .PHONEY: docs clean modules: $(FORMATTER) ../hacking/templates/rst.j2 PYTHONPATH=../lib $(FORMATTER) -t rst --template-dir=../hacking/templates --module-dir=../library -o rst/ staticmin: cat _themes/srtd/static/css/theme.css | sed -e 's/^[ \t]*//g; s/[ \t]*$$//g; s/\([:{;,]\) /\1/g; s/ {/{/g; s/\/\*.*\*\///g; /^$$/d' | sed -e :a -e '$$!N; s/\n\(.\)/\1/; ta' > _themes/srtd/static/css/theme.min.css ansible-1.7.2/docsite/README.md000066400000000000000000000025341241061774000160550ustar00rootroot00000000000000Homepage and documentation source for Ansible ============================================= This project hosts the source behind [docs.ansible.com](http://docs.ansible.com/) Contributions to the documentation are welcome. To make changes, submit a pull request that changes the reStructuredText files in the "rst/" directory only, and Michael can do a docs build and push the static files. If you wish to verify output from the markup such as link references, you may install sphinx and build the documentation by running `make viewdocs` from the `ansible/docsite` directory. To include module documentation you'll need to run `make webdocs` at the top level of the repository. The generated html files are in docsite/htmlout/. If you do not want to learn the reStructuredText format, you can also [file issues] about documentation problems on the Ansible GitHub project. Note that module documentation can actually be [generated from a DOCUMENTATION docstring][module-docs] in the modules directory, so corrections to modules written as such need to be made in the module source, rather than in docsite source. To install sphinx and the required theme, install pip and then "pip install sphinx sphinx_rtd_theme" [file issues]: https://github.com/ansible/ansible/issues [module-docs]: http://docs.ansible.com/developing_modules.html#documenting-your-module ansible-1.7.2/docsite/_static/000077500000000000000000000000001241061774000162205ustar00rootroot00000000000000ansible-1.7.2/docsite/_static/ansible-local.css000066400000000000000000000001521241061774000214350ustar00rootroot00000000000000/* Local CSS tweaks for ansible */ .dropdown-menu { overflow-y: auto; } h2 { padding-top: 40px; }ansible-1.7.2/docsite/_static/basic.css000066400000000000000000000204171241061774000200170ustar00rootroot00000000000000/* * basic.css * ~~~~~~~~~ * * Sphinx stylesheet -- basic theme. * * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /* -- main layout ----------------------------------------------------------- */ div.clearer { clear: both; } /* -- relbar ---------------------------------------------------------------- */ div.related { width: 100%; font-size: 90%; } div.related h3 { display: none; } div.related ul { margin: 0; padding: 0 0 0 10px; list-style: none; } div.related li { display: inline; } div.related li.right { float: right; margin-right: 5px; } /* -- sidebar --------------------------------------------------------------- */ div.sphinxsidebarwrapper { padding: 10px 5px 0 10px; } div.sphinxsidebar { float: left; width: 230px; margin-left: -100%; font-size: 90%; } div.sphinxsidebar ul { list-style: none; } div.sphinxsidebar ul ul, div.sphinxsidebar ul.want-points { margin-left: 20px; list-style: square; } div.sphinxsidebar ul ul { margin-top: 0; margin-bottom: 0; } div.sphinxsidebar form { margin-top: 10px; } div.sphinxsidebar input { border: 1px solid #98dbcc; font-family: sans-serif; font-size: 1em; } div.sphinxsidebar #searchbox input[type="text"] { width: 170px; } div.sphinxsidebar #searchbox input[type="submit"] { width: 30px; } img { border: 0; } /* -- search page ----------------------------------------------------------- */ ul.search { margin: 10px 0 0 20px; padding: 0; } ul.search li { padding: 5px 0 5px 20px; background-image: url(file.png); background-repeat: no-repeat; background-position: 0 7px; } ul.search li a { font-weight: bold; } ul.search li div.context { color: #888; margin: 2px 0 0 30px; text-align: left; } ul.keywordmatches li.goodmatch a { font-weight: bold; } /* -- index page ------------------------------------------------------------ */ table.contentstable { width: 90%; } table.contentstable p.biglink { line-height: 150%; } a.biglink { font-size: 1.3em; } span.linkdescr { font-style: italic; padding-top: 5px; font-size: 90%; } /* -- general index --------------------------------------------------------- */ table.indextable { width: 100%; } table.indextable td { text-align: left; vertical-align: top; } table.indextable dl, table.indextable dd { margin-top: 0; margin-bottom: 0; } table.indextable tr.pcap { height: 10px; } table.indextable tr.cap { margin-top: 10px; background-color: #f2f2f2; } img.toggler { margin-right: 3px; margin-top: 3px; cursor: pointer; } div.modindex-jumpbox { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; margin: 1em 0 1em 0; padding: 0.4em; } div.genindex-jumpbox { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; margin: 1em 0 1em 0; padding: 0.4em; } /* -- general body styles --------------------------------------------------- */ a.headerlink { visibility: hidden; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink { visibility: visible; } div.body p.caption { text-align: inherit; } div.body td { text-align: left; } .field-list ul { padding-left: 1em; } .first { margin-top: 0 !important; } p.rubric { margin-top: 30px; font-weight: bold; } img.align-left, .figure.align-left, object.align-left { clear: left; float: left; margin-right: 1em; } img.align-right, .figure.align-right, object.align-right { clear: right; float: right; margin-left: 1em; } img.align-center, .figure.align-center, object.align-center { display: block; margin-left: auto; margin-right: auto; } .align-left { text-align: left; } .align-center { text-align: center; } .align-right { text-align: right; } /* -- sidebars -------------------------------------------------------------- */ div.sidebar { margin: 0 0 0.5em 1em; border: 1px solid #ddb; padding: 7px 7px 0 7px; background-color: #ffe; width: 40%; float: right; } p.sidebar-title { font-weight: bold; } /* -- topics ---------------------------------------------------------------- */ div.topic { border: 1px solid #ccc; padding: 7px 7px 0 7px; margin: 10px 0 10px 0; } p.topic-title { font-size: 1.1em; font-weight: bold; margin-top: 10px; } /* -- admonitions ----------------------------------------------------------- */ div.admonition { margin-top: 10px; margin-bottom: 10px; padding: 7px; } div.admonition dt { font-weight: bold; } div.admonition dl { margin-bottom: 0; } p.admonition-title { margin: 0px 10px 5px 0px; font-weight: bold; } div.body p.centered { text-align: center; margin-top: 25px; } /* -- tables ---------------------------------------------------------------- */ table.docutils { border: 0; border-collapse: collapse; } table.docutils td, table.docutils th { padding: 1px 8px 1px 5px; border-top: 0; border-left: 0; border-right: 0; border-bottom: 1px solid #aaa; } table.field-list td, table.field-list th { border: 0 !important; } table.footnote td, table.footnote th { border: 0 !important; } th { text-align: left; padding-right: 5px; } table.citation { border-left: solid 1px gray; margin-left: 1px; } table.citation td { border-bottom: none; } /* -- other body styles ----------------------------------------------------- */ ol.arabic { list-style: decimal; } ol.loweralpha { list-style: lower-alpha; } ol.upperalpha { list-style: upper-alpha; } ol.lowerroman { list-style: lower-roman; } ol.upperroman { list-style: upper-roman; } dl { margin-bottom: 15px; } dd p { margin-top: 0px; } dd ul, dd table { margin-bottom: 10px; } dd { margin-top: 3px; margin-bottom: 10px; margin-left: 30px; } dt:target, .highlighted { background-color: #fbe54e; } dl.glossary dt { font-weight: bold; font-size: 1.1em; } .field-list ul { margin: 0; padding-left: 1em; } .field-list p { margin: 0; } .refcount { color: #060; } .optional { font-size: 1.3em; } .versionmodified { font-style: italic; } .system-message { background-color: #fda; padding: 5px; border: 3px solid red; } .footnote:target { background-color: #ffa; } .line-block { display: block; margin-top: 1em; margin-bottom: 1em; } .line-block .line-block { margin-top: 0; margin-bottom: 0; margin-left: 1.5em; } .guilabel, .menuselection { font-family: sans-serif; } .accelerator { text-decoration: underline; } .classifier { font-style: oblique; } abbr, acronym { border-bottom: dotted 1px; cursor: help; } /* -- code displays --------------------------------------------------------- */ pre { overflow: auto; overflow-y: hidden; /* fixes display issues on Chrome browsers */ } td.linenos pre { padding: 5px 0px; border: 0; background-color: transparent; color: #aaa; } table.highlighttable { margin-left: 0.5em; } table.highlighttable td { padding: 0 0.5em 0 0.5em; } tt.descname { background-color: transparent; font-weight: bold; font-size: 1.2em; } tt.descclassname { background-color: transparent; } tt.xref, a tt { background-color: transparent; font-weight: bold; } h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { background-color: transparent; } .viewcode-link { float: right; } .viewcode-back { float: right; font-family: sans-serif; } div.viewcode-block:target { margin: -1px -10px; padding: 0 10px; } /* -- math display ---------------------------------------------------------- */ img.math { vertical-align: middle; } div.body div.math p { text-align: center; } span.eqno { float: right; } /* -- printout stylesheet --------------------------------------------------- */ @media print { div.document, div.documentwrapper, div.bodywrapper { margin: 0 !important; width: 100%; } div.sphinxsidebar, div.related, div.footer, #top-link { display: none; } }ansible-1.7.2/docsite/_static/bootstrap-dropdown.js000066400000000000000000000032321241061774000224250ustar00rootroot00000000000000/* ============================================================ * bootstrap-dropdown.js v1.4.0 * http://twitter.github.com/bootstrap/javascript.html#dropdown * ============================================================ * Copyright 2011 Twitter, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============================================================ */ !function( $ ){ "use strict" /* DROPDOWN PLUGIN DEFINITION * ========================== */ $.fn.dropdown = function ( selector ) { return this.each(function () { $(this).delegate(selector || d, 'click', function (e) { var li = $(this).parent('li') , isActive = li.hasClass('open') clearMenus() !isActive && li.toggleClass('open') return false }) }) } /* APPLY TO STANDARD DROPDOWN ELEMENTS * =================================== */ var d = 'a.menu, .dropdown-toggle' function clearMenus() { $(d).parent('li').removeClass('open') } $(function () { $('html').bind("click", clearMenus) $('body').dropdown( '[data-dropdown] a.menu, [data-dropdown] .dropdown-toggle' ) }) }( window.jQuery || window.ender ); ansible-1.7.2/docsite/_static/bootstrap-scrollspy.js000066400000000000000000000056721241061774000226350ustar00rootroot00000000000000/* ============================================================= * bootstrap-scrollspy.js v1.4.0 * http://twitter.github.com/bootstrap/javascript.html#scrollspy * ============================================================= * Copyright 2011 Twitter, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============================================================== */ !function ( $ ) { "use strict" var $window = $(window) function ScrollSpy( topbar, selector ) { var processScroll = $.proxy(this.processScroll, this) this.$topbar = $(topbar) this.selector = selector || 'li > a' this.refresh() this.$topbar.delegate(this.selector, 'click', processScroll) $window.scroll(processScroll) this.processScroll() } ScrollSpy.prototype = { refresh: function () { this.targets = this.$topbar.find(this.selector).map(function () { var href = $(this).attr('href') return /^#\w/.test(href) && $(href).length ? href : null }) this.offsets = $.map(this.targets, function (id) { return $(id).offset().top }) } , processScroll: function () { var scrollTop = $window.scrollTop() + 10 , offsets = this.offsets , targets = this.targets , activeTarget = this.activeTarget , i for (i = offsets.length; i--;) { activeTarget != targets[i] && scrollTop >= offsets[i] && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) && this.activateButton( targets[i] ) } } , activateButton: function (target) { this.activeTarget = target this.$topbar .find(this.selector).parent('.active') .removeClass('active') this.$topbar .find(this.selector + '[href="' + target + '"]') .parent('li') .addClass('active') } } /* SCROLLSPY PLUGIN DEFINITION * =========================== */ $.fn.scrollSpy = function( options ) { var scrollspy = this.data('scrollspy') if (!scrollspy) { return this.each(function () { $(this).data('scrollspy', new ScrollSpy( this, options )) }) } if ( options === true ) { return scrollspy } if ( typeof options == 'string' ) { scrollspy[options]() } return this } $(document).ready(function () { $('body').scrollSpy('[data-scrollspy] li > a') }) }( window.jQuery || window.ender );ansible-1.7.2/docsite/_static/bootstrap-sphinx.css000066400000000000000000000002731241061774000222600ustar00rootroot00000000000000/* * bootstrap-sphinx.css * ~~~~~~~~~~~~~~~~~~~~ * * Sphinx stylesheet -- Twitter Bootstrap theme. */ body { padding-top: 42px; } div.documentwrapper { float: left; width: 100%; }ansible-1.7.2/docsite/_static/bootstrap.css000066400000000000000000001560751241061774000207650ustar00rootroot00000000000000/*! * Bootstrap v1.4.0 * * Copyright 2011 Twitter, Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Designed and built with all the love in the world @twitter by @mdo and @fat. * Date: Sun Nov 20 21:42:29 PST 2011 */ /* Reset.less * Props to Eric Meyer (meyerweb.com) for his CSS reset file. We're using an adapted version here that cuts out some of the reset HTML elements we will never need here (i.e., dfn, samp, etc). * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ html, body { margin: 0; padding: 0; } h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, cite, code, del, dfn, em, img, q, s, samp, small, strike, strong, sub, sup, tt, var, dd, dl, dt, li, ol, ul, fieldset, form, label, legend, button, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; font-weight: normal; font-style: normal; font-size: 100%; line-height: 1; font-family: inherit; } table { border-collapse: collapse; border-spacing: 0; } ol, ul { list-style: none; } q:before, q:after, blockquote:before, blockquote:after { content: ""; } html { overflow-y: scroll; font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } a:focus { outline: thin dotted; } a:hover, a:active { outline: 0; } article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; } audio, canvas, video { display: inline-block; *display: inline; *zoom: 1; } audio:not([controls]) { display: none; } sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sup { top: -0.5em; } sub { bottom: -0.25em; } img { border: 0; -ms-interpolation-mode: bicubic; } button, input, select, textarea { font-size: 100%; margin: 0; vertical-align: baseline; *vertical-align: middle; } button, input { line-height: normal; *overflow: visible; } button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; } button, input[type="button"], input[type="reset"], input[type="submit"] { cursor: pointer; -webkit-appearance: button; } input[type="search"] { -webkit-appearance: textfield; -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; } input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } textarea { overflow: auto; vertical-align: top; } /* Variables.less * Variables to customize the look and feel of Bootstrap * ----------------------------------------------------- */ /* Mixins.less * Snippets of reusable CSS to develop faster and keep code readable * ----------------------------------------------------------------- */ /* * Scaffolding * Basic and global styles for generating a grid system, structural layout, and page templates * ------------------------------------------------------------------------------------------- */ body { background-color: #ffffff; margin: 0; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; font-weight: normal; line-height: 18px; color: #404040; } .container { width: 940px; margin-left: auto; margin-right: auto; zoom: 1; } .container:before, .container:after { display: table; content: ""; zoom: 1; } .container:after { clear: both; } .container-fluid { position: relative; min-width: 940px; padding-left: 20px; padding-right: 20px; zoom: 1; } .container-fluid:before, .container-fluid:after { display: table; content: ""; zoom: 1; } .container-fluid:after { clear: both; } .container-fluid > .sidebar { position: absolute; top: 0; left: 20px; width: 220px; } .container-fluid > .content { margin-left: 240px; } a { color: #0069d6; text-decoration: none; line-height: inherit; font-weight: inherit; } a:hover { color: #00438a; text-decoration: underline; } .pull-right { float: right; } .pull-left { float: left; } .hide { display: none; } .show { display: block; } .row { zoom: 1; margin-left: -20px; } .row:before, .row:after { display: table; content: ""; zoom: 1; } .row:after { clear: both; } .row > [class*="span"] { display: inline; float: left; margin-left: 20px; } .span1 { width: 40px; } .span2 { width: 100px; } .span3 { width: 160px; } .span4 { width: 220px; } .span5 { width: 280px; } .span6 { width: 340px; } .span7 { width: 400px; } .span8 { width: 460px; } .span9 { width: 520px; } .span10 { width: 580px; } .span11 { width: 640px; } .span12 { width: 700px; } .span13 { width: 760px; } .span14 { width: 820px; } .span15 { width: 880px; } .span16 { width: 940px; } .span17 { width: 1000px; } .span18 { width: 1060px; } .span19 { width: 1120px; } .span20 { width: 1180px; } .span21 { width: 1240px; } .span22 { width: 1300px; } .span23 { width: 1360px; } .span24 { width: 1420px; } .row > .offset1 { margin-left: 80px; } .row > .offset2 { margin-left: 140px; } .row > .offset3 { margin-left: 200px; } .row > .offset4 { margin-left: 260px; } .row > .offset5 { margin-left: 320px; } .row > .offset6 { margin-left: 380px; } .row > .offset7 { margin-left: 440px; } .row > .offset8 { margin-left: 500px; } .row > .offset9 { margin-left: 560px; } .row > .offset10 { margin-left: 620px; } .row > .offset11 { margin-left: 680px; } .row > .offset12 { margin-left: 740px; } .span-one-third { width: 300px; } .span-two-thirds { width: 620px; } .row > .offset-one-third { margin-left: 340px; } .row > .offset-two-thirds { margin-left: 660px; } /* Typography.less * Headings, body text, lists, code, and more for a versatile and durable typography system * ---------------------------------------------------------------------------------------- */ p { font-size: 13px; font-weight: normal; line-height: 18px; margin-bottom: 9px; } p small { font-size: 11px; color: #bfbfbf; } h1, h2, h3, h4, h5, h6 { font-weight: bold; color: #404040; } h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { color: #bfbfbf; } h1 { margin-bottom: 18px; font-size: 30px; line-height: 36px; } h1 small { font-size: 18px; } h2 { font-size: 24px; line-height: 36px; } h2 small { font-size: 14px; } h3, h4, h5, h6 { line-height: 36px; } h3 { font-size: 18px; } h3 small { font-size: 14px; } h4 { font-size: 16px; } h4 small { font-size: 12px; } h5 { font-size: 14px; } h6 { font-size: 13px; color: #bfbfbf; text-transform: uppercase; } ul, ol { margin: 0 0 18px 25px; } ul ul, ul ol, ol ol, ol ul { margin-bottom: 0; } ul { list-style: disc; } ol { list-style: decimal; } li { line-height: 18px; color: #808080; } ul.unstyled { list-style: none; margin-left: 0; } dl { margin-bottom: 18px; } dl dt, dl dd { line-height: 18px; } dl dt { font-weight: bold; } dl dd { margin-left: 9px; } hr { margin: 20px 0 19px; border: 0; border-bottom: 1px solid #eee; } strong { font-style: inherit; font-weight: bold; } em { font-style: italic; font-weight: inherit; line-height: inherit; } .muted { color: #bfbfbf; } blockquote { margin-bottom: 18px; border-left: 5px solid #eee; padding-left: 15px; } blockquote p { font-size: 14px; font-weight: 300; line-height: 18px; margin-bottom: 0; } blockquote small { display: block; font-size: 12px; font-weight: 300; line-height: 18px; color: #bfbfbf; } blockquote small:before { content: '\2014 \00A0'; } address { display: block; line-height: 18px; margin-bottom: 18px; } code, pre { padding: 0 3px 2px; font-family: Monaco, Andale Mono, Courier New, monospace; font-size: 12px; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } .module { font-family: Monaco, Andale Mono, Courier New, monospace; font-size: 12px; } code { color: rgba(0, 0, 0, 0.75); } pre { background-color: #f5f5f5; display: block; padding: 8.5px; margin: 0 0 18px; line-height: 18px; font-size: 12px; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, 0.15); -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; white-space: pre; white-space: pre-wrap; word-wrap: break-word; } /* Forms.less * Base styles for various input types, form layouts, and states * ------------------------------------------------------------- */ form { margin-bottom: 18px; } fieldset { margin-bottom: 18px; padding-top: 18px; } fieldset legend { display: block; padding-left: 150px; font-size: 19.5px; line-height: 1; color: #404040; *padding: 0 0 5px 145px; /* IE6-7 */ *line-height: 1.5; /* IE6-7 */ } form .clearfix { margin-bottom: 18px; zoom: 1; } form .clearfix:before, form .clearfix:after { display: table; content: ""; zoom: 1; } form .clearfix:after { clear: both; } label, input, select, textarea { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; font-weight: normal; line-height: normal; } label { padding-top: 6px; font-size: 13px; line-height: 18px; float: left; width: 130px; text-align: right; color: #404040; } form .input { margin-left: 150px; } input[type=checkbox], input[type=radio] { cursor: pointer; } input, textarea, select, .uneditable-input { display: inline-block; width: 210px; height: 18px; padding: 4px; font-size: 13px; line-height: 18px; color: #808080; border: 1px solid #ccc; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } select { padding: initial; } input[type=checkbox], input[type=radio] { width: auto; height: auto; padding: 0; margin: 3px 0; *margin-top: 0; /* IE6-7 */ line-height: normal; border: none; } input[type=file] { background-color: #ffffff; padding: initial; border: initial; line-height: initial; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; } input[type=button], input[type=reset], input[type=submit] { width: auto; height: auto; } select, input[type=file] { height: 27px; *height: auto; line-height: 27px; *margin-top: 4px; /* For IE7, add top margin to align select with labels */ } select[multiple] { height: inherit; background-color: #ffffff; } textarea { height: auto; } .uneditable-input { background-color: #ffffff; display: block; border-color: #eee; -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); cursor: not-allowed; } :-moz-placeholder { color: #bfbfbf; } ::-webkit-input-placeholder { color: #bfbfbf; } input, textarea { -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; -moz-transition: border linear 0.2s, box-shadow linear 0.2s; -ms-transition: border linear 0.2s, box-shadow linear 0.2s; -o-transition: border linear 0.2s, box-shadow linear 0.2s; transition: border linear 0.2s, box-shadow linear 0.2s; -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); } input:focus, textarea:focus { outline: 0; border-color: rgba(82, 168, 236, 0.8); -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); } input[type=file]:focus, input[type=checkbox]:focus, select:focus { -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; outline: 1px dotted #666; } form .clearfix.error > label, form .clearfix.error .help-block, form .clearfix.error .help-inline { color: #b94a48; } form .clearfix.error input, form .clearfix.error textarea { color: #b94a48; border-color: #ee5f5b; } form .clearfix.error input:focus, form .clearfix.error textarea:focus { border-color: #e9322d; -webkit-box-shadow: 0 0 6px #f8b9b7; -moz-box-shadow: 0 0 6px #f8b9b7; box-shadow: 0 0 6px #f8b9b7; } form .clearfix.error .input-prepend .add-on, form .clearfix.error .input-append .add-on { color: #b94a48; background-color: #fce6e6; border-color: #b94a48; } form .clearfix.warning > label, form .clearfix.warning .help-block, form .clearfix.warning .help-inline { color: #c09853; } form .clearfix.warning input, form .clearfix.warning textarea { color: #c09853; border-color: #ccae64; } form .clearfix.warning input:focus, form .clearfix.warning textarea:focus { border-color: #be9a3f; -webkit-box-shadow: 0 0 6px #e5d6b1; -moz-box-shadow: 0 0 6px #e5d6b1; box-shadow: 0 0 6px #e5d6b1; } form .clearfix.warning .input-prepend .add-on, form .clearfix.warning .input-append .add-on { color: #c09853; background-color: #d2b877; border-color: #c09853; } form .clearfix.success > label, form .clearfix.success .help-block, form .clearfix.success .help-inline { color: #468847; } form .clearfix.success input, form .clearfix.success textarea { color: #468847; border-color: #57a957; } form .clearfix.success input:focus, form .clearfix.success textarea:focus { border-color: #458845; -webkit-box-shadow: 0 0 6px #9acc9a; -moz-box-shadow: 0 0 6px #9acc9a; box-shadow: 0 0 6px #9acc9a; } form .clearfix.success .input-prepend .add-on, form .clearfix.success .input-append .add-on { color: #468847; background-color: #bcddbc; border-color: #468847; } .input-mini, input.mini, textarea.mini, select.mini { width: 60px; } .input-small, input.small, textarea.small, select.small { width: 90px; } .input-medium, input.medium, textarea.medium, select.medium { width: 150px; } .input-large, input.large, textarea.large, select.large { width: 210px; } .input-xlarge, input.xlarge, textarea.xlarge, select.xlarge { width: 270px; } .input-xxlarge, input.xxlarge, textarea.xxlarge, select.xxlarge { width: 530px; } textarea.xxlarge { overflow-y: auto; } input.span1, textarea.span1 { display: inline-block; float: none; width: 30px; margin-left: 0; } input.span2, textarea.span2 { display: inline-block; float: none; width: 90px; margin-left: 0; } input.span3, textarea.span3 { display: inline-block; float: none; width: 150px; margin-left: 0; } input.span4, textarea.span4 { display: inline-block; float: none; width: 210px; margin-left: 0; } input.span5, textarea.span5 { display: inline-block; float: none; width: 270px; margin-left: 0; } input.span6, textarea.span6 { display: inline-block; float: none; width: 330px; margin-left: 0; } input.span7, textarea.span7 { display: inline-block; float: none; width: 390px; margin-left: 0; } input.span8, textarea.span8 { display: inline-block; float: none; width: 450px; margin-left: 0; } input.span9, textarea.span9 { display: inline-block; float: none; width: 510px; margin-left: 0; } input.span10, textarea.span10 { display: inline-block; float: none; width: 570px; margin-left: 0; } input.span11, textarea.span11 { display: inline-block; float: none; width: 630px; margin-left: 0; } input.span12, textarea.span12 { display: inline-block; float: none; width: 690px; margin-left: 0; } input.span13, textarea.span13 { display: inline-block; float: none; width: 750px; margin-left: 0; } input.span14, textarea.span14 { display: inline-block; float: none; width: 810px; margin-left: 0; } input.span15, textarea.span15 { display: inline-block; float: none; width: 870px; margin-left: 0; } input.span16, textarea.span16 { display: inline-block; float: none; width: 930px; margin-left: 0; } input[disabled], select[disabled], textarea[disabled], input[readonly], select[readonly], textarea[readonly] { background-color: #f5f5f5; border-color: #ddd; cursor: not-allowed; } .actions { background: #f5f5f5; margin-top: 18px; margin-bottom: 18px; padding: 17px 20px 18px 150px; border-top: 1px solid #ddd; -webkit-border-radius: 0 0 3px 3px; -moz-border-radius: 0 0 3px 3px; border-radius: 0 0 3px 3px; } .actions .secondary-action { float: right; } .actions .secondary-action a { line-height: 30px; } .actions .secondary-action a:hover { text-decoration: underline; } .help-inline, .help-block { font-size: 13px; line-height: 18px; color: #bfbfbf; } .help-inline { padding-left: 5px; *position: relative; /* IE6-7 */ *top: -5px; /* IE6-7 */ } .help-block { display: block; max-width: 600px; } .inline-inputs { color: #808080; } .inline-inputs span { padding: 0 2px 0 1px; } .input-prepend input, .input-append input { -webkit-border-radius: 0 3px 3px 0; -moz-border-radius: 0 3px 3px 0; border-radius: 0 3px 3px 0; } .input-prepend .add-on, .input-append .add-on { position: relative; background: #f5f5f5; border: 1px solid #ccc; z-index: 2; float: left; display: block; width: auto; min-width: 16px; height: 18px; padding: 4px 4px 4px 5px; margin-right: -1px; font-weight: normal; line-height: 18px; color: #bfbfbf; text-align: center; text-shadow: 0 1px 0 #ffffff; -webkit-border-radius: 3px 0 0 3px; -moz-border-radius: 3px 0 0 3px; border-radius: 3px 0 0 3px; } .input-prepend .active, .input-append .active { background: #a9dba9; border-color: #46a546; } .input-prepend .add-on { *margin-top: 1px; /* IE6-7 */ } .input-append input { float: left; -webkit-border-radius: 3px 0 0 3px; -moz-border-radius: 3px 0 0 3px; border-radius: 3px 0 0 3px; } .input-append .add-on { -webkit-border-radius: 0 3px 3px 0; -moz-border-radius: 0 3px 3px 0; border-radius: 0 3px 3px 0; margin-right: 0; margin-left: -1px; } .inputs-list { margin: 0 0 5px; width: 100%; } .inputs-list li { display: block; padding: 0; width: 100%; } .inputs-list label { display: block; float: none; width: auto; padding: 0; margin-left: 20px; line-height: 18px; text-align: left; white-space: normal; } .inputs-list label strong { color: #808080; } .inputs-list label small { font-size: 11px; font-weight: normal; } .inputs-list .inputs-list { margin-left: 25px; margin-bottom: 10px; padding-top: 0; } .inputs-list:first-child { padding-top: 6px; } .inputs-list li + li { padding-top: 2px; } .inputs-list input[type=radio], .inputs-list input[type=checkbox] { margin-bottom: 0; margin-left: -20px; float: left; } .form-stacked { padding-left: 20px; } .form-stacked fieldset { padding-top: 9px; } .form-stacked legend { padding-left: 0; } .form-stacked label { display: block; float: none; width: auto; font-weight: bold; text-align: left; line-height: 20px; padding-top: 0; } .form-stacked .clearfix { margin-bottom: 9px; } .form-stacked .clearfix div.input { margin-left: 0; } .form-stacked .inputs-list { margin-bottom: 0; } .form-stacked .inputs-list li { padding-top: 0; } .form-stacked .inputs-list li label { font-weight: normal; padding-top: 0; } .form-stacked div.clearfix.error { padding-top: 10px; padding-bottom: 10px; padding-left: 10px; margin-top: 0; margin-left: -10px; } .form-stacked .actions { margin-left: -20px; padding-left: 20px; } /* * Tables.less * Tables for, you guessed it, tabular data * ---------------------------------------- */ table { width: 100%; margin-bottom: 18px; padding: 0; font-size: 13px; border-collapse: collapse; } table th, table td { padding: 10px 10px 9px; line-height: 18px; text-align: left; } table th { padding-top: 9px; font-weight: bold; vertical-align: middle; } table td { vertical-align: top; border-top: 1px solid #ddd; } table tbody th { border-top: 1px solid #ddd; vertical-align: top; } .condensed-table th, .condensed-table td { padding: 5px 5px 4px; } .bordered-table { border: 1px solid #ddd; border-collapse: separate; *border-collapse: collapse; /* IE7, collapse table to remove spacing */ -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .bordered-table th + th, .bordered-table td + td, .bordered-table th + td { border-left: 1px solid #ddd; } .bordered-table thead tr:first-child th:first-child, .bordered-table tbody tr:first-child td:first-child { -webkit-border-radius: 4px 0 0 0; -moz-border-radius: 4px 0 0 0; border-radius: 4px 0 0 0; } .bordered-table thead tr:first-child th:last-child, .bordered-table tbody tr:first-child td:last-child { -webkit-border-radius: 0 4px 0 0; -moz-border-radius: 0 4px 0 0; border-radius: 0 4px 0 0; } .bordered-table tbody tr:last-child td:first-child { -webkit-border-radius: 0 0 0 4px; -moz-border-radius: 0 0 0 4px; border-radius: 0 0 0 4px; } .bordered-table tbody tr:last-child td:last-child { -webkit-border-radius: 0 0 4px 0; -moz-border-radius: 0 0 4px 0; border-radius: 0 0 4px 0; } table .span1 { width: 20px; } table .span2 { width: 60px; } table .span3 { width: 100px; } table .span4 { width: 140px; } table .span5 { width: 180px; } table .span6 { width: 220px; } table .span7 { width: 260px; } table .span8 { width: 300px; } table .span9 { width: 340px; } table .span10 { width: 380px; } table .span11 { width: 420px; } table .span12 { width: 460px; } table .span13 { width: 500px; } table .span14 { width: 540px; } table .span15 { width: 580px; } table .span16 { width: 620px; } .zebra-striped tbody tr:nth-child(odd) td, .zebra-striped tbody tr:nth-child(odd) th { background-color: #f9f9f9; } .zebra-striped tbody tr:hover td, .zebra-striped tbody tr:hover th { background-color: #f5f5f5; } table .header { cursor: pointer; } table .header:after { content: ""; float: right; margin-top: 7px; border-width: 0 4px 4px; border-style: solid; border-color: #000 transparent; visibility: hidden; } table .headerSortUp, table .headerSortDown { background-color: rgba(141, 192, 219, 0.25); text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); } table .header:hover:after { visibility: visible; } table .headerSortDown:after, table .headerSortDown:hover:after { visibility: visible; filter: alpha(opacity=60); -khtml-opacity: 0.6; -moz-opacity: 0.6; opacity: 0.6; } table .headerSortUp:after { border-bottom: none; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 4px solid #000; visibility: visible; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; filter: alpha(opacity=60); -khtml-opacity: 0.6; -moz-opacity: 0.6; opacity: 0.6; } table .blue { color: #049cdb; border-bottom-color: #049cdb; } table .headerSortUp.blue, table .headerSortDown.blue { background-color: #ade6fe; } table .green { color: #46a546; border-bottom-color: #46a546; } table .headerSortUp.green, table .headerSortDown.green { background-color: #cdeacd; } table .red { color: #9d261d; border-bottom-color: #9d261d; } table .headerSortUp.red, table .headerSortDown.red { background-color: #f4c8c5; } table .yellow { color: #ffc40d; border-bottom-color: #ffc40d; } table .headerSortUp.yellow, table .headerSortDown.yellow { background-color: #fff6d9; } table .orange { color: #f89406; border-bottom-color: #f89406; } table .headerSortUp.orange, table .headerSortDown.orange { background-color: #fee9cc; } table .purple { color: #7a43b6; border-bottom-color: #7a43b6; } table .headerSortUp.purple, table .headerSortDown.purple { background-color: #e2d5f0; } /* Patterns.less * Repeatable UI elements outside the base styles provided from the scaffolding * ---------------------------------------------------------------------------- */ .topbar { height: 40px; position: fixed; top: 0; left: 0; right: 0; z-index: 10000; overflow: visible; } .topbar a { color: #bfbfbf; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .topbar h3 a:hover, .topbar .brand:hover, .topbar ul .active > a { background-color: #333; background-color: rgba(255, 255, 255, 0.05); color: #ffffff; text-decoration: none; } .topbar h3 { position: relative; } .topbar h3 a, .topbar .brand { float: left; display: block; padding: 8px 20px 12px; margin-left: -20px; color: #ffffff; font-size: 20px; font-weight: 200; line-height: 1; } .topbar p { margin: 0; line-height: 40px; } .topbar p a:hover { background-color: transparent; color: #ffffff; } .topbar form { float: left; margin: 5px 0 0 0; position: relative; filter: alpha(opacity=100); -khtml-opacity: 1; -moz-opacity: 1; opacity: 1; } .topbar form.pull-right { float: right; } .topbar input { background-color: #444; background-color: rgba(255, 255, 255, 0.3); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: normal; font-weight: 13px; line-height: 1; padding: 4px 9px; color: #ffffff; color: rgba(255, 255, 255, 0.75); border: 1px solid #111; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); -webkit-transition: none; -moz-transition: none; -ms-transition: none; -o-transition: none; transition: none; } .topbar input:-moz-placeholder { color: #e6e6e6; } .topbar input::-webkit-input-placeholder { color: #e6e6e6; } .topbar input:hover { background-color: #bfbfbf; background-color: rgba(255, 255, 255, 0.5); color: #ffffff; } .topbar input:focus, .topbar input.focused { outline: 0; background-color: #ffffff; color: #404040; text-shadow: 0 1px 0 #ffffff; border: 0; padding: 5px 10px; -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); } .topbar-inner, .topbar .fill { background-color: #222; background-color: #222222; background-repeat: repeat-x; background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222)); background-image: -moz-linear-gradient(top, #333333, #222222); background-image: -ms-linear-gradient(top, #333333, #222222); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222)); background-image: -webkit-linear-gradient(top, #333333, #222222); background-image: -o-linear-gradient(top, #333333, #222222); background-image: linear-gradient(top, #333333, #222222); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0); -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); } .topbar div > ul, .nav { display: block; float: left; margin: 0 10px 0 0; position: relative; left: 0; } .topbar div > ul > li, .nav > li { display: block; float: left; } .topbar div > ul a, .nav a { display: block; float: none; padding: 10px 10px 11px; line-height: 19px; text-decoration: none; } .topbar div > ul a:hover, .nav a:hover { color: #ffffff; text-decoration: none; } .topbar div > ul .active > a, .nav .active > a { background-color: #222; background-color: rgba(0, 0, 0, 0.5); } .topbar div > ul.secondary-nav, .nav.secondary-nav { float: right; margin-left: 10px; margin-right: 0; } .topbar div > ul.secondary-nav .menu-dropdown, .nav.secondary-nav .menu-dropdown, .topbar div > ul.secondary-nav .dropdown-menu, .nav.secondary-nav .dropdown-menu { right: 0; border: 0; } .topbar div > ul a.menu:hover, .nav a.menu:hover, .topbar div > ul li.open .menu, .nav li.open .menu, .topbar div > ul .dropdown-toggle:hover, .nav .dropdown-toggle:hover, .topbar div > ul .dropdown.open .dropdown-toggle, .nav .dropdown.open .dropdown-toggle { background: #444; background: rgba(255, 255, 255, 0.05); } .topbar div > ul .menu-dropdown, .nav .menu-dropdown, .topbar div > ul .dropdown-menu, .nav .dropdown-menu { background-color: #333; } .topbar div > ul .menu-dropdown a.menu, .nav .menu-dropdown a.menu, .topbar div > ul .dropdown-menu a.menu, .nav .dropdown-menu a.menu, .topbar div > ul .menu-dropdown .dropdown-toggle, .nav .menu-dropdown .dropdown-toggle, .topbar div > ul .dropdown-menu .dropdown-toggle, .nav .dropdown-menu .dropdown-toggle { color: #ffffff; } .topbar div > ul .menu-dropdown a.menu.open, .nav .menu-dropdown a.menu.open, .topbar div > ul .dropdown-menu a.menu.open, .nav .dropdown-menu a.menu.open, .topbar div > ul .menu-dropdown .dropdown-toggle.open, .nav .menu-dropdown .dropdown-toggle.open, .topbar div > ul .dropdown-menu .dropdown-toggle.open, .nav .dropdown-menu .dropdown-toggle.open { background: #444; background: rgba(255, 255, 255, 0.05); } .topbar div > ul .menu-dropdown li a, .nav .menu-dropdown li a, .topbar div > ul .dropdown-menu li a, .nav .dropdown-menu li a { color: #999; text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5); } .topbar div > ul .menu-dropdown li a:hover, .nav .menu-dropdown li a:hover, .topbar div > ul .dropdown-menu li a:hover, .nav .dropdown-menu li a:hover { background-color: #191919; background-repeat: repeat-x; background-image: -khtml-gradient(linear, left top, left bottom, from(#292929), to(#191919)); background-image: -moz-linear-gradient(top, #292929, #191919); background-image: -ms-linear-gradient(top, #292929, #191919); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #292929), color-stop(100%, #191919)); background-image: -webkit-linear-gradient(top, #292929, #191919); background-image: -o-linear-gradient(top, #292929, #191919); background-image: linear-gradient(top, #292929, #191919); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#292929', endColorstr='#191919', GradientType=0); color: #ffffff; } .topbar div > ul .menu-dropdown .active a, .nav .menu-dropdown .active a, .topbar div > ul .dropdown-menu .active a, .nav .dropdown-menu .active a { color: #ffffff; } .topbar div > ul .menu-dropdown .divider, .nav .menu-dropdown .divider, .topbar div > ul .dropdown-menu .divider, .nav .dropdown-menu .divider { background-color: #222; border-color: #444; } .topbar ul .menu-dropdown li a, .topbar ul .dropdown-menu li a { padding: 4px 15px; } li.menu, .dropdown { position: relative; } a.menu:after, .dropdown-toggle:after { width: 0; height: 0; display: inline-block; content: "↓"; text-indent: -99999px; vertical-align: top; margin-top: 8px; margin-left: 4px; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 4px solid #ffffff; filter: alpha(opacity=50); -khtml-opacity: 0.5; -moz-opacity: 0.5; opacity: 0.5; } .menu-dropdown, .dropdown-menu { background-color: #ffffff; float: left; display: none; position: absolute; top: 40px; z-index: 900; min-width: 160px; max-width: 220px; _width: 160px; margin-left: 0; margin-right: 0; padding: 6px 0; zoom: 1; border-color: #999; border-color: rgba(0, 0, 0, 0.2); border-style: solid; border-width: 0 1px 1px; -webkit-border-radius: 0 0 6px 6px; -moz-border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px; -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); -moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); -webkit-background-clip: padding-box; -moz-background-clip: padding-box; background-clip: padding-box; } .menu-dropdown li, .dropdown-menu li { float: none; display: block; background-color: none; } .menu-dropdown .divider, .dropdown-menu .divider { height: 1px; margin: 5px 0; overflow: hidden; background-color: #eee; border-bottom: 1px solid #ffffff; } .topbar .dropdown-menu a, .dropdown-menu a { display: block; padding: 4px 15px; clear: both; font-weight: normal; line-height: 18px; color: #808080; text-shadow: 0 1px 0 #ffffff; } .topbar .dropdown-menu a:hover, .dropdown-menu a:hover, .topbar .dropdown-menu a.hover, .dropdown-menu a.hover { background-color: #dddddd; background-repeat: repeat-x; background-image: -khtml-gradient(linear, left top, left bottom, from(#eeeeee), to(#dddddd)); background-image: -moz-linear-gradient(top, #eeeeee, #dddddd); background-image: -ms-linear-gradient(top, #eeeeee, #dddddd); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #eeeeee), color-stop(100%, #dddddd)); background-image: -webkit-linear-gradient(top, #eeeeee, #dddddd); background-image: -o-linear-gradient(top, #eeeeee, #dddddd); background-image: linear-gradient(top, #eeeeee, #dddddd); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#dddddd', GradientType=0); color: #404040; text-decoration: none; -webkit-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.025), inset 0 -1px rgba(0, 0, 0, 0.025); -moz-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.025), inset 0 -1px rgba(0, 0, 0, 0.025); box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.025), inset 0 -1px rgba(0, 0, 0, 0.025); } .open .menu, .dropdown.open .menu, .open .dropdown-toggle, .dropdown.open .dropdown-toggle { color: #ffffff; background: #ccc; background: rgba(0, 0, 0, 0.3); } .open .menu-dropdown, .dropdown.open .menu-dropdown, .open .dropdown-menu, .dropdown.open .dropdown-menu { display: block; } .tabs, .pills { margin: 0 0 18px; padding: 0; list-style: none; zoom: 1; } .tabs:before, .pills:before, .tabs:after, .pills:after { display: table; content: ""; zoom: 1; } .tabs:after, .pills:after { clear: both; } .tabs > li, .pills > li { float: left; } .tabs > li > a, .pills > li > a { display: block; } .tabs { border-color: #ddd; border-style: solid; border-width: 0 0 1px; } .tabs > li { position: relative; margin-bottom: -1px; } .tabs > li > a { padding: 0 15px; margin-right: 2px; line-height: 34px; border: 1px solid transparent; -webkit-border-radius: 4px 4px 0 0; -moz-border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0; } .tabs > li > a:hover { text-decoration: none; background-color: #eee; border-color: #eee #eee #ddd; } .tabs .active > a, .tabs .active > a:hover { color: #808080; background-color: #ffffff; border: 1px solid #ddd; border-bottom-color: transparent; cursor: default; } .tabs .menu-dropdown, .tabs .dropdown-menu { top: 35px; border-width: 1px; -webkit-border-radius: 0 6px 6px 6px; -moz-border-radius: 0 6px 6px 6px; border-radius: 0 6px 6px 6px; } .tabs a.menu:after, .tabs .dropdown-toggle:after { border-top-color: #999; margin-top: 15px; margin-left: 5px; } .tabs li.open.menu .menu, .tabs .open.dropdown .dropdown-toggle { border-color: #999; } .tabs li.open a.menu:after, .tabs .dropdown.open .dropdown-toggle:after { border-top-color: #555; } .pills a { margin: 5px 3px 5px 0; padding: 0 15px; line-height: 30px; text-shadow: 0 1px 1px #ffffff; -webkit-border-radius: 15px; -moz-border-radius: 15px; border-radius: 15px; } .pills a:hover { color: #ffffff; text-decoration: none; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.25); background-color: #00438a; } .pills .active a { color: #ffffff; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.25); background-color: #0069d6; } .pills-vertical > li { float: none; } .tab-content > .tab-pane, .pill-content > .pill-pane, .tab-content > div, .pill-content > div { display: none; } .tab-content > .active, .pill-content > .active { display: block; } .breadcrumb { padding: 7px 14px; margin: 0 0 18px; background-color: #f5f5f5; background-repeat: repeat-x; background-image: -khtml-gradient(linear, left top, left bottom, from(#ffffff), to(#f5f5f5)); background-image: -moz-linear-gradient(top, #ffffff, #f5f5f5); background-image: -ms-linear-gradient(top, #ffffff, #f5f5f5); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #f5f5f5)); background-image: -webkit-linear-gradient(top, #ffffff, #f5f5f5); background-image: -o-linear-gradient(top, #ffffff, #f5f5f5); background-image: linear-gradient(top, #ffffff, #f5f5f5); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0); border: 1px solid #ddd; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: inset 0 1px 0 #ffffff; -moz-box-shadow: inset 0 1px 0 #ffffff; box-shadow: inset 0 1px 0 #ffffff; } .breadcrumb li { display: inline; text-shadow: 0 1px 0 #ffffff; } .breadcrumb .divider { padding: 0 5px; color: #bfbfbf; } .breadcrumb .active a { color: #404040; } .hero-unit { background-color: #f5f5f5; margin-bottom: 30px; padding: 60px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; } .hero-unit h1 { margin-bottom: 0; font-size: 60px; line-height: 1; letter-spacing: -1px; } .hero-unit p { font-size: 18px; font-weight: 200; line-height: 27px; } footer { margin-top: 17px; padding-top: 17px; border-top: 1px solid #eee; } .page-header { margin-bottom: 17px; border-bottom: 1px solid #ddd; -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); } .page-header h1 { margin-bottom: 8px; } .btn.danger, .alert-message.danger, .btn.danger:hover, .alert-message.danger:hover, .btn.error, .alert-message.error, .btn.error:hover, .alert-message.error:hover, .btn.success, .alert-message.success, .btn.success:hover, .alert-message.success:hover, .btn.info, .alert-message.info, .btn.info:hover, .alert-message.info:hover { color: #ffffff; } .btn .close, .alert-message .close { font-family: Arial, sans-serif; line-height: 18px; } .btn.danger, .alert-message.danger, .btn.error, .alert-message.error { background-color: #c43c35; background-repeat: repeat-x; background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35)); background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35)); background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); background-image: linear-gradient(top, #ee5f5b, #c43c35); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0); text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); border-color: #c43c35 #c43c35 #882a25; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); } .btn.success, .alert-message.success { background-color: #57a957; background-repeat: repeat-x; background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957)); background-image: -moz-linear-gradient(top, #62c462, #57a957); background-image: -ms-linear-gradient(top, #62c462, #57a957); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957)); background-image: -webkit-linear-gradient(top, #62c462, #57a957); background-image: -o-linear-gradient(top, #62c462, #57a957); background-image: linear-gradient(top, #62c462, #57a957); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0); text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); border-color: #57a957 #57a957 #3d773d; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); } .btn.info, .alert-message.info { background-color: #339bb9; background-repeat: repeat-x; background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9)); background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); background-image: -ms-linear-gradient(top, #5bc0de, #339bb9); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9)); background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); background-image: -o-linear-gradient(top, #5bc0de, #339bb9); background-image: linear-gradient(top, #5bc0de, #339bb9); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0); text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); border-color: #339bb9 #339bb9 #22697d; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); } .btn { cursor: pointer; display: inline-block; background-color: #e6e6e6; background-repeat: no-repeat; background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(25%, #ffffff), to(#e6e6e6)); background-image: -webkit-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); background-image: -moz-linear-gradient(top, #ffffff, #ffffff 25%, #e6e6e6); background-image: -ms-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); background-image: -o-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); background-image: linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); padding: 5px 14px 6px; text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); color: #333; font-size: 13px; line-height: normal; border: 1px solid #ccc; border-bottom-color: #bbb; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -webkit-transition: 0.1s linear all; -moz-transition: 0.1s linear all; -ms-transition: 0.1s linear all; -o-transition: 0.1s linear all; transition: 0.1s linear all; } .btn:hover { background-position: 0 -15px; color: #333; text-decoration: none; } .btn:focus { outline: 1px dotted #666; } .btn.primary { color: #ffffff; background-color: #0064cd; background-repeat: repeat-x; background-image: -khtml-gradient(linear, left top, left bottom, from(#049cdb), to(#0064cd)); background-image: -moz-linear-gradient(top, #049cdb, #0064cd); background-image: -ms-linear-gradient(top, #049cdb, #0064cd); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #049cdb), color-stop(100%, #0064cd)); background-image: -webkit-linear-gradient(top, #049cdb, #0064cd); background-image: -o-linear-gradient(top, #049cdb, #0064cd); background-image: linear-gradient(top, #049cdb, #0064cd); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#049cdb', endColorstr='#0064cd', GradientType=0); text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); border-color: #0064cd #0064cd #003f81; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); } .btn.active, .btn:active { -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); } .btn.disabled { cursor: default; background-image: none; filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); filter: alpha(opacity=65); -khtml-opacity: 0.65; -moz-opacity: 0.65; opacity: 0.65; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; } .btn[disabled] { cursor: default; background-image: none; filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); filter: alpha(opacity=65); -khtml-opacity: 0.65; -moz-opacity: 0.65; opacity: 0.65; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; } .btn.large { font-size: 15px; line-height: normal; padding: 9px 14px 9px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; } .btn.small { padding: 7px 9px 7px; font-size: 11px; } :root .alert-message, :root .btn { border-radius: 0 \0; } button.btn::-moz-focus-inner, input[type=submit].btn::-moz-focus-inner { padding: 0; border: 0; } .close { float: right; color: #000000; font-size: 20px; font-weight: bold; line-height: 13.5px; text-shadow: 0 1px 0 #ffffff; filter: alpha(opacity=25); -khtml-opacity: 0.25; -moz-opacity: 0.25; opacity: 0.25; } .close:hover { color: #000000; text-decoration: none; filter: alpha(opacity=40); -khtml-opacity: 0.4; -moz-opacity: 0.4; opacity: 0.4; } .alert-message { position: relative; padding: 7px 15px; margin-bottom: 18px; color: #404040; background-color: #eedc94; background-repeat: repeat-x; background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94)); background-image: -moz-linear-gradient(top, #fceec1, #eedc94); background-image: -ms-linear-gradient(top, #fceec1, #eedc94); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94)); background-image: -webkit-linear-gradient(top, #fceec1, #eedc94); background-image: -o-linear-gradient(top, #fceec1, #eedc94); background-image: linear-gradient(top, #fceec1, #eedc94); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0); text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); border-color: #eedc94 #eedc94 #e4c652; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); border-width: 1px; border-style: solid; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); } .alert-message .close { margin-top: 1px; *margin-top: 0; } .alert-message a { font-weight: bold; color: #404040; } .alert-message.danger p a, .alert-message.error p a, .alert-message.success p a, .alert-message.info p a { color: #ffffff; } .alert-message h5 { line-height: 18px; } .alert-message p { margin-bottom: 0; } .alert-message div { margin-top: 5px; margin-bottom: 2px; line-height: 28px; } .alert-message .btn { -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); } .alert-message.block-message { background-image: none; background-color: #fdf5d9; filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); padding: 14px; border-color: #fceec1; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; } .alert-message.block-message ul, .alert-message.block-message p { margin-right: 30px; } .alert-message.block-message ul { margin-bottom: 0; } .alert-message.block-message li { color: #404040; } .alert-message.block-message .alert-actions { margin-top: 5px; } .alert-message.block-message.error, .alert-message.block-message.success, .alert-message.block-message.info { color: #404040; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); } .alert-message.block-message.error { background-color: #fddfde; border-color: #fbc7c6; } .alert-message.block-message.success { background-color: #d1eed1; border-color: #bfe7bf; } .alert-message.block-message.info { background-color: #ddf4fb; border-color: #c6edf9; } .alert-message.block-message.danger p a, .alert-message.block-message.error p a, .alert-message.block-message.success p a, .alert-message.block-message.info p a { color: #404040; } .pagination { height: 36px; margin: 18px 0; } .pagination ul { float: left; margin: 0; border: 1px solid #ddd; border: 1px solid rgba(0, 0, 0, 0.15); -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); } .pagination li { display: inline; } .pagination a { float: left; padding: 0 14px; line-height: 34px; border-right: 1px solid; border-right-color: #ddd; border-right-color: rgba(0, 0, 0, 0.15); *border-right-color: #ddd; /* IE6-7 */ text-decoration: none; } .pagination a:hover, .pagination .active a { background-color: #c7eefe; } .pagination .disabled a, .pagination .disabled a:hover { background-color: transparent; color: #bfbfbf; } .pagination .next a { border: 0; } .well { background-color: #f5f5f5; margin-bottom: 20px; padding: 19px; min-height: 20px; border: 1px solid #eee; border: 1px solid rgba(0, 0, 0, 0.05); -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); } .well blockquote { border-color: #ddd; border-color: rgba(0, 0, 0, 0.15); } .modal-backdrop { background-color: #000000; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 10000; } .modal-backdrop.fade { opacity: 0; } .modal-backdrop, .modal-backdrop.fade.in { filter: alpha(opacity=80); -khtml-opacity: 0.8; -moz-opacity: 0.8; opacity: 0.8; } .modal { position: fixed; top: 50%; left: 50%; z-index: 11000; width: 560px; margin: -250px 0 0 -280px; background-color: #ffffff; border: 1px solid #999; border: 1px solid rgba(0, 0, 0, 0.3); *border: 1px solid #999; /* IE6-7 */ -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); -webkit-background-clip: padding-box; -moz-background-clip: padding-box; background-clip: padding-box; } .modal .close { margin-top: 7px; } .modal.fade { -webkit-transition: opacity .3s linear, top .3s ease-out; -moz-transition: opacity .3s linear, top .3s ease-out; -ms-transition: opacity .3s linear, top .3s ease-out; -o-transition: opacity .3s linear, top .3s ease-out; transition: opacity .3s linear, top .3s ease-out; top: -25%; } .modal.fade.in { top: 50%; } .modal-header { border-bottom: 1px solid #eee; padding: 5px 15px; } .modal-body { padding: 15px; } .modal-body form { margin-bottom: 0; } .modal-footer { background-color: #f5f5f5; padding: 14px 15px 15px; border-top: 1px solid #ddd; -webkit-border-radius: 0 0 6px 6px; -moz-border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px; -webkit-box-shadow: inset 0 1px 0 #ffffff; -moz-box-shadow: inset 0 1px 0 #ffffff; box-shadow: inset 0 1px 0 #ffffff; zoom: 1; margin-bottom: 0; } .modal-footer:before, .modal-footer:after { display: table; content: ""; zoom: 1; } .modal-footer:after { clear: both; } .modal-footer .btn { float: right; margin-left: 5px; } .modal .popover, .modal .twipsy { z-index: 12000; } .twipsy { display: block; position: absolute; visibility: visible; padding: 5px; font-size: 11px; z-index: 1000; filter: alpha(opacity=80); -khtml-opacity: 0.8; -moz-opacity: 0.8; opacity: 0.8; } .twipsy.fade.in { filter: alpha(opacity=80); -khtml-opacity: 0.8; -moz-opacity: 0.8; opacity: 0.8; } .twipsy.above .twipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 5px solid #000000; } .twipsy.left .twipsy-arrow { top: 50%; right: 0; margin-top: -5px; border-top: 5px solid transparent; border-bottom: 5px solid transparent; border-left: 5px solid #000000; } .twipsy.below .twipsy-arrow { top: 0; left: 50%; margin-left: -5px; border-left: 5px solid transparent; border-right: 5px solid transparent; border-bottom: 5px solid #000000; } .twipsy.right .twipsy-arrow { top: 50%; left: 0; margin-top: -5px; border-top: 5px solid transparent; border-bottom: 5px solid transparent; border-right: 5px solid #000000; } .twipsy-inner { padding: 3px 8px; background-color: #000000; color: white; text-align: center; max-width: 200px; text-decoration: none; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .twipsy-arrow { position: absolute; width: 0; height: 0; } .popover { position: absolute; top: 0; left: 0; z-index: 1000; padding: 5px; display: none; } .popover.above .arrow { bottom: 0; left: 50%; margin-left: -5px; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 5px solid #000000; } .popover.right .arrow { top: 50%; left: 0; margin-top: -5px; border-top: 5px solid transparent; border-bottom: 5px solid transparent; border-right: 5px solid #000000; } .popover.below .arrow { top: 0; left: 50%; margin-left: -5px; border-left: 5px solid transparent; border-right: 5px solid transparent; border-bottom: 5px solid #000000; } .popover.left .arrow { top: 50%; right: 0; margin-top: -5px; border-top: 5px solid transparent; border-bottom: 5px solid transparent; border-left: 5px solid #000000; } .popover .arrow { position: absolute; width: 0; height: 0; } .popover .inner { background: #000000; background: rgba(0, 0, 0, 0.8); padding: 3px; overflow: hidden; width: 280px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); } .popover .title { background-color: #f5f5f5; padding: 9px 15px; line-height: 1; -webkit-border-radius: 3px 3px 0 0; -moz-border-radius: 3px 3px 0 0; border-radius: 3px 3px 0 0; border-bottom: 1px solid #eee; } .popover .content { background-color: #ffffff; padding: 14px; -webkit-border-radius: 0 0 3px 3px; -moz-border-radius: 0 0 3px 3px; border-radius: 0 0 3px 3px; -webkit-background-clip: padding-box; -moz-background-clip: padding-box; background-clip: padding-box; } .popover .content p, .popover .content ul, .popover .content ol { margin-bottom: 0; } .fade { -webkit-transition: opacity 0.15s linear; -moz-transition: opacity 0.15s linear; -ms-transition: opacity 0.15s linear; -o-transition: opacity 0.15s linear; transition: opacity 0.15s linear; opacity: 0; } .fade.in { opacity: 1; } .label { padding: 1px 3px 2px; font-size: 9.75px; font-weight: bold; color: #ffffff; text-transform: uppercase; white-space: nowrap; background-color: #bfbfbf; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } .label.important { background-color: #c43c35; } .label.warning { background-color: #f89406; } .label.success { background-color: #46a546; } .label.notice { background-color: #62cffc; } .media-grid { margin-left: -20px; margin-bottom: 0; zoom: 1; } .media-grid:before, .media-grid:after { display: table; content: ""; zoom: 1; } .media-grid:after { clear: both; } .media-grid li { display: inline; } .media-grid a { float: left; padding: 4px; margin: 0 0 18px 20px; border: 1px solid #ddd; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); } .media-grid a img { display: block; } .media-grid a:hover { border-color: #0069d6; -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); } ansible-1.7.2/docsite/_static/default.css000066400000000000000000000077101241061774000203630ustar00rootroot00000000000000/* * default.css_t * ~~~~~~~~~~~~~ * * Sphinx stylesheet -- default theme. * * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @import url("basic.css"); /* -- page layout ----------------------------------------------------------- */ body { font-family: sans-serif; font-size: 100%; background-color: #11303d; color: #000; margin: 0; padding: 0; } div.document { background-color: #1c4e63; } div.documentwrapper { float: left; width: 100%; } div.bodywrapper { margin: 0 0 0 230px; } div.body { background-color: #ffffff; color: #000000; padding: 0 20px 30px 20px; } div.footer { color: #ffffff; width: 100%; padding: 9px 0 9px 0; text-align: center; font-size: 75%; } div.footer a { color: #ffffff; text-decoration: underline; } div.related { background-color: #133f52; line-height: 30px; color: #ffffff; } div.related a { color: #ffffff; } div.sphinxsidebar { } div.sphinxsidebar h3 { font-family: 'Trebuchet MS', sans-serif; color: #ffffff; font-size: 1.4em; font-weight: normal; margin: 0; padding: 0; } div.sphinxsidebar h3 a { color: #ffffff; } div.sphinxsidebar h4 { font-family: 'Trebuchet MS', sans-serif; color: #ffffff; font-size: 1.3em; font-weight: normal; margin: 5px 0 0 0; padding: 0; } div.sphinxsidebar p { color: #ffffff; } div.sphinxsidebar p.topless { margin: 5px 10px 10px 10px; } div.sphinxsidebar ul { margin: 10px; padding: 0; color: #ffffff; } div.sphinxsidebar a { color: #98dbcc; } div.sphinxsidebar input { border: 1px solid #98dbcc; font-family: sans-serif; font-size: 1em; } /* -- hyperlink styles ------------------------------------------------------ */ a { color: #355f7c; text-decoration: none; } a:visited { color: #355f7c; text-decoration: none; } a:hover { text-decoration: underline; } /* -- body styles ----------------------------------------------------------- */ div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 { font-family: 'Trebuchet MS', sans-serif; background-color: #f2f2f2; font-weight: normal; color: #20435c; border-bottom: 1px solid #ccc; margin: 20px -20px 10px -20px; padding: 3px 0 3px 10px; } div.body h1 { margin-top: 0; font-size: 200%; } div.body h2 { font-size: 160%; } div.body h3 { font-size: 140%; } div.body h4 { font-size: 120%; } div.body h5 { font-size: 110%; } div.body h6 { font-size: 100%; } a.headerlink { color: #c60f0f; font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; } a.headerlink:hover { background-color: #c60f0f; color: white; } div.body p, div.body dd, div.body li { text-align: justify; line-height: 130%; } div.admonition p.admonition-title + p { display: inline; } div.admonition p { margin-bottom: 5px; } div.admonition pre { margin-bottom: 5px; } div.admonition ul, div.admonition ol { margin-bottom: 5px; } div.note { background-color: #eee; border: 1px solid #ccc; } div.seealso { background-color: #ffc; border: 1px solid #ff6; } div.topic { background-color: #eee; } div.warning { background-color: #ffe4e4; border: 1px solid #f66; } p.admonition-title { display: inline; } p.admonition-title:after { content: ":"; } pre { padding: 5px; background-color: #eeffcc; color: #333333; line-height: 120%; border: 1px solid #ac9; border-left: none; border-right: none; } tt { background-color: #ecf0f3; padding: 0 1px 0 1px; font-size: 0.95em; } th { background-color: #ede; } .warning tt { background: #efc2c2; } .note tt { background: #d6d6d6; } .viewcode-back { font-family: sans-serif; } div.viewcode-block:target { background-color: #f4debf; border-top: 1px solid #ac9; border-bottom: 1px solid #ac9; }ansible-1.7.2/docsite/_static/doctools.js000066400000000000000000000152701241061774000204110ustar00rootroot00000000000000/* * doctools.js * ~~~~~~~~~~~ * * Sphinx JavaScript utilities for all documentation. * * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /** * select a different prefix for underscore */ $u = _.noConflict(); /** * make the code below compatible with browsers without * an installed firebug like debugger if (!window.console || !console.firebug) { var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; window.console = {}; for (var i = 0; i < names.length; ++i) window.console[names[i]] = function() {}; } */ /** * small helper function to urldecode strings */ jQuery.urldecode = function(x) { return decodeURIComponent(x).replace(/\+/g, ' '); } /** * small helper function to urlencode strings */ jQuery.urlencode = encodeURIComponent; /** * This function returns the parsed url parameters of the * current request. Multiple values per key are supported, * it will always return arrays of strings for the value parts. */ jQuery.getQueryParameters = function(s) { if (typeof s == 'undefined') s = document.location.search; var parts = s.substr(s.indexOf('?') + 1).split('&'); var result = {}; for (var i = 0; i < parts.length; i++) { var tmp = parts[i].split('=', 2); var key = jQuery.urldecode(tmp[0]); var value = jQuery.urldecode(tmp[1]); if (key in result) result[key].push(value); else result[key] = [value]; } return result; }; /** * small function to check if an array contains * a given item. */ jQuery.contains = function(arr, item) { for (var i = 0; i < arr.length; i++) { if (arr[i] == item) return true; } return false; }; /** * highlight a given string on a jquery object by wrapping it in * span elements with the given class name. */ jQuery.fn.highlightText = function(text, className) { function highlight(node) { if (node.nodeType == 3) { var val = node.nodeValue; var pos = val.toLowerCase().indexOf(text); if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { var span = document.createElement("span"); span.className = className; span.appendChild(document.createTextNode(val.substr(pos, text.length))); node.parentNode.insertBefore(span, node.parentNode.insertBefore( document.createTextNode(val.substr(pos + text.length)), node.nextSibling)); node.nodeValue = val.substr(0, pos); } } else if (!jQuery(node).is("button, select, textarea")) { jQuery.each(node.childNodes, function() { highlight(this); }); } } return this.each(function() { highlight(this); }); }; /** * Small JavaScript module for the documentation. */ var Documentation = { init : function() { this.fixFirefoxAnchorBug(); this.highlightSearchWords(); this.initIndexTable(); }, /** * i18n support */ TRANSLATIONS : {}, PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, LOCALE : 'unknown', // gettext and ngettext don't access this so that the functions // can safely bound to a different name (_ = Documentation.gettext) gettext : function(string) { var translated = Documentation.TRANSLATIONS[string]; if (typeof translated == 'undefined') return string; return (typeof translated == 'string') ? translated : translated[0]; }, ngettext : function(singular, plural, n) { var translated = Documentation.TRANSLATIONS[singular]; if (typeof translated == 'undefined') return (n == 1) ? singular : plural; return translated[Documentation.PLURALEXPR(n)]; }, addTranslations : function(catalog) { for (var key in catalog.messages) this.TRANSLATIONS[key] = catalog.messages[key]; this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); this.LOCALE = catalog.locale; }, /** * add context elements like header anchor links */ addContextElements : function() { $('div[id] > :header:first').each(function() { $('\u00B6'). attr('href', '#' + this.id). attr('title', _('Permalink to this headline')). appendTo(this); }); $('dt[id]').each(function() { $('\u00B6'). attr('href', '#' + this.id). attr('title', _('Permalink to this definition')). appendTo(this); }); }, /** * workaround a firefox stupidity */ fixFirefoxAnchorBug : function() { if (document.location.hash && $.browser.mozilla) window.setTimeout(function() { document.location.href += ''; }, 10); }, /** * highlight the search words provided in the url in the text */ highlightSearchWords : function() { var params = $.getQueryParameters(); var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; if (terms.length) { var body = $('div.body'); window.setTimeout(function() { $.each(terms, function() { body.highlightText(this.toLowerCase(), 'highlighted'); }); }, 10); $('') .appendTo($('#searchbox')); } }, /** * init the domain index toggle buttons */ initIndexTable : function() { var togglers = $('img.toggler').click(function() { var src = $(this).attr('src'); var idnum = $(this).attr('id').substr(7); $('tr.cg-' + idnum).toggle(); if (src.substr(-9) == 'minus.png') $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); else $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); }).css('display', ''); if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { togglers.click(); } }, /** * helper function to hide the search marks again */ hideSearchWords : function() { $('#searchbox .highlight-link').fadeOut(300); $('span.highlighted').removeClass('highlighted'); }, /** * make the url absolute */ makeURL : function(relativeURL) { return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; }, /** * get the current relative url */ getCurrentURL : function() { var path = document.location.pathname; var parts = path.split(/\//); $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { if (this == '..') parts.pop(); }); var url = parts.join('/'); return path.substring(url.lastIndexOf('/') + 1, path.length - 1); } }; // quick alias for translations _ = Documentation.gettext; $(document).ready(function() { Documentation.init(); }); ansible-1.7.2/docsite/_static/favicon.ico000066400000000000000000000004761241061774000203500ustar00rootroot00000000000000(( €õñÿÿ7æúú:õ=õúõT€“Y€ET€•Y€ET€•Y€ETƒ3333ˆ•YIIIIIIET‚""b"(•Y€ET€•Y€Eq€•YˆˆˆˆˆˆESIIIIII5UUUUUUPøøøøøøøøøø€ansible-1.7.2/docsite/_static/file.png000066400000000000000000000006101241061774000176420ustar00rootroot00000000000000‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYs  šœtIMEÕ  )¶TIDAT8Ë­‘±JÄ@†¿Ir('[ "&xØÙYZ ‚Xø0‚!i|†_@±Ô÷•t§ÓDÄæÏ] ¹#¹Äxÿjv˜ùç› Y–ÐN‡ažE‘i«(ŠÌÄÉ™yž£µ@D¦£&±ˆ`Û6®ë–P¦Zk’$)5%"ôz½Ê.NñA#Aœba‘`Vsø¾_3ñc°,«™àä2m¼Ýñþjó [kŸìlv¹y|!IÕ´ðþyô;ÀðvÈé "Œß®°—a©?ŸAúðÄ7Œ`ô˜ñÇc^énôk?¸²Bg}»TЙ¹D#ÁÑÞ "R¹D1÷£çyüEŽRê*ŽãÝ6MJ©3þK_U«t8F~ÇIEND®B`‚ansible-1.7.2/docsite/_static/minus.png000066400000000000000000000003071241061774000200610ustar00rootroot00000000000000‰PNG  IHDR &Îàq pHYs  šœtIME× <®8åtEXtCommentöÌ–¿RIDATÓczô(BÅñãÇáÒpö¿ÿ¨èˆip»‘¹P÷îÝÃc· ¸ |¶IEND®B`‚ansible-1.7.2/docsite/_static/pygments.css000066400000000000000000000075341241061774000206110ustar00rootroot00000000000000.highlight .hll { background-color: #ffffcc } .highlight { background: #eeffcc; } .highlight .c { color: #408090; font-style: italic } /* Comment */ .highlight .err { border: 1px solid #FF0000 } /* Error */ .highlight .k { color: #007020; font-weight: bold } /* Keyword */ .highlight .o { color: #666666 } /* Operator */ .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ .highlight .cp { color: #007020 } /* Comment.Preproc */ .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #A00000 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #FF0000 } /* Generic.Error */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ .highlight .gi { color: #00A000 } /* Generic.Inserted */ .highlight .go { color: #303030 } /* Generic.Output */ .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ .highlight .gt { color: #0040D0 } /* Generic.Traceback */ .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #007020 } /* Keyword.Pseudo */ .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #902000 } /* Keyword.Type */ .highlight .m { color: #208050 } /* Literal.Number */ .highlight .s { color: #4070a0 } /* Literal.String */ .highlight .na { color: #4070a0 } /* Name.Attribute */ .highlight .nb { color: #007020 } /* Name.Builtin */ .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ .highlight .no { color: #60add5 } /* Name.Constant */ .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ .highlight .ne { color: #007020 } /* Name.Exception */ .highlight .nf { color: #06287e } /* Name.Function */ .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #bb60d5 } /* Name.Variable */ .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mf { color: #208050 } /* Literal.Number.Float */ .highlight .mh { color: #208050 } /* Literal.Number.Hex */ .highlight .mi { color: #208050 } /* Literal.Number.Integer */ .highlight .mo { color: #208050 } /* Literal.Number.Oct */ .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ .highlight .sc { color: #4070a0 } /* Literal.String.Char */ .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ .highlight .sx { color: #c65d09 } /* Literal.String.Other */ .highlight .sr { color: #235388 } /* Literal.String.Regex */ .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ .highlight .ss { color: #517918 } /* Literal.String.Symbol */ .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ansible-1.7.2/docsite/_static/searchtools.js000066400000000000000000000372531241061774000211160ustar00rootroot00000000000000/* * searchtools.js_t * ~~~~~~~~~~~~~~~~ * * Sphinx JavaScript utilties for the full-text search. * * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /** * helper function to return a node containing the * search summary for a given text. keywords is a list * of stemmed words, hlwords is the list of normal, unstemmed * words. the first one is used to find the occurance, the * latter for highlighting it. */ jQuery.makeSearchSummary = function(text, keywords, hlwords) { var textLower = text.toLowerCase(); var start = 0; $.each(keywords, function() { var i = textLower.indexOf(this.toLowerCase()); if (i > -1) start = i; }); start = Math.max(start - 120, 0); var excerpt = ((start > 0) ? '...' : '') + $.trim(text.substr(start, 240)) + ((start + 240 - text.length) ? '...' : ''); var rv = $('
').text(excerpt); $.each(hlwords, function() { rv = rv.highlightText(this, 'highlighted'); }); return rv; } /** * Porter Stemmer */ var Stemmer = function() { var step2list = { ational: 'ate', tional: 'tion', enci: 'ence', anci: 'ance', izer: 'ize', bli: 'ble', alli: 'al', entli: 'ent', eli: 'e', ousli: 'ous', ization: 'ize', ation: 'ate', ator: 'ate', alism: 'al', iveness: 'ive', fulness: 'ful', ousness: 'ous', aliti: 'al', iviti: 'ive', biliti: 'ble', logi: 'log' }; var step3list = { icate: 'ic', ative: '', alize: 'al', iciti: 'ic', ical: 'ic', ful: '', ness: '' }; var c = "[^aeiou]"; // consonant var v = "[aeiouy]"; // vowel var C = c + "[^aeiouy]*"; // consonant sequence var V = v + "[aeiou]*"; // vowel sequence var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 var s_v = "^(" + C + ")?" + v; // vowel in stem this.stemWord = function (w) { var stem; var suffix; var firstch; var origword = w; if (w.length < 3) return w; var re; var re2; var re3; var re4; firstch = w.substr(0,1); if (firstch == "y") w = firstch.toUpperCase() + w.substr(1); // Step 1a re = /^(.+?)(ss|i)es$/; re2 = /^(.+?)([^s])s$/; if (re.test(w)) w = w.replace(re,"$1$2"); else if (re2.test(w)) w = w.replace(re2,"$1$2"); // Step 1b re = /^(.+?)eed$/; re2 = /^(.+?)(ed|ing)$/; if (re.test(w)) { var fp = re.exec(w); re = new RegExp(mgr0); if (re.test(fp[1])) { re = /.$/; w = w.replace(re,""); } } else if (re2.test(w)) { var fp = re2.exec(w); stem = fp[1]; re2 = new RegExp(s_v); if (re2.test(stem)) { w = stem; re2 = /(at|bl|iz)$/; re3 = new RegExp("([^aeiouylsz])\\1$"); re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); if (re2.test(w)) w = w + "e"; else if (re3.test(w)) { re = /.$/; w = w.replace(re,""); } else if (re4.test(w)) w = w + "e"; } } // Step 1c re = /^(.+?)y$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(s_v); if (re.test(stem)) w = stem + "i"; } // Step 2 re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; suffix = fp[2]; re = new RegExp(mgr0); if (re.test(stem)) w = stem + step2list[suffix]; } // Step 3 re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; suffix = fp[2]; re = new RegExp(mgr0); if (re.test(stem)) w = stem + step3list[suffix]; } // Step 4 re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; re2 = /^(.+?)(s|t)(ion)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(mgr1); if (re.test(stem)) w = stem; } else if (re2.test(w)) { var fp = re2.exec(w); stem = fp[1] + fp[2]; re2 = new RegExp(mgr1); if (re2.test(stem)) w = stem; } // Step 5 re = /^(.+?)e$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(mgr1); re2 = new RegExp(meq1); re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) w = stem; } re = /ll$/; re2 = new RegExp(mgr1); if (re.test(w) && re2.test(w)) { re = /.$/; w = w.replace(re,""); } // and turn initial Y back to y if (firstch == "y") w = firstch.toLowerCase() + w.substr(1); return w; } } /** * Search Module */ var Search = { _index : null, _queued_query : null, _pulse_status : -1, init : function() { var params = $.getQueryParameters(); if (params.q) { var query = params.q[0]; $('input[name="q"]')[0].value = query; this.performSearch(query); } }, loadIndex : function(url) { $.ajax({type: "GET", url: url, data: null, success: null, dataType: "script", cache: true}); }, setIndex : function(index) { var q; this._index = index; if ((q = this._queued_query) !== null) { this._queued_query = null; Search.query(q); } }, hasIndex : function() { return this._index !== null; }, deferQuery : function(query) { this._queued_query = query; }, stopPulse : function() { this._pulse_status = 0; }, startPulse : function() { if (this._pulse_status >= 0) return; function pulse() { Search._pulse_status = (Search._pulse_status + 1) % 4; var dotString = ''; for (var i = 0; i < Search._pulse_status; i++) dotString += '.'; Search.dots.text(dotString); if (Search._pulse_status > -1) window.setTimeout(pulse, 500); }; pulse(); }, /** * perform a search for something */ performSearch : function(query) { // create the required interface elements this.out = $('#search-results'); this.title = $('

' + _('Searching') + '

').appendTo(this.out); this.dots = $('').appendTo(this.title); this.status = $('

').appendTo(this.out); this.output = $('