Compare commits

..

69 Commits

Author SHA1 Message Date
cb4b196288 Version bump for 1.6.5 2014-06-25 21:10:25 -05:00
8ed484c544 Additional fixes for safe_eval 2014-06-25 21:07:41 -05:00
cc4129f6a1 Version bump for 1.6.4 2014-06-25 14:20:46 -05:00
c35bbdaa21 Assert the MOCK_CFG exists for the mock-rpm build target 2014-06-25 14:15:31 -05:00
84c40fc111 Add support for rpm builds through mock 2014-06-25 14:15:26 -05:00
2c6c1b99c7 Correct Makefile variable usage 2014-06-25 14:02:58 -05:00
2aa7ce006f Updated DEB build workflow
Updates to Makefile include:
 * add targets: deb-src, deb-src-upload, deb-upload
 * add variables to control DEB building: DEBUILD_OPTS, DPUT_OPTS, DEB_PPA, DEB_DIST, DEB_RELEASE
 * create deb files for all release values in DEB_DIST

Several updates to packaging/debian/*
 * Updated control file
 * Whitespace/formatting of changelog

Add deb-build to .gitignore
2014-06-25 14:02:46 -05:00
b8b96b2109 Change safe_eval to a strict white list 2014-06-25 14:00:49 -05:00
dffea7f877 Version bump and CHANGELOG/RELEASES update for 1.6.3 2014-06-09 14:30:07 -05:00
7059528059 Cleaning up svr4pkg commit fix for #7645 2014-06-09 14:14:13 -05:00
fadf02d0c6 fix for svr4pkg module failure reporting, issue #7645 2014-06-09 14:14:09 -05:00
3ebecdd1ed Fixing mysql master replication boolean
Fixes #7528
2014-06-09 14:14:06 -05:00
58a0bcbe51 Fix issue with symlink path detection
Fixes #7627
Fixes #7664
2014-06-09 14:14:02 -05:00
10074d3622 Fix linking issue to directories in file module
The os.path.isdir() returns True for symlinks that point to directories,
so we also need to check to make sure it's not a symlink too.

Fixes #7657
2014-06-09 14:13:55 -05:00
2625196f5d Fix error passing play vars to an included playbook with empty vars
Fixes #7658
2014-06-09 14:13:50 -05:00
e85a9abe75 Fix order of merging variables for the combined cache
Fixes #7598
2014-06-09 14:13:18 -05:00
b99ea2723a Removing cruft leftover from the deprecation of include+with_items
Also cleaning up integration tests that had checks for the empty item
attribute in certain results.

Fixes #7535
2014-06-09 14:11:21 -05:00
7cb7fdc2a7 fixing problem where ansible would error out because Amazon was saying the group didnt exist yet (needed to wait a few more seconds for amazon to propagate correctly) 2014-06-09 14:11:12 -05:00
936e1de18b Fix error when using os.getlogin() without a tty 2014-06-09 14:11:08 -05:00
c4b6c0ab84 Fix typo in CHANGE MASTER TO syntax 2014-06-09 14:11:05 -05:00
4dd5eeb1c4 Ensure there are no duplicates in the merged/intersected lists 2014-06-09 14:11:01 -05:00
d8c8c0823a Merge and intersect lists without using sets.
Using sets for these operations is dangerous because sets cannot contain
certain object types (such as lists) and their iteration order is
undefined.

Fixes #7596
2014-06-09 14:10:57 -05:00
3801be693b dont mutate inventory vars 2014-06-09 14:10:53 -05:00
75adb3978b Check groupnames for None as well as an empty string in add_host
Fixes #7585
2014-06-09 14:10:48 -05:00
4e4ffa669a Correctly examine path for relative links in file module
Fixes #7515
Fixes #7537
2014-06-09 14:10:44 -05:00
ce80c0b8af Support checking for su user to atomic_move
Fixes #7553
2014-06-09 14:10:40 -05:00
b50a64b0a1 Correct issue of handlers running on all hosts incorrectly
Also adds an integration test to catch this bug in the future.

Fixes #7559
2014-06-09 14:10:35 -05:00
adfbcb8760 now module searches for update-alternatives vs hardcoding it 2014-06-09 14:10:29 -05:00
5128bced6b Don't use listify_ function, when all we want to do is template variables
This was causing a bug in the env module, due to the fact that we now
pass variables for the module through the templating engine combined
with the fact that we split-up the hostvars and setup variables. As a
result, if a variable in the env lookup had the same name as the variable
in Ansible, it would try and template itself over and over again until
the recursion limit would be hit, at which time an empty string was
returned.

Fixes #7396
2014-06-09 14:10:24 -05:00
549f67c0d8 Merge pull request #7527 from hlieberman/release1.6.2
Remove colon which breaks installation of 1.6.2.
2014-05-25 13:06:39 -04:00
d98b6ae8ab Remove colon which breaks installation of 1.6.2.
Rework the description so that it doesn't require the colon, rather
than just wrapping it in quotes.
2014-05-23 20:15:18 -04:00
ce4883bcc5 Version bump for 1.6.2 2014-05-23 15:37:57 -05:00
a75a84b44a Don't re-query inventory when trimming failed/dark hosts
Since the filter list contains hosts, passing that back to list_hosts()
in the inventoy causes issues when the hostname is an IPv6 address
(with :'s interpreted as group unions). Since we already have the list
of hosts, we should not need to pass that back through inventory a
second time.

Fixes #7446
2014-05-23 15:28:42 -05:00
f132e99b2a Adding the capability to proxy the ssl cert check
The ssl cert check will now respect the http and https proxy
environment settings. The url may also have the username/password
embedded, in which case basic auth will be used to connect to the
proxy server.

Fixes #7413
2014-05-23 15:27:05 -05:00
4d0ce5bd41 Make sure dwim'd relative path ends in a "/" if the original does
Fixes #7296
2014-05-23 15:17:43 -05:00
b01da1b780 Ensure the validation string has %s in it 2014-05-21 16:16:48 -05:00
1248d2ce8a Fixing absolute path calculation for file module when linking
Fixes #7403
2014-05-21 15:00:21 -05:00
d72cd70cc8 Also set the environment variables when resetting the locale to C 2014-05-21 15:00:05 -05:00
362626d07c Default use_proxy to True for fetch_url()
Also added some error handling to the fetch_url() call in the
apt_repository module, so that failures to look up the PPA info
are properly handled.

Fixes #7322
2014-05-21 14:59:58 -05:00
a54b8764fa Reset locale to 'C' if the specified one is invalid
Fixes #7448
2014-05-21 14:59:51 -05:00
6b4584d004 Remove erroneous set of status_code causing a traceback in module uri
Fixes #7416
2014-05-21 14:59:43 -05:00
cb0842ab49 docker: fix targetting images by name 2014-05-21 14:59:32 -05:00
2432b45eb1 Fixed extension filtering in InventoryDirectory 2014-05-21 14:59:29 -05:00
d6214c5d56 Check module_path permissions when creating ssh_wrapper for git
If the module directory is not writable/executable to the current user
(most likely because of a sudo to a non-root user), the ssh_wrapper
will be created in the default location for mkstemp() calls. To facilitate
the deletion of these new files, a new mechanism for cleaning up files
created by the module was also added.

Fixes #7375
2014-05-21 14:59:20 -05:00
c5b6d23c63 During vsphere config check attempt cast before marking values missing
Fixes #7385
2014-05-21 14:59:13 -05:00
e83f14200c Fix env splitting in docker module
ENV variable value could contain '=' (for example mysql://host/db?pool=10)
2014-05-21 14:59:05 -05:00
7c0431b1e4 Add missing basedir to Runner in _do_setup_step 2014-05-21 14:58:58 -05:00
1c5055a401 Properly merge role conditionals in with pre-existing conditionals
Fixes #7387
2014-05-21 14:58:49 -05:00
24d885e368 Fix to unescape * was discarded by unescape of @
`decoded_name` was created twice, each from `rset.name`

So, the second call to `.replace(r'\100', '@')` overwrites decoded_name, discarding the result of the call to `.replace(r'\052', '*')`

I had a problem with wildcard domains that was fixed by this patch.
2014-05-21 14:57:23 -05:00
8851ceaa9e Use the existing module_vars during the templating of module_vars
Since some of the vars contained in there may be used in the templating
of other variables. This also reverts e83a494 which originally fixed
issue #6979 but broke some other variable related things.

Fixes #6979
Fixes #7321
Fixes #7332
2014-05-21 14:56:59 -05:00
854bf14222 Evaluate changed_when only if task is not skipped
Fixes #7405
2014-05-21 14:55:45 -05:00
d8526a6c80 Only chown on atomic move if the uid/gid don't match the src/tmp file
This is a corner case for remote file systems that don't support
chown() and where the source and destination for the atomic_move
are on that remote file system.

Fixes #7372
2014-05-21 14:55:39 -05:00
e0fe6ca5d8 Use utils.combine_vars on vars_files data
Fixes #7345
2014-05-21 14:55:35 -05:00
ca2a12aa5b Pass vars_files on to included playbooks too
Fixes #7384
2014-05-21 14:55:29 -05:00
29018cf2a7 Correctly initialize combined_cache for hosts if setup is skipped
Fixes #7364
2014-05-21 14:55:24 -05:00
9d8eee633d Make sure the docker data has a "Names" field before using it
Fixes #7363
2014-05-21 14:55:20 -05:00
8cc71a6eec Do not base synchronize source on the inventory directory 2014-05-21 14:55:01 -05:00
3565249471 Fix: Remove check for Ghost state
This fixed the just committed change handling non existent Ghost state.
2014-05-21 14:53:39 -05:00
595813a1fe Remove check for Ghost state
This doesn't exist anymore and causes ansible to throw a KeyError
2014-05-21 14:53:34 -05:00
0de306574e rds module: Fix undeclared reference to "params" when setting password in
modify mode.
2014-05-21 14:53:28 -05:00
d33486d52a ec2: Fix bug with running/stopped state and wait=yes.
If `get_all_instances` returns multiple reservations, the old wait loop only
dealt with the first reservation. Thus, the wait loop may end before all
instances get to be running/stopped.

Also clean up the code a little.
2014-05-21 14:53:23 -05:00
0dabb37337 Make sure the default ec2_group egress rule is not removed
Upon a second run, the default egress rule will be removed when a
vpc is specified but no other egress rules were set. This patch
corrects that behavior by removing the default egress rule from the
list of unmatched outbound rules.

Fixes #7309
2014-05-21 14:53:18 -05:00
9a930fb481 Add pyc/pyo to ignore list for inventory directories
Fixes #7308
2014-05-21 14:53:09 -05:00
d4e11c5c69 Version bump for 1.6.1 release 2014-05-07 12:33:07 -05:00
08f4984d92 Add integration tests for group_by module. Fixed bug introduced by ansible/ansible#7273 while also fixing issue described in ansible/ansible#6953 2014-05-07 09:12:30 -05:00
7daaabdedb Close fds when running commands from the accelerate daemon
Fixes #7307
2014-05-07 08:26:06 -05:00
9943c50863 Make sure distro variable is set if python-apt is installed
Fixes #7295
2014-05-07 08:25:58 -05:00
ce15813e70 made enabled/disabled checks of apache2_module workable 2014-05-07 08:25:50 -05:00
f05d457560 Updating changlog and releases for 1.6 2014-05-05 16:46:31 -05:00
6110 changed files with 126580 additions and 523998 deletions

View File

@ -1,251 +0,0 @@
trigger:
batch: true
branches:
include:
- devel
- stable-*
pr:
autoCancel: true
branches:
include:
- devel
- stable-*
schedules:
- cron: 0 7 * * *
displayName: Nightly
always: true
branches:
include:
- devel
- stable-*
variables:
- name: checkoutPath
value: ansible
- name: coverageBranches
value: devel
- name: entryPoint
value: test/utils/shippable/shippable.sh
- name: fetchDepth
value: 500
resources:
containers:
- container: default
image: quay.io/ansible/azure-pipelines-test-container:1.9.0
pool: Standard
stages:
- stage: Sanity
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
- test: 5
- stage: Units
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: units/{0}
targets:
- test: 2.6
- test: 2.7
- test: 3.5
- test: 3.6
- test: 3.7
- test: 3.8
- test: 3.9
- test: '3.10'
- stage: Windows
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Server {0}
testFormat: windows/{0}/1
targets:
- test: 2012
- test: 2012-R2
- test: 2016
- test: 2019
- test: 2022
- stage: Remote
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: macOS 11.1
test: macos/11.1
- name: RHEL 7.9
test: rhel/7.9
- name: RHEL 8.4 py36
test: rhel/8.4@3.6
- name: RHEL 8.4 py38
test: rhel/8.4@3.8
- name: FreeBSD 12.2
test: freebsd/12.2
- name: FreeBSD 13.0
test: freebsd/13.0
groups:
- 1
- 2
- 3
- 4
- 5
- stage: Docker
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: linux/{0}
targets:
- name: Alpine 3
test: alpine3
- name: CentOS 6
test: centos6
- name: CentOS 7
test: centos7
- name: Fedora 33
test: fedora33
- name: Fedora 34
test: fedora34
- name: openSUSE 15 py2
test: opensuse15py2
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 18.04
test: ubuntu1804
- name: Ubuntu 20.04
test: ubuntu2004
groups:
- 1
- 2
- 3
- 4
- 5
- stage: Galaxy
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: galaxy/{0}/1
targets:
- test: 3.8
- test: 3.9
- test: '3.10'
- stage: Generic
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: generic/{0}/1
targets:
- test: 3.8
- test: 3.9
- test: '3.10'
- stage: Incidental_Remote
displayName: Incidental Remote
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: i/{0}
targets:
- name: macOS 11.1
test: macos/11.1
- name: RHEL 7.9
test: rhel/7.9
- name: RHEL 8.4 py36
test: rhel/8.4@3.6
- name: RHEL 8.4 py38
test: rhel/8.4@3.8
- name: FreeBSD 12.2
test: freebsd/12.2
- name: FreeBSD 13.0
test: freebsd/13.0
- stage: Incidental_Docker
displayName: Incidental Docker
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: i/linux/{0}
targets:
- name: CentOS 6
test: centos6
- name: CentOS 7
test: centos7
- name: Fedora 33
test: fedora33
- name: Fedora 34
test: fedora34
- name: openSUSE 15 py2
test: opensuse15py2
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 18.04
test: ubuntu1804
- name: Ubuntu 20.04
test: ubuntu2004
- stage: Incidental_Windows
displayName: Incidental Windows
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Server {0}
testFormat: i/windows/{0}
targets:
- test: 2012
- test: 2012-R2
- test: 2016
- test: 2019
- test: 2022
- stage: Incidental
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: i/{0}/1
targets:
- name: IOS Python
test: ios/csr1000v/
- name: VyOS Python
test: vyos/1.1.8/
- name: AWS Python 2.7
test: aws/2.7
- name: AWS Python 3.6
test: aws/3.6
- name: Cloud Python
test: cloud/
- stage: Summary
condition: succeededOrFailed()
dependsOn:
- Sanity
- Units
- Windows
- Remote
- Docker
- Galaxy
- Generic
- Incidental_Remote
- Incidental_Docker
- Incidental_Windows
- Incidental
jobs:
- template: templates/coverage.yml

View File

@ -1,20 +0,0 @@
#!/usr/bin/env bash
# Aggregate code coverage results for later processing.
set -o pipefail -eu
agent_temp_directory="$1"
PATH="${PWD}/bin:${PATH}"
mkdir "${agent_temp_directory}/coverage/"
options=(--venv --color -v)
ansible-test coverage combine --group-by command --export "${agent_temp_directory}/coverage/" "${options[@]}"
if ansible-test coverage analyze targets generate --help >/dev/null 2>&1; then
# Only analyze coverage if the installed version of ansible-test supports it.
# Doing so allows this script to work unmodified for multiple Ansible versions.
ansible-test coverage analyze targets generate "${agent_temp_directory}/coverage/coverage-analyze-targets.json" "${options[@]}"
fi

View File

@ -1,60 +0,0 @@
#!/usr/bin/env python
"""
Combine coverage data from multiple jobs, keeping the data only from the most recent attempt from each job.
Coverage artifacts must be named using the format: "Coverage $(System.JobAttempt) {StableUniqueNameForEachJob}"
The recommended coverage artifact name format is: Coverage $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)
Keep in mind that Azure Pipelines does not enforce unique job display names (only names).
It is up to pipeline authors to avoid name collisions when deviating from the recommended format.
"""
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import re
import shutil
import sys
def main():
"""Main program entry point."""
source_directory = sys.argv[1]
if '/ansible_collections/' in os.getcwd():
output_path = "tests/output"
else:
output_path = "test/results"
destination_directory = os.path.join(output_path, 'coverage')
if not os.path.exists(destination_directory):
os.makedirs(destination_directory)
jobs = {}
count = 0
for name in os.listdir(source_directory):
match = re.search('^Coverage (?P<attempt>[0-9]+) (?P<label>.+)$', name)
label = match.group('label')
attempt = int(match.group('attempt'))
jobs[label] = max(attempt, jobs.get(label, 0))
for label, attempt in jobs.items():
name = 'Coverage {attempt} {label}'.format(label=label, attempt=attempt)
source = os.path.join(source_directory, name)
source_files = os.listdir(source)
for source_file in source_files:
source_path = os.path.join(source, source_file)
destination_path = os.path.join(destination_directory, source_file + '.' + label)
print('"%s" -> "%s"' % (source_path, destination_path))
shutil.copyfile(source_path, destination_path)
count += 1
print('Coverage file count: %d' % count)
print('##vso[task.setVariable variable=coverageFileCount]%d' % count)
print('##vso[task.setVariable variable=outputPath]%s' % output_path)
if __name__ == '__main__':
main()

View File

@ -1,24 +0,0 @@
#!/usr/bin/env bash
# Check the test results and set variables for use in later steps.
set -o pipefail -eu
if [[ "$PWD" =~ /ansible_collections/ ]]; then
output_path="tests/output"
else
output_path="test/results"
fi
echo "##vso[task.setVariable variable=outputPath]${output_path}"
if compgen -G "${output_path}"'/junit/*.xml' > /dev/null; then
echo "##vso[task.setVariable variable=haveTestResults]true"
fi
if compgen -G "${output_path}"'/bot/ansible-test-*' > /dev/null; then
echo "##vso[task.setVariable variable=haveBotResults]true"
fi
if compgen -G "${output_path}"'/coverage/*' > /dev/null; then
echo "##vso[task.setVariable variable=haveCoverageData]true"
fi

View File

@ -1,101 +0,0 @@
#!/usr/bin/env python
"""
Upload code coverage reports to codecov.io.
Multiple coverage files from multiple languages are accepted and aggregated after upload.
Python coverage, as well as PowerShell and Python stubs can all be uploaded.
"""
import argparse
import dataclasses
import pathlib
import shutil
import subprocess
import tempfile
import typing as t
import urllib.request
@dataclasses.dataclass(frozen=True)
class CoverageFile:
name: str
path: pathlib.Path
flags: t.List[str]
@dataclasses.dataclass(frozen=True)
class Args:
dry_run: bool
path: pathlib.Path
def parse_args() -> Args:
parser = argparse.ArgumentParser()
parser.add_argument('-n', '--dry-run', action='store_true')
parser.add_argument('path', type=pathlib.Path)
args = parser.parse_args()
# Store arguments in a typed dataclass
fields = dataclasses.fields(Args)
kwargs = {field.name: getattr(args, field.name) for field in fields}
return Args(**kwargs)
def process_files(directory: pathlib.Path) -> t.Tuple[CoverageFile, ...]:
processed = []
for file in directory.joinpath('reports').glob('coverage*.xml'):
name = file.stem.replace('coverage=', '')
# Get flags from name
flags = name.replace('-powershell', '').split('=') # Drop '-powershell' suffix
flags = [flag if not flag.startswith('stub') else flag.split('-')[0] for flag in flags] # Remove "-01" from stub files
processed.append(CoverageFile(name, file, flags))
return tuple(processed)
def upload_files(codecov_bin: pathlib.Path, files: t.Tuple[CoverageFile, ...], dry_run: bool = False) -> None:
for file in files:
cmd = [
str(codecov_bin),
'--name', file.name,
'--file', str(file.path),
]
for flag in file.flags:
cmd.extend(['--flags', flag])
if dry_run:
print(f'DRY-RUN: Would run command: {cmd}')
continue
subprocess.run(cmd, check=True)
def download_file(url: str, dest: pathlib.Path, flags: int, dry_run: bool = False) -> None:
if dry_run:
print(f'DRY-RUN: Would download {url} to {dest} and set mode to {flags:o}')
return
with urllib.request.urlopen(url) as resp:
with dest.open('w+b') as f:
# Read data in chunks rather than all at once
shutil.copyfileobj(resp, f, 64 * 1024)
dest.chmod(flags)
def main():
args = parse_args()
url = 'https://ci-files.testing.ansible.com/codecov/linux/codecov'
with tempfile.TemporaryDirectory(prefix='codecov-') as tmpdir:
codecov_bin = pathlib.Path(tmpdir) / 'codecov'
download_file(url, codecov_bin, 0o755, args.dry_run)
files = process_files(args.path)
upload_files(codecov_bin, files, args.dry_run)
if __name__ == '__main__':
main()

View File

@ -1,17 +0,0 @@
#!/usr/bin/env bash
# Generate code coverage reports for uploading to Azure Pipelines and codecov.io.
set -o pipefail -eu
PATH="${PWD}/bin:${PATH}"
if ! ansible-test --help >/dev/null 2>&1; then
# Install the devel version of ansible-test for generating code coverage reports.
# This is only used by Ansible Collections, which are typically tested against multiple Ansible versions (in separate jobs).
# Since a version of ansible-test is required that can work the output from multiple older releases, the devel version is used.
pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
fi
# Generate stubs using docker (if supported) otherwise fall back to using a virtual environment instead.
# The use of docker is required when Powershell code is present, but Ansible 2.12 was the first version to support --docker with coverage.
ansible-test coverage xml --group-by command --stub --docker --color -v || ansible-test coverage xml --group-by command --stub --venv --color -v

View File

@ -1,34 +0,0 @@
#!/usr/bin/env bash
# Configure the test environment and run the tests.
set -o pipefail -eu
entry_point="$1"
test="$2"
read -r -a coverage_branches <<< "$3" # space separated list of branches to run code coverage on for scheduled builds
export COMMIT_MESSAGE
export COMPLETE
export COVERAGE
export IS_PULL_REQUEST
if [ "${SYSTEM_PULLREQUEST_TARGETBRANCH:-}" ]; then
IS_PULL_REQUEST=true
COMMIT_MESSAGE=$(git log --format=%B -n 1 HEAD^2)
else
IS_PULL_REQUEST=
COMMIT_MESSAGE=$(git log --format=%B -n 1 HEAD)
fi
COMPLETE=
COVERAGE=
if [ "${BUILD_REASON}" = "Schedule" ]; then
COMPLETE=yes
if printf '%s\n' "${coverage_branches[@]}" | grep -q "^${BUILD_SOURCEBRANCHNAME}$"; then
COVERAGE=yes
fi
fi
"${entry_point}" "${test}" 2>&1 | "$(dirname "$0")/time-command.py"

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
"""Prepends a relative timestamp to each input line from stdin and writes it to stdout."""
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import sys
import time
def main():
"""Main program entry point."""
start = time.time()
sys.stdin.reconfigure(errors='surrogateescape')
sys.stdout.reconfigure(errors='surrogateescape')
for line in sys.stdin:
seconds = time.time() - start
sys.stdout.write('%02d:%02d %s' % (seconds // 60, seconds % 60, line))
sys.stdout.flush()
if __name__ == '__main__':
main()

View File

@ -1,29 +0,0 @@
# This template adds a job for processing code coverage data.
# It will upload results to Azure Pipelines and codecov.io.
# Use it from a job stage that completes after all other jobs have completed.
# This can be done by placing it in a separate summary stage that runs after the test stage(s) have completed.
jobs:
- job: Coverage
displayName: Code Coverage
container: default
workspace:
clean: all
steps:
- checkout: self
fetchDepth: $(fetchDepth)
path: $(checkoutPath)
- task: DownloadPipelineArtifact@2
displayName: Download Coverage Data
inputs:
path: coverage/
patterns: "Coverage */*=coverage.combined"
- bash: .azure-pipelines/scripts/combine-coverage.py coverage/
displayName: Combine Coverage Data
- bash: .azure-pipelines/scripts/report-coverage.sh
displayName: Generate Coverage Report
condition: gt(variables.coverageFileCount, 0)
- bash: .azure-pipelines/scripts/publish-codecov.py "$(outputPath)"
displayName: Publish to codecov.io
condition: gt(variables.coverageFileCount, 0)
continueOnError: true

View File

@ -1,55 +0,0 @@
# This template uses the provided targets and optional groups to generate a matrix which is then passed to the test template.
# If this matrix template does not provide the required functionality, consider using the test template directly instead.
parameters:
# A required list of dictionaries, one per test target.
# Each item in the list must contain a "test" or "name" key.
# Both may be provided. If one is omitted, the other will be used.
- name: targets
type: object
# An optional list of values which will be used to multiply the targets list into a matrix.
# Values can be strings or numbers.
- name: groups
type: object
default: []
# An optional format string used to generate the job name.
# - {0} is the name of an item in the targets list.
- name: nameFormat
type: string
default: "{0}"
# An optional format string used to generate the test name.
# - {0} is the name of an item in the targets list.
- name: testFormat
type: string
default: "{0}"
# An optional format string used to add the group to the job name.
# {0} is the formatted name of an item in the targets list.
# {{1}} is the group -- be sure to include the double "{{" and "}}".
- name: nameGroupFormat
type: string
default: "{0} - {{1}}"
# An optional format string used to add the group to the test name.
# {0} is the formatted test of an item in the targets list.
# {{1}} is the group -- be sure to include the double "{{" and "}}".
- name: testGroupFormat
type: string
default: "{0}/{{1}}"
jobs:
- template: test.yml
parameters:
jobs:
- ${{ if eq(length(parameters.groups), 0) }}:
- ${{ each target in parameters.targets }}:
- name: ${{ format(parameters.nameFormat, coalesce(target.name, target.test)) }}
test: ${{ format(parameters.testFormat, coalesce(target.test, target.name)) }}
- ${{ if not(eq(length(parameters.groups), 0)) }}:
- ${{ each group in parameters.groups }}:
- ${{ each target in parameters.targets }}:
- name: ${{ format(format(parameters.nameGroupFormat, parameters.nameFormat), coalesce(target.name, target.test), group) }}
test: ${{ format(format(parameters.testGroupFormat, parameters.testFormat), coalesce(target.test, target.name), group) }}

View File

@ -1,45 +0,0 @@
# This template uses the provided list of jobs to create test one or more test jobs.
# It can be used directly if needed, or through the matrix template.
parameters:
# A required list of dictionaries, one per test job.
# Each item in the list must contain a "job" and "name" key.
- name: jobs
type: object
jobs:
- ${{ each job in parameters.jobs }}:
- job: test_${{ replace(replace(replace(replace(job.test, '/', '_'), '.', '_'), '-', '_'), '@', '_') }}
displayName: ${{ job.name }}
container: default
workspace:
clean: all
steps:
- checkout: self
fetchDepth: $(fetchDepth)
path: $(checkoutPath)
- bash: .azure-pipelines/scripts/run-tests.sh "$(entryPoint)" "${{ job.test }}" "$(coverageBranches)"
displayName: Run Tests
- bash: .azure-pipelines/scripts/process-results.sh
condition: succeededOrFailed()
displayName: Process Results
- bash: .azure-pipelines/scripts/aggregate-coverage.sh "$(Agent.TempDirectory)"
condition: eq(variables.haveCoverageData, 'true')
displayName: Aggregate Coverage Data
- task: PublishTestResults@2
condition: eq(variables.haveTestResults, 'true')
inputs:
testResultsFiles: "$(outputPath)/junit/*.xml"
displayName: Publish Test Results
- task: PublishPipelineArtifact@1
condition: eq(variables.haveBotResults, 'true')
displayName: Publish Bot Results
inputs:
targetPath: "$(outputPath)/bot/"
artifactName: "Bot $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)"
- task: PublishPipelineArtifact@1
condition: eq(variables.haveCoverageData, 'true')
displayName: Publish Coverage Data
inputs:
targetPath: "$(Agent.TempDirectory)/coverage/"
artifactName: "Coverage $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)"

View File

@ -1,5 +0,0 @@
team = "ansible"
repo = "ansible"
check_sha = "f31421576b00f0b167cdbe61217c31c21a41ac02" # the very first commit in repo
fix_commit_msg = false # Don't replace "#" with "GH-"
default_branch = "devel"

1
.gitattributes vendored
View File

@ -1 +0,0 @@
.github/ export-ignore

151
.github/BOTMETA.yml vendored
View File

@ -1,151 +0,0 @@
automerge: false
collection_redirect: true
notifications: false
files:
$module_utils/csharp: &id001
labels: windows
maintainers: $team_windows_core
support: core
$module_utils/network:
labels: networking
$module_utils/network/common:
maintainers: $team_networking
support: network
$module_utils/powershell: *id001
$modules:
ignored: ryansb tomaszkiewicz
$modules/lineinfile.py: $team_ansible samdoran
$modules/stat.py:
ignored: bpennypacker
$modules/unarchive.py:
ignored: dagwieers
labels: m:unarchive
maintainers: pileofrogs
$modules/add_host.py:
ignored: skvidal
maintainers: $team_ansible
$modules/get_url.py: ptux
$modules/uri.py:
ignored: romeotheriault
maintainers: $team_ansible
$modules/pip.py: Lujeni webknjaz
$modules//yum.py:
ignored: skvidal
maintainers: $team_ansible kustodian
$modules/user.py: $team_ansible samdoran
$modules/pause.py: samdoran
$modules/wait_for.py: gregswift
$plugins/cliconf/:
labels: networking
$plugins/connection/psrp.py: *id001
$plugins/connection/winrm.py: *id001
$plugins/doc_fragments/url_windows.py:
labels: windows
maintainers: $team_windows_core
support: core
$plugins/httpapi:
labels: networking
maintainers: $team_networking
support: network
$plugins/netconf/:
labels: networking
maintainers: $team_networking
support: network
$plugins/shell/powershell.py: *id001
$plugins/terminal/:
labels: networking
$plugins/terminal/__init__.py:
support: network
.github/BOTMETA.yml:
labels: botmeta
support: core
docs/:
maintainers:
- acozine
docs/docsite/rst/community/:
maintainers:
- gundalow
docs/docsite/rst/dev_guide/:
maintainers:
- gundalow
docs/docsite/rst/network/:
labels: networking
maintainers:
- samccann
docs/docsite/rst/user_guide/windows: *id001
hacking/report.py:
notified: mattclay
hacking/shippable/:
notified: mattclay
lib/ansible/cli/scripts/ansible_connection_cli_stub.py:
keywords:
- persistent connection
labels: networking
lib/ansible/config/ansible_builtin_runtime.yml:
labels: runtime
maintainers: gundalow
lib/ansible/executor/powershell: *id001
lib/ansible/inventory:
keywords:
- core inventory
- inventory
- inventory parsing
lib/ansible/playbook/handler.py:
keywords:
- handlers
lib/ansible/playbook/role:
keywords:
- roles path
- roles_path
- role
- role path
lib/ansible/playbook/role/include.py:
keywords:
- include role
- include_role
- role include
lib/ansible/playbook/role/requirement.py:
keywords:
- role dependencies
- role dep
- role dependency
lib/ansible/release.py:
notified: mattclay nitzmahone
lib/ansible/template:
keywords:
- jinja
- jinja2
lib/ansible/utils/collection_loader.py:
notified: mattclay nitzmahone
test/integration/targets/incidental_:
notified: mattclay
test/lib/:
notified: mattclay
test/lib/ansible_test/_util/controller/sanity/validate-modules:
keywords:
- validate-modules
notified:
- mattclay
test/lib/ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py:
notified:
- gundalow
- sivel
test/lib/ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py:
notified:
- gundalow
- sivel
test/sanity/:
notified: mattclay
test/sanity/ignore.txt:
notified: tremble
test/support/:
notified: mattclay
test/utils/shippable/:
notified: mattclay
macros:
module_utils: lib/ansible/module_utils
modules: lib/ansible/modules
plugins: lib/ansible/plugins
team_ansible: []
team_networking: Qalthos ganeshrn trishnaguha justjais NilashishC danielmellado rohitthakur2590 GomathiselviS
team_windows_core: nitzmahone jborean93

View File

@ -1,3 +0,0 @@
# Community Code of Conduct
Please see the official [Ansible Community Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html).

View File

@ -1,25 +0,0 @@
# WELCOME TO ANSIBLE GITHUB
Hi! Nice to see you here!
## QUESTIONS ?
Please see the [Community Guide](https://docs.ansible.com/ansible/latest/community/index.html) for information on how to ask questions on the [mailing lists](https://docs.ansible.com/ansible/latest/community/communication.html#mailing-list-information) and IRC.
The GitHub issue tracker is not the best place for questions for various reasons, but both IRC and the mailing list are very helpful places for those things, as the community page explains best.
## CONTRIBUTING ?
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. You can also read the same [CLA](https://docs.ansible.com/ansible/latest/community/contributor_license_agreement.html) on the Ansible docsite.
Please review the [Community Guide](https://docs.ansible.com/ansible/latest/community/index.html) for more information on contributing to Ansible.
## BUG TO REPORT ?
First and foremost, also check the [Community Guide](https://docs.ansible.com/ansible/latest/community/index.html).
You can report bugs or make enhancement requests at the [Ansible GitHub issue page](http://github.com/ansible/ansible/issues/new/choose) by filling out the issue template that will be presented.
Also please make sure you are testing on the latest released version of Ansible or the development branch; see the [Installation Guide](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) for details.
Thanks!

View File

@ -1 +0,0 @@
Please raise issues via the [new interface](https://github.com/ansible/ansible/issues/new/choose)

View File

@ -1,263 +0,0 @@
---
name: 🐛 Bug report
description: Create a report to help us improve
body:
- type: markdown
attributes:
value: >
**Thank you for wanting to report a bug in ansible-core!**
⚠
Verify first that your issue is not [already reported on
GitHub][issue search] and keep in mind that we may have to keep
the current behavior because [every change breaks someone's
workflow][XKCD 1172].
We try to be mindful about this.
Also test if the latest release and devel branch are affected too.
**Tip:** If you are seeking community support, please consider
[starting a mailing list thread or chatting in IRC][ML||IRC].
[ML||IRC]:
https://docs.ansible.com/ansible-core/devel/community/communication.html?utm_medium=github&utm_source=issue_form--bug_report.yml#mailing-list-information
[issue search]: ../search?q=is%3Aissue&type=issues
[XKCD 1172]: https://xkcd.com/1172/
- type: textarea
attributes:
label: Summary
description: Explain the problem briefly below.
placeholder: >-
When I try to do X with ansible-core from the devel branch on GitHub, Y
breaks in a way Z under the env E. Here are all the details I know
about this problem...
validations:
required: true
- type: dropdown
attributes:
label: Issue Type
description: >
Please select the single available option in the drop-down.
<details>
<summary>
<em>Why?</em>
</summary>
We would do it by ourselves but unfortunatelly, the curent
edition of GitHub Issue Forms Alpha does not support this yet 🤷
_We will make it easier in the future, once GitHub
supports dropdown defaults. Promise!_
</details>
# FIXME: Once GitHub allows defining the default choice, update this
options:
- Bug Report
validations:
required: true
- type: input
attributes:
label: Component Name
description: >
Write the short name of the rst file, module, plugin, task or
feature below, *use your best guess if unsure*.
**Tip:** Cannot find it in this repository? Please be advised that
the source for some parts of the documentation are hosted outside
of this repository. If the page you are reporting describes
modules/plugins/etc that are not officially supported by the
Ansible Core Engineering team, there is a good chance that it is
coming from one of the [Ansible Collections maintained by the
community][collections org]. If this is the case, please make sure
to file an issue under the appropriate project there instead.
[collections org]: /ansible-collections
placeholder: dnf, apt, yum, pip, user etc.
validations:
required: true
- type: textarea
attributes:
label: Ansible Version
description: >-
Paste verbatim output from `ansible --version` below, under
the prompt line. Please don't wrap it with tripple backticks — your
whole input will be turned into a code snippet automatically.
render: console
value: |
$ ansible --version
placeholder: |
$ ansible --version
ansible [core 2.11.0b4.post0] (detached HEAD ref: refs/) last updated 2021/04/02 00:33:35 (GMT +200)
config file = None
configured module search path = ['~/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = ~/src/github/ansible/ansible/lib/ansible
ansible collection location = ~/.ansible/collections:/usr/share/ansible/collections
executable location = bin/ansible
python version = 3.9.0 (default, Oct 26 2020, 13:08:59) [GCC 10.2.0]
jinja version = 2.11.3
libyaml = True
validations:
required: true
- type: textarea
attributes:
label: Configuration
description: >-
Paste verbatim output from `ansible-config dump --only-changed`
below, under the prompt line.
Please don't wrap it with tripple backticks — your
whole input will be turned into a code snippet automatically.
render: console
value: |
$ ansible-config dump --only-changed
placeholder: |
$ ansible-config dump --only-changed
DEFAULT_GATHERING(~/src/github/ansible/ansible/ansible.cfg) = smart
DEFAULT_HOST_LIST(~/src/github/ansible/ansible/ansible.cfg) = ['~/src/github/ansible/ansible/hosts']
DEFAULT_VAULT_PASSWORD_FILE(~/src/github/ansible/ansible/ansible.cfg) = ~/src/github/ansible/ansible/vault/print-password.sh
validations:
required: true
- type: textarea
attributes:
label: OS / Environment
description: >-
Provide all relevant information below, e.g. target OS versions,
network device firmware, etc.
placeholder: RHEL 8, CentOS Stream etc.
validations:
required: true
- type: textarea
attributes:
label: Steps to Reproduce
description: |
Describe exactly how to reproduce the problem, using a minimal test-case. It would *really* help us understand your problem if you could also pased any playbooks, configs and commands you used.
**HINT:** You can paste https://gist.github.com links for larger files.
value: |
<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
```
placeholder: |
1. Implement the following playbook:
```yaml
---
# ping.yml
- hosts: all
gather_facts: false
tasks:
- ping:
...
```
2. Then run `ANSIBLE_DEBUG=1 ansible-playbook ping.yml -vvvvv`
3. An error occurs.
validations:
required: true
- type: textarea
attributes:
label: Expected Results
description: >-
Describe what you expected to happen when running the steps above.
placeholder: >-
I expected X to happen because I assumed Y and was shocked
that it did not.
validations:
required: true
- type: textarea
attributes:
label: Actual Results
description: |
Describe what actually happened. If possible run with extra verbosity (`-vvvv`).
Paste verbatim command output and don't wrap it with tripple backticks — your
whole input will be turned into a code snippet automatically.
render: console
placeholder: >-
Certificate did not match expected hostname: files.pythonhosted.org. Certificate: {'notAfter': 'Apr 28 19:20:25 2021 GMT', 'subjectAltName': ((u'DNS', 'r.ssl.fastly.net'), (u'DNS', '*.catchpoint.com'), (u'DNS', '*.cnn.io'), (u'DNS', '*.dollarshaveclub.com'), (u'DNS', '*.eater.com'), (u'DNS', '*.fastly.picmonkey.com'), (u'DNS', '*.files.saymedia-content.com'), (u'DNS', '*.ft.com'), (u'DNS', '*.meetupstatic.com'), (u'DNS', '*.nfl.com'), (u'DNS', '*.pagar.me'), (u'DNS', '*.picmonkey.com'), (u'DNS', '*.realself.com'), (u'DNS', '*.sbnation.com'), (u'DNS', '*.shakr.com'), (u'DNS', '*.streamable.com'), (u'DNS', '*.surfly.com'), (u'DNS', '*.theverge.com'), (u'DNS', '*.thrillist.com'), (u'DNS', '*.vox-cdn.com'), (u'DNS', '*.vox.com'), (u'DNS', '*.voxmedia.com'), (u'DNS', 'eater.com'), (u'DNS', 'ft.com'), (u'DNS', 'i.gse.io'), (u'DNS', 'picmonkey.com'), (u'DNS', 'realself.com'), (u'DNS', 'static.wixstatic.com'), (u'DNS', 'streamable.com'), (u'DNS', 'surfly.com'), (u'DNS', 'theverge.com'), (u'DNS', 'vox-cdn.com'), (u'DNS', 'vox.com'), (u'DNS', 'www.joyent.com')), 'subject': ((('countryName', u'US'),), (('stateOrProvinceName', u'California'),), (('localityName', u'San Francisco'),), (('organizationName', u'Fastly, Inc'),), (('commonName', u'r.ssl.fastly.net'),))}
Exception:
Traceback (most recent call last):
File "/usr/local/lib/python2.6/dist-packages/pip/basecommand.py", line 215, in main
status = self.run(options, args)
File "/usr/local/lib/python2.6/dist-packages/pip/commands/install.py", line 335, in run
wb.build(autobuilding=True)
File "/usr/local/lib/python2.6/dist-packages/pip/wheel.py", line 749, in build
self.requirement_set.prepare_files(self.finder)
File "/usr/local/lib/python2.6/dist-packages/pip/req/req_set.py", line 380, in prepare_files
ignore_dependencies=self.ignore_dependencies))
File "/usr/local/lib/python2.6/dist-packages/pip/req/req_set.py", line 620, in _prepare_file
session=self.session, hashes=hashes)
File "/usr/local/lib/python2.6/dist-packages/pip/download.py", line 821, in unpack_url
hashes=hashes
File "/usr/local/lib/python2.6/dist-packages/pip/download.py", line 659, in unpack_http_url
hashes)
File "/usr/local/lib/python2.6/dist-packages/pip/download.py", line 853, in _download_http_url
stream=True,
File "/usr/local/lib/python2.6/dist-packages/pip/_vendor/requests/sessions.py", line 521, in get
return self.request('GET', url, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/pip/download.py", line 386, in request
return super(PipSession, self).request(method, url, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/pip/_vendor/requests/sessions.py", line 508, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python2.6/dist-packages/pip/_vendor/requests/sessions.py", line 618, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/pip/_vendor/cachecontrol/adapter.py", line 47, in send
resp = super(CacheControlAdapter, self).send(request, **kw)
File "/usr/local/lib/python2.6/dist-packages/pip/_vendor/requests/adapters.py", line 506, in send
raise SSLError(e, request=request)
SSLError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Max retries exceeded with url: /packages/ef/ab/aa12712415809bf698e719b307419f953e25344e8f42d557533d7a02b276/netapp_lib-2020.7.16-py2-none-any.whl (Caused by SSLError(CertificateError("hostname 'files.pythonhosted.org' doesn't match either of 'r.ssl.fastly.net', '*.catchpoint.com', '*.cnn.io', '*.dollarshaveclub.com', '*.eater.com', '*.fastly.picmonkey.com', '*.files.saymedia-content.com', '*.ft.com', '*.meetupstatic.com', '*.nfl.com', '*.pagar.me', '*.picmonkey.com', '*.realself.com', '*.sbnation.com', '*.shakr.com', '*.streamable.com', '*.surfly.com', '*.theverge.com', '*.thrillist.com', '*.vox-cdn.com', '*.vox.com', '*.voxmedia.com', 'eater.com', 'ft.com', 'i.gse.io', 'picmonkey.com', 'realself.com', 'static.wixstatic.com', 'streamable.com', 'surfly.com', 'theverge.com', 'vox-cdn.com', 'vox.com', 'www.joyent.com'",),))
ERROR: Command "/usr/bin/python2.6 /root/ansible/test/lib/ansible_test/_data/quiet_pip.py install --disable-pip-version-check -r /root/ansible/test/lib/ansible_test/_data/requirements/units.txt -r tests/unit/requirements.txt -c /root/ansible/test/lib/ansible_test/_data/requirements/constraints.txt" returned exit status 2.
ERROR: Command "docker exec d47eb360db4ce779c1f690db964655b76e68895c4360ff252c46fe7fe6f5c75a /usr/bin/env ANSIBLE_TEST_CONTENT_ROOT=/root/ansible_collections/netapp/ontap LC_ALL=en_US.UTF-8 /usr/bin/python3.6 /root/ansible/bin/ansible-test units --metadata tests/output/.tmp/metadata-9i2qfrcl.json --truncate 200 --redact --color yes --requirements --python default --requirements-mode only" returned exit status 1.
validations:
required: true
- type: markdown
attributes:
value: >
*One last thing...*
*Please, complete **all** sections as described, this form
is [processed automatically by a robot][ansibot help].*
Thank you for your collaboration!
[ansibot help]:
/ansible/ansibullbot/blob/master/ISSUE_HELP.md#for-issue-submitters
- type: checkboxes
attributes:
label: Code of Conduct
description: |
Read the [Ansible Code of Conduct][CoC] first.
[CoC]: https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_form--bug_report.yml
options:
- label: I agree to follow the Ansible Code of Conduct
required: true
...

View File

@ -1,26 +0,0 @@
# Ref: https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository#configuring-the-template-chooser
blank_issues_enabled: false # default: true
contact_links:
- name: 🔐 Security bug report 🔥
url: https://docs.ansible.com/ansible/latest/community/reporting_bugs_and_features.html?utm_medium=github&utm_source=issue_template_chooser
about: |
Please learn how to report security vulnerabilities here.
For all security related bugs, email security@ansible.com
instead of using this issue tracker and you will receive
a prompt response.
For more information, see
https://docs.ansible.com/ansible/latest/community/reporting_bugs_and_features.html
- name: 📝 Ansible Code of Conduct
url: https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_template_chooser
about: ❤ Be nice to other members of the community. ☮ Behave.
- name: 💬 Talks to the community
url: https://docs.ansible.com/ansible/latest/community/communication.html?utm_medium=github&utm_source=issue_template_chooser#mailing-list-information
about: Please ask and answer usage questions here
- name: ⚡ Working groups
url: https://github.com/ansible/community/wiki
about: Interested in improving a specific area? Become a part of a working group!
- name: 💼 For Enterprise
url: https://www.ansible.com/products/engine?utm_medium=github&utm_source=issue_template_chooser
about: Red Hat offers support for the Ansible Automation Platform

View File

@ -1,199 +0,0 @@
---
name: 📝 Documentation Report
description: Ask us about docs
body:
- type: markdown
attributes:
value: >
**Thank you for wanting to report a problem with ansible-core
documentation!**
Please fill out your suggestions below. If the problem seems
straightforward, feel free to go ahead and
[submit a pull request] instead!
⚠
Verify first that your issue is not [already reported on
GitHub][issue search].
Also test if the latest release and devel branch are affected too.
**Tip:** If you are seeking community support, please consider
[starting a mailing list thread or chatting in IRC][ML||IRC].
[ML||IRC]:
https://docs.ansible.com/ansible-core/devel/community/communication.html?utm_medium=github&utm_source=issue_form--documentation_report.yml#mailing-list-information
[issue search]: ../search?q=is%3Aissue&type=issues
[submit a pull request]:
https://docs.ansible.com/ansible-core/devel/community/documentation_contributions.html
- type: textarea
attributes:
label: Summary
description: >
Explain the problem briefly below, add suggestions to wording
or structure.
**HINT:** Did you know the documentation has a `View on GitHub`
link on every page? Feel free to use it to start a pull request
right from the GitHub UI!
placeholder: >-
I was reading the ansible-core documentation of version X and I'm having
problems understanding Y. It would be very helpful if that got
rephrased as Z.
validations:
required: true
- type: dropdown
attributes:
label: Issue Type
description: >
Please select the single available option in the drop-down.
<details>
<summary>
<em>Why?</em>
</summary>
We would do it by ourselves but unfortunatelly, the curent
edition of GitHub Issue Forms Alpha does not support this yet 🤷
_We will make it easier in the future, once GitHub
supports dropdown defaults. Promise!_
</details>
# FIXME: Once GitHub allows defining the default choice, update this
options:
- Documentation Report
validations:
required: true
- type: input
attributes:
label: Component Name
description: >
Write the short name of the rst file, module, plugin, task or
feature below, *use your best guess if unsure*.
**Tip:** Be advised that the source for some parts of the
documentation are hosted outside of this repository. If the page
you are reporting describes modules/plugins/etc that are not
officially supported by the Ansible Core Engineering team, there
is a good chance that it is coming from one of the [Ansible
Collections maintained by the community][collections org]. If this
is the case, please make sure to file an issue under the
appropriate project there instead.
[collections org]: /ansible-collections
placeholder: docs/docsite/rst/dev_guide/debugging.rst
validations:
required: true
- type: textarea
attributes:
label: Ansible Version
description: >-
Paste verbatim output from `ansible --version` below, under
the prompt line. Please don't wrap it with tripple backticks — your
whole input will be turned into a code snippet automatically.
render: console
value: |
$ ansible --version
placeholder: |
$ ansible --version
ansible [core 2.11.0b4.post0] (detached HEAD ref: refs/) last updated 2021/04/02 00:33:35 (GMT +200)
config file = None
configured module search path = ['~/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = ~/src/github/ansible/ansible/lib/ansible
ansible collection location = ~/.ansible/collections:/usr/share/ansible/collections
executable location = bin/ansible
python version = 3.9.0 (default, Oct 26 2020, 13:08:59) [GCC 10.2.0]
jinja version = 2.11.3
libyaml = True
validations:
required: true
- type: textarea
attributes:
label: Configuration
description: >-
Paste verbatim output from `ansible-config dump --only-changed`
below, under the prompt line.
Please don't wrap it with tripple backticks — your
whole input will be turned into a code snippet automatically.
render: console
value: |
$ ansible-config dump --only-changed
placeholder: |
$ ansible-config dump --only-changed
DEFAULT_GATHERING(~/src/github/ansible/ansible/ansible.cfg) = smart
DEFAULT_HOST_LIST(~/src/github/ansible/ansible/ansible.cfg) = ['~/src/github/ansible/ansible/hosts']
DEFAULT_VAULT_PASSWORD_FILE(~/src/github/ansible/ansible/ansible.cfg) = ~/src/github/ansible/ansible/vault/print-password.sh
validations:
required: true
- type: textarea
attributes:
label: OS / Environment
description: >-
Provide all relevant information below, e.g. OS version,
browser, etc.
placeholder: Fedora 33, Firefox etc.
validations:
required: true
- type: textarea
attributes:
label: Additional Information
description: |
Describe how this improves the documentation, e.g. before/after situation or screenshots.
**HINT:** You can paste https://gist.github.com links for larger files.
placeholder: >-
When the improvement is applied, it makes it more straightforward
to understand X.
validations:
required: true
- type: markdown
attributes:
value: >
*One last thing...*
*Please, complete **all** sections as described, this form
is [processed automatically by a robot][ansibot help].*
Thank you for your collaboration!
[ansibot help]:
/ansible/ansibullbot/blob/master/ISSUE_HELP.md#for-issue-submitters
- type: checkboxes
attributes:
label: Code of Conduct
description: |
Read the [Ansible Code of Conduct][CoC] first.
[CoC]: https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_form--documentation_report.yml
options:
- label: I agree to follow the Ansible Code of Conduct
required: true
...

View File

@ -1,192 +0,0 @@
---
name: ✨ Feature request
description: Suggest an idea for this project
body:
- type: markdown
attributes:
value: >
**Thank you for wanting to suggest a feature for ansible-core!**
💡
Before you go ahead with your request, please first consider if it
would be useful for majority of the ansible-core users. As a
general rule of thumb, any feature that is only of interest to a
small sub group should be [implemented in a third-party Ansible
Collection][contribute to collections] or maybe even just your
project alone. Be mindful of the fact that the essential
ansible-core features have a broad impact.
If unsure, consider filing a [new proposal] instead outlining your
use-cases, the research and implementation considerations. Then,
start a discussion on one of the public [IRC meetings] we have just
for this.
<details>
<summary>
❗ Every change breaks someone's workflow.
</summary>
[![❗ Every change breaks someone's workflow.
](https://imgs.xkcd.com/comics/workflow.png)
](https://xkcd.com/1172/)
</details>
⚠
Verify first that your idea is not [already requested on
GitHub][issue search].
Also test if the devel branch does not already implement this.
**Tip:** If you are seeking community support, please consider
[starting a mailing list thread or chatting in IRC][ML||IRC].
[contribute to collections]:
https://docs.ansible.com/ansible-core/devel/community/contributing_maintained_collections.html?utm_medium=github&utm_source=issue_form--feature_request.yml
[IRC meetings]:
https://docs.ansible.com/ansible-core/devel/community/communication.html?utm_medium=github&utm_source=issue_form--feature_request.yml#irc-meetings
[issue search]: ../search?q=is%3Aissue&type=issues
[ML||IRC]:
https://docs.ansible.com/ansible-core/devel/community/communication.html?utm_medium=github&utm_source=issue_form--feature_request.yml#mailing-list-information
[new proposal]: ../../proposals/issues/new
- type: textarea
attributes:
label: Summary
description: >
Describe the new feature/improvement you would like briefly below.
What's the problem this feature will solve?
What are you trying to do, that you are unable to achieve
with ansible-core as it currently stands?
* Provide examples of real-world use cases that this would enable
and how it solves the problem you described.
* How do you solve this now?
* Have you tried to work around the problem using other tools?
* Could there be a different approach to solving this issue?
*Know **exactly** what you want?* Consider filing a [new proposal]
instead outlining your research and implementation considerations.
[new proposal]: ../../proposals/issues/new
placeholder: >-
I am trying to do X with ansible-core from the devel branch on GitHub and
I think that implementing a feature Y would be very helpful for me and
every other user of ansible-core because of Z.
validations:
required: true
- type: dropdown
attributes:
label: Issue Type
description: >
Please select the single available option in the drop-down.
<details>
<summary>
<em>Why?</em>
</summary>
We would do it by ourselves but unfortunatelly, the curent
edition of GitHub Issue Forms Alpha does not support this yet 🤷
_We will make it easier in the future, once GitHub
supports dropdown defaults. Promise!_
</details>
# FIXME: Once GitHub allows defining the default choice, update this
options:
- Feature Idea
validations:
required: true
- type: input
attributes:
label: Component Name
description: >
Write the short name of the module, plugin, task or feature below,
*use your best guess if unsure*.
Be aware that a lot of content that used to reside in this repository
previously, is now hosted under [individual collection
projects][collections org].
If this is the case, please make sure to file an issue under the
appropriate project there instead.
[collections org]: /ansible-collections
placeholder: dnf, apt, yum, pip, user etc.
validations:
required: true
- type: textarea
attributes:
label: Additional Information
description: |
Describe how the feature would be used, why it is needed and what it would solve.
**HINT:** You can paste https://gist.github.com links for larger files.
value: |
<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
```
placeholder: >-
I asked on https://stackoverflow.com/.... and the community
advised me to do X, Y and Z.
validations:
required: true
- type: markdown
attributes:
value: >
*One last thing...*
*Please, complete **all** sections as described, this form
is [processed automatically by a robot][ansibot help].*
Thank you for your collaboration!
[ansibot help]:
/ansible/ansibullbot/blob/master/ISSUE_HELP.md#for-issue-submitters
- type: checkboxes
attributes:
label: Code of Conduct
description: |
Read the [Ansible Code of Conduct][CoC] first.
[CoC]: https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_form--feature_request.yml
options:
- label: I agree to follow the Ansible Code of Conduct
required: true
...

View File

@ -1,23 +0,0 @@
##### SUMMARY
<!--- Describe the change below, including rationale and design decisions -->
<!--- HINT: Include "Fixes #nnn" if you are fixing an existing issue -->
##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
- Bugfix Pull Request
- Docs Pull Request
- Feature Pull Request
- Test Pull Request
##### COMPONENT NAME
<!--- Write the short name of the module, plugin, task or feature below -->
##### ADDITIONAL INFORMATION
<!--- Include additional information to help people understand the change here -->
<!--- A step-by-step reproduction of the problem is helpful if there is no related issue -->
<!--- Paste verbatim command output below, e.g. before and after your change -->
```paste below
```

View File

@ -1,14 +0,0 @@
---
- 2.12.0 Dazed and Confused
- 2.11.0 Hey Hey, What Can I Do
- 2.10.0 When the Levee Breaks
- 2.9.0 Immigrant Song
- 2.8.0 How Many More Times
- 2.7.0 In the Light
- 2.6.0 Heartbreaker
- 2.5.0 Kashmir
- 2.4.0 Dancing Days
- 2.3.0 Ramble On
- 2.2.0 The Battle of Evermore
- 2.1.0 The Song Remains the Same
- 2.0.0 Over the Hills and Far Away

15
.github/SECURITY.md vendored
View File

@ -1,15 +0,0 @@
# Security Policy
## Supported Versions
Ansible applies security fixes according to the 3-versions-back support
policy. Please find more information in [our docs](
https://docs.ansible.com/ansible/devel/reference_appendices/release_and_maintenance.html#release-status
).
## Reporting a Vulnerability
We encourage responsible disclosure practices for security
vulnerabilities. Please read our [policies for reporting bugs](
https://docs.ansible.com/ansible/devel/community/reporting_bugs_and_features.html#reporting-a-bug
) if you want to report a security issue that might affect Ansible.

91
.gitignore vendored
View File

@ -2,10 +2,9 @@
*.py[co]
build
AUTHORS.TXT
# Emacs backup and autosave files...
# Emacs backup files...
*~
.\#*
\#*
# RPM stuff...
MANIFEST
dist
@ -17,102 +16,38 @@ rpm-build
.idea
#IntelliJ IDEA stuff..
*.iml
#VSCode stuff..
.vscode/
# Mac OS X stuff...
.DS_Store
# manpage build stuff...
docs/man/man1/ansible*.1
docs/man/man1/ansible*.1.asciidoc.in
docs/man/man3/*
# Sublime stuff
*.sublime-project
*.sublime-workspace
# docsite stuff...
docs/docsite/_build
docs/docsite/*.html
docs/docsite/htmlout
docs/docsite/rst/conf.py
docs/docsite/rst/index.rst
docs/docsite/rst/cli/ansible-*.rst
docs/docsite/rst/cli/ansible.rst
docs/docsite/rst/dev_guide/collections_galaxy_meta.rst
docs/docsite/rst/dev_guide/testing/sanity/index.rst.new
docs/docsite/rst/modules/*.rst
docs/docsite/rst/collections/*.rst
!docs/docsite/rst/collections/all_plugins.rst
docs/docsite/rst/collections/*/*.rst
docs/docsite/rst/playbooks_directives.rst
docs/docsite/rst/plugins_by_category.rst
docs/docsite/rst/plugins/*/*.rst
docs/docsite/rst/reference_appendices/config.rst
docs/docsite/rst/reference_appendices/playbooks_keywords.rst
docs/docsite/rst_warnings
docs/docsite/searchindex.js
docs/docsite/_static/*.gif
docs/docsite/_static/*.png
docs/docsite/_static/websupport.js
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/
debian/
deb-build
# Vim swap files
*.swp
*.swo
credentials.yml
# test output
*.retry
*.out
.pytest_cache/
.tox
.cache
.pytest_cache
.coverage
results.xml
coverage.xml
/test/units/cover-html
/test/integration/inventory
/test/integration/targets/*/backup/
/test/cache/*
# Development
/test/develop
venv
Vagrantfile
.vagrant
# Backwards compatibility with `stable-2.9` and earlier branches.
# Also used in the `devel` branch during early Ansible 2.10 development.
/lib/ansible.egg-info/
# First used in the `devel` branch during Ansible 2.10 development.
/lib/ansible_base.egg-info/
# First used in the `devel` branch during Ansible 2.11 development.
/lib/ansible_core.egg-info/
# vendored lib dir
lib/ansible/_vendor/*
!lib/ansible/_vendor/__init__.py
# test stuff
/test/integration/cloud-config-*.*
!/test/integration/cloud-config-*.*.template
.python-version
/hacking/tests/selinux/*.mod
/hacking/tests/selinux/*.pp
# Release directory
packaging/release/ansible_release
/.cache/
/test/results/
/test/integration/cloud-config-aws.yml
/test/integration/inventory.networking
/test/integration/inventory.winrm
/test/integration/cloud-config-aws.yml
/test/integration/cloud-config-cs.ini
# python 'rope' stuff
.ropeproject
# local 'ack' config files
.ackrc
# default 'coverage html' results
htmlcov/
# default 'coverage' tool data
.coverage
# ansible-test coverage results
test/units/.coverage.*
/test/integration/cloud-config-azure.yml
/SYMLINK_CACHE.json
changelogs/.plugin-cache.yaml
.ansible-test-timeout.json
ansible.egg-info/

View File

@ -1,36 +0,0 @@
Michael DeHaan <michael.dehaan@gmail.com> <michael@ansibleworks.com>
Michael DeHaan <michael.dehaan@gmail.com> Michael DeHaan <michael@ansibleworks.com>
Michael DeHaan <michael.dehaan@gmail.com> <michael@ansible.com>
<bcoca@ansible.com> <brian.coca+git@gmail.com>
<bcoca@ansible.com> <briancoca+ansible@gmail.com>
<bcoca@ansible.com> <briancoca+dev@gmail.com>
<bcoca@ansible.com> <bcoca@tablethotels.com>
<a.badger@gmail.com> <toshio@fedoraproject.org>
James Tanner <tanner.jc@gmail.com>
<jimi@sngx.net> <jcammarata@ansibleworks.com>
Michael Scherer <misc@zarb.org> mscherer <misc@zarb.org>
<misc@zarb.org> <misc@ephaone.org>
<misc@zarb.org> <mscherer@users.noreply.github.com>
James Martin <jmartin@ansible.com> <jmartin@basho.com>
James Laska <jlaska@ansible.com> <jlaska@redhat.com>
James Laska <jlaska@ansible.com> <jlaska@ansibleworks.com>
James Laska <jlaska@ansible.com> <jlaska@James-Laskas-MacBook-Pro.local>
James Laska <jlaska@ansible.com> <jlaska@users.noreply.github.com>
Jason McKerr <mckerrj@gmail.com> <jmckerr@jmckerr-OSX.local>
Chris Houseknecht <chouseknecht@ansible.com>
Chris Houseknecht <chouseknecht@ansible.com> chouseknecht <chouse@ansible.com>
Chris Houseknecht <chouseknecht@ansible.com> Chris Houseknecht <chouse@ansibleworks.com>
Stephen Fromm <sfromm@gmail.com> Stephen Fromm <stephenf@nero.net>
Sandra Wills <docschick@ansible.com> Sandra Wills <swills@ansible.com>
Will Thames <will@thames.id.au> willthames <will@thames.id.au>
Will Thames <will@thames.id.au> Will Thames <willdthames@gmail.com>
Will Thames <will@thames.id.au> willthames <willdthames@gmail.com>
Will Thames <will@thames.id.au> willthames <will@musc.org.uk>
Will Thames <will@thames.id.au> u348095 <will.thames@suncorp.com.au>
Will Thames <will@thames.id.au> willthames <will.thames@suncorp.com.au>
Will Thames <will@thames.id.au> Will Thames <will.thames@xvt.com.au>
nitzmahone <mdavis@ansible.com> Matt Davis <nitzmahone@users.noreply.github.com>
Dag Wieers <dag@wieers.com> Dag Wieërs <dag@wieers.com>
Dag Wieers <dag@wieers.com> Dag Wieers <dag.wieers@gmail.com>
Rene Moser <mail@renemoser.net> René Moser <mail@renemoser.net>
Rene Moser <mail@renemoser.net> Rene Moser <rene.moser@swisstxt.ch>

1298
CHANGELOG.md Normal file

File diff suppressed because it is too large Load Diff

319
CODING_GUIDELINES.md Normal file
View File

@ -0,0 +1,319 @@
Coding 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!

224
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,224 @@
Ansible 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 recieve 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.

View File

@ -1,40 +1,8 @@
include README.rst
include COPYING
include SYMLINK_CACHE.json
include requirements.txt
recursive-include docs *
include docs/docsite/rst/collections/all_plugins.rst
exclude docs/docsite/rst_warnings
exclude docs/docsite/rst/conf.py
exclude docs/docsite/rst/index.rst
recursive-exclude docs/docsite/_build *
recursive-exclude docs/docsite/_extensions *.pyc *.pyo
include README.md packaging/rpm/ansible.spec COPYING
include examples/hosts
include examples/ansible.cfg
include examples/scripts/ConfigureRemotingForAnsible.ps1
include examples/scripts/upgrade_to_ps3.ps1
include lib/ansible/keyword_desc.yml
recursive-include lib/ansible/executor/powershell *.ps1
recursive-include lib/ansible/module_utils/csharp *.cs
recursive-include lib/ansible/module_utils/powershell *.psm1
recursive-include lib/ansible/modules/windows *.ps1
recursive-include lib/ansible/galaxy/data *.yml *.j2 README.md ansible.cfg inventory .git_keep
recursive-include lib/ansible/config *.yml
recursive-include licenses *.txt
recursive-include packaging *
recursive-include test/ansible_test *.py Makefile
recursive-include test/integration *
recursive-include test/lib/ansible_test/config *.yml *.template
recursive-include test/lib/ansible_test/_data *.cfg *.ini *.ps1 *.txt *.yml coveragerc
recursive-include test/lib/ansible_test/_util *.cfg *.json *.ps1 *.psd1 *.py *.sh *.txt *.yml
recursive-include test/lib/ansible_test/_util/controller/sanity/validate-modules validate-modules
recursive-include test/sanity *.json *.py *.txt
recursive-include test/support *.py *.ps1 *.psm1 *.cs
exclude test/sanity/code-smell/botmeta.*
recursive-include test/units *
graft examples/playbooks
include packaging/distutils/setup.py
recursive-include docs *
recursive-include library *
include Makefile
include MANIFEST.in
include changelogs/CHANGELOG*.rst
include changelogs/changelog.yaml
recursive-include hacking/build_library *.py
include hacking/build-ansible.py

296
Makefile
View File

@ -1,85 +1,66 @@
#!/usr/bin/make
# WARN: gmake syntax
########################################################
# Makefile for Ansible
#
# useful targets:
# make clean ---------------- clean up
# make webdocs -------------- produce ansible doc at docs/docsite/_build/html
# make coredocs ------------- produce core doc at docs/docsite/_build/html
# 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 gettext -------------- produce POT files for docs
# make generate-po ---------- generate language specific po file
# make needs-translation ---- generate list of file with unstranlated or fuzzy string for a specific language
# make tests ---------------- run the tests (see https://docs.ansible.com/ansible/devel/dev_guide/testing_units.html for requirements)
# make tests ---------------- run the tests
# make pyflakes, make pep8 -- source code checks
########################################################
# variable section
NAME = ansible-core
NAME = ansible
OS = $(shell uname -s)
PREFIX ?= '/usr/local'
SDIST_DIR ?= 'dist'
# 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 ?= $(patsubst %.rst.in,%,$(wildcard ./docs/man/man1/ansible*.1.rst.in))
ifneq ($(shell which rst2man 2>/dev/null),)
ASCII2MAN = rst2man $< $@
else ifneq ($(shell which rst2man.py 2>/dev/null),)
ASCII2MAN = rst2man.py $< $@
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: rst2man from docutils command is not installed but is required to build $(MANPAGES)" && exit 1
ASCII2MAN = @echo "ERROR: AsciiDoc 'a2x' command is not installed but is required to build $(MANPAGES)" && exit 1
endif
PYTHON ?= python
GENERATE_CLI = hacking/build-ansible.py generate-man
PYTHON=python
SITELIB = $(shell $(PYTHON) -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")
# fetch version from project release.py as single source-of-truth
VERSION := $(shell $(PYTHON) packaging/release/versionhelper/version_helper.py --raw || echo error)
ifeq ($(findstring error,$(VERSION)), error)
$(error "version_helper failed")
endif
# 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="%ci")
GIT_HASH := $(shell git log -n 1 --format="%h")
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD | sed 's/[-_.\/]//g')
GITINFO = .$(GIT_HASH).$(GIT_BRANCH)
else
GITINFO = ""
GIT_DATE := $(shell git log -n 1 --format="%ai")
endif
ifeq ($(shell echo $(OS) | egrep -c 'Darwin|FreeBSD|OpenBSD|DragonFly'),1)
DATE := $(shell date -j -r $(shell git log -n 1 --format="%ct") +%Y%m%d%H%M)
CPUS ?= $(shell sysctl hw.ncpu|awk '{print $$2}')
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)
CPUS ?= $(shell nproc)
endif
# Intenationalisation and Localisation
LANGUAGES ?=
# DEB build parameters
DEBUILD_BIN ?= debuild
DEBUILD_OPTS = --source-option="-I"
DPUT_BIN ?= dput
DPUT_OPTS ?=
DEB_DATE := $(shell LC_TIME=C date +"%a, %d %b %Y %T %z")
DEB_VERSION ?= $(shell $(PYTHON) packaging/release/versionhelper/version_helper.py --debversion)
ifeq ($(OFFICIAL),yes)
DEB_RELEASE ?= $(shell $(PYTHON) packaging/release/versionhelper/version_helper.py --debrelease)ppa
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 ?= 100.git$(DATE)$(GITINFO)
DEB_RELEASE = 0.git$(DATE)
# Do not sign unofficial builds
DEBUILD_OPTS += -uc -us
DPUT_OPTS += -u
@ -89,161 +70,157 @@ DEB_PPA ?= ppa
# Choose the desired Ubuntu release: lucid precise saucy trusty
DEB_DIST ?= unstable
# pbuilder parameters
PBUILDER_ARCH ?= amd64
PBUILDER_CACHE_DIR = /var/cache/pbuilder
PBUILDER_BIN ?= pbuilder
PBUILDER_OPTS ?= --debootstrapopts --variant=buildd --architecture $(PBUILDER_ARCH) --debbuildopts -b
# RPM build parameters
RPMSPECDIR= packaging/rpm
RPMSPEC = $(RPMSPECDIR)/ansible.spec
RPMDIST = $(shell rpm --eval '%{?dist}')
RPMRELEASE = 1
ifeq ($(OFFICIAL),)
RPMRELEASE = 0.git$(DATE)
endif
RPMNVR = "$(NAME)-$(VERSION)-$(RPMRELEASE)$(RPMDIST)"
# ansible-test parameters
ANSIBLE_TEST ?= bin/ansible-test
TEST_FLAGS ?=
# MOCK build parameters
MOCK_BIN ?= mock
MOCK_CFG ?=
# ansible-test units parameters (make test / make test-py3)
PYTHON_VERSION ?= $(shell python2 -c 'import sys; print("%s.%s" % sys.version_info[:2])')
PYTHON3_VERSION ?= $(shell python3 -c 'import sys; print("%s.%s" % sys.version_info[:2])')
# ansible-test integration parameters (make integration)
IMAGE ?= centos7
TARGET ?=
NOSETESTS ?= nosetests
########################################################
.PHONY: all
all: clean python
.PHONY: tests
tests:
$(ANSIBLE_TEST) units -v --python $(PYTHON_VERSION) $(TEST_FLAGS)
PYTHONPATH=./lib ANSIBLE_LIBRARY=./library $(NOSETESTS) -d -w test/units -v
.PHONY: tests-py3
tests-py3:
$(ANSIBLE_TEST) units -v --python $(PYTHON3_VERSION) $(TEST_FLAGS)
authors:
sh hacking/authors.sh
.PHONY: integration
integration:
$(ANSIBLE_TEST) integration -v --docker $(IMAGE) $(TARGET) $(TEST_FLAGS)
# Regenerate %.1.rst if %.1.rst.in has been modified more
# recently than %.1.rst.
%.1.rst: %.1.rst.in
# Regenerate %.1.asciidoc if %.1.asciidoc.in has been modified more
# recently than %.1.asciidoc.
%.1.asciidoc: %.1.asciidoc.in
sed "s/%VERSION%/$(VERSION)/" $< > $@
rm $<
# Regenerate %.1 if %.1.rst or release.py has been modified more
# recently than %.1. (Implicitly runs the %.1.rst recipe)
%.1: %.1.rst lib/ansible/release.py
# 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)
.PHONY: clean
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
rm -rf lib/ansible*.egg-info/
@echo "Cleaning up byte compiled python stuff"
find . -type f -regex ".*\.py[co]$$" -delete
find . -type d -name "__pycache__" -delete
@echo "Cleaning up editor backup files"
find . -type f -not -path ./test/units/inventory_test_data/group_vars/noparse/all.yml~ \( -name "*~" -or -name "#*" \) -delete
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 "*.rst" -delete
find ./docs/man -type f -name "*.asciidoc" -delete
find ./docs/man/man3 -type f -name "*.3" -delete
rm -f ./docs/man/man1/*
@echo "Cleaning up output from test runs"
rm -rf test/test_data
rm -rf logs/
rm -rf .cache/
rm -f test/units/.coverage*
rm -rf test/results/*/*
find test/ -type f -name '*.retry' -delete
@echo "Cleaning up symlink cache"
rm -f SYMLINK_CACHE.json
@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 docsite"
$(MAKE) -C docs/docsite clean
@echo "Cleaning up authors file"
rm -f AUTHORS.TXT
.PHONY: python
python:
$(PYTHON) setup.py build
.PHONY: install
install:
$(PYTHON) setup.py install
install_manpages:
gzip -9 $(wildcard ./docs/man/man1/ansible*.1)
cp $(wildcard ./docs/man/man1/ansible*.1.gz) $(PREFIX)/man/man1/
sdist: clean docs
$(PYTHON) setup.py sdist
.PHONY: sdist_check
sdist_check:
$(PYTHON) -c 'import setuptools, sys; sys.exit(int(not (tuple(map(int, setuptools.__version__.split("."))) > (39, 2, 0))))'
$(PYTHON) packaging/sdist/check-link-behavior.py
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
.PHONY: sdist
sdist: sdist_check clean docs
_ANSIBLE_SDIST_FROM_MAKEFILE=1 $(PYTHON) setup.py sdist --dist-dir=$(SDIST_DIR)
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 "#############################################"
# Official releases generate the changelog as the last commit before the release.
# Snapshots shouldn't result in new checkins so the changelog is generated as
# part of creating the tarball.
.PHONY: snapshot
snapshot: sdist_check clean docs changelog
_ANSIBLE_SDIST_FROM_MAKEFILE=1 $(PYTHON) setup.py sdist --dist-dir=$(SDIST_DIR)
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 "#############################################"
.PHONY: sdist_upload
sdist_upload: clean docs
$(PYTHON) setup.py sdist upload 2>&1 |tee upload.log
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 "#############################################"
.PHONY: changelog
changelog:
PYTHONPATH=./lib antsibull-changelog release -vv --use-ansible-doc && PYTHONPATH=./lib antsibull-changelog generate -vv --use-ansible-doc
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 "#############################################"
.PHONY: debian
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|%VERSION%|$(DEB_VERSION)|g;s|%RELEASE%|$(DEB_RELEASE)|;s|%DIST%|$${DIST}|g;s|%DATE%|$(DEB_DATE)|g" deb-build/$${DIST}/$(NAME)-$(VERSION)/debian/changelog ; \
sed -ie "s#^$(NAME) (\([^)]*\)) \([^;]*\);#ansible (\1-$(DEB_RELEASE)~$${DIST}) $${DIST};#" deb-build/$${DIST}/$(NAME)-$(VERSION)/debian/changelog ; \
done
.PHONY: deb
deb: deb-src
@for DIST in $(DEB_DIST) ; do \
PBUILDER_OPTS="$(PBUILDER_OPTS) --distribution $${DIST} --basetgz $(PBUILDER_CACHE_DIR)/$${DIST}-$(PBUILDER_ARCH)-base.tgz --buildresult $(CURDIR)/deb-build/$${DIST}" ; \
$(PBUILDER_BIN) create $${PBUILDER_OPTS} --othermirror "deb http://archive.ubuntu.com/ubuntu $${DIST} universe" ; \
$(PBUILDER_BIN) update $${PBUILDER_OPTS} ; \
$(PBUILDER_BIN) build $${PBUILDER_OPTS} deb-build/$${DIST}/$(NAME)_$(DEB_VERSION)-$(DEB_RELEASE)~$${DIST}.dsc ; \
done
@echo "#############################################"
@echo "Ansible DEB artifacts:"
@for DIST in $(DEB_DIST) ; do \
echo deb-build/$${DIST}/$(NAME)_$(DEB_VERSION)-$(DEB_RELEASE)~$${DIST}_amd64.changes ; \
done
@echo "#############################################"
# Build package outside of pbuilder, with locally installed dependencies.
# Install BuildRequires as noted in packaging/debian/control.
.PHONY: local_deb
local_deb: debian
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)_$(DEB_VERSION)-$(DEB_RELEASE)~$${DIST}_amd64.changes ; \
echo deb-build/$${DIST}/$(NAME)_$(VERSION)-$(DEB_RELEASE)~$${DIST}_amd64.changes ; \
done
@echo "#############################################"
.PHONY: deb-src
deb-src: debian
@for DIST in $(DEB_DIST) ; do \
(cd deb-build/$${DIST}/$(NAME)-$(VERSION)/ && $(DEBUILD) -S) ; \
@ -251,62 +228,23 @@ deb-src: debian
@echo "#############################################"
@echo "Ansible DEB artifacts:"
@for DIST in $(DEB_DIST) ; do \
echo deb-build/$${DIST}/$(NAME)_$(DEB_VERSION)-$(DEB_RELEASE)~$${DIST}_source.changes ; \
echo deb-build/$${DIST}/$(NAME)_$(VERSION)-$(DEB_RELEASE)~$${DIST}_source.changes ; \
done
@echo "#############################################"
.PHONY: deb-upload
deb-upload: deb
@for DIST in $(DEB_DIST) ; do \
$(DPUT_BIN) $(DPUT_OPTS) $(DEB_PPA) deb-build/$${DIST}/$(NAME)_$(DEB_VERSION)-$(DEB_RELEASE)~$${DIST}_amd64.changes ; \
$(DPUT_BIN) $(DPUT_OPTS) $(DEB_PPA) deb-build/$${DIST}/$(NAME)_$(VERSION)-$(DEB_RELEASE)~$${DIST}_amd64.changes ; \
done
.PHONY: deb-src-upload
deb-src-upload: deb-src
@for DIST in $(DEB_DIST) ; do \
$(DPUT_BIN) $(DPUT_OPTS) $(DEB_PPA) deb-build/$${DIST}/$(NAME)_$(DEB_VERSION)-$(DEB_RELEASE)~$${DIST}_source.changes ; \
$(DPUT_BIN) $(DPUT_OPTS) $(DEB_PPA) deb-build/$${DIST}/$(NAME)_$(VERSION)-$(DEB_RELEASE)~$${DIST}_source.changes ; \
done
.PHONY: epub
epub:
(cd docs/docsite/; CPUS=$(CPUS) $(MAKE) epub)
# for arch or gentoo, read instructions in the appropriate 'packaging' subdirectory directory
.PHONY: webdocs
webdocs:
(cd docs/docsite/; CPUS=$(CPUS) $(MAKE) docs)
.PHONY: coredocs
coredocs:
(cd docs/docsite/; CPUS=$(CPUS) $(MAKE) coredocs)
webdocs: $(MANPAGES)
(cd docsite/; make docs)
.PHONY: gettext
gettext:
(cd docs/docsite/; CPUS=$(CPUS) $(MAKE) gettext)
.PHONY: generate-po
generate-po:
(cd docs/docsite/; CPUS=$(CPUS) LANGUAGES=$(LANGUAGES) $(MAKE) generate-po)
.PHONY: needs-translation
needs-translation:
(cd docs/docsite/; CPUS=$(CPUS) LANGUAGES=$(LANGUAGES) $(MAKE) needs-translation)
.PHONY: linkcheckdocs
linkcheckdocs:
(cd docs/docsite/; CPUS=$(CPUS) $(MAKE) linkcheckdocs)
.PHONY: generate_rst
generate_rst: lib/ansible/cli/*.py
mkdir -p ./docs/man/man1/ ; \
$(PYTHON) $(GENERATE_CLI) --template-file=docs/templates/man.j2 --output-dir=docs/man/man1/ --output-format man lib/ansible/cli/*.py
docs: generate_rst
$(MAKE) $(MANPAGES)
.PHONY: alldocs
alldocs: docs webdocs
version:
@echo $(VERSION)
docs: $(MANPAGES)

48
README.md Normal file
View File

@ -0,0 +1,48 @@
[![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
======
Michael DeHaan -- michael@ansible.com
[Ansible, Inc](http://ansible.com)

View File

@ -1,115 +0,0 @@
|PyPI version| |Docs badge| |Chat badge| |Build Status| |Code Of Conduct| |Mailing Lists| |License| |CII Best Practices|
*******
Ansible
*******
Ansible is a radically simple IT automation system. It handles
configuration management, application deployment, cloud provisioning,
ad-hoc task execution, network automation, and multi-node orchestration. Ansible makes complex
changes like zero-downtime rolling updates with load balancers easy. More information on the Ansible `website <https://ansible.com/>`_.
Design Principles
=================
* Have an extremely simple setup process with a minimal learning curve.
* Manage machines quickly and in parallel.
* Avoid custom-agents and additional open ports, be agentless by
leveraging the existing SSH daemon.
* Describe infrastructure in a language that is both machine and human
friendly.
* Focus on security and easy auditability/review/rewriting of content.
* Manage new remote machines instantly, without bootstrapping any
software.
* Allow module development in any dynamic language, not just Python.
* Be usable as non-root.
* Be the easiest IT automation system to use, ever.
Use Ansible
===========
You can install a released version of Ansible with ``pip`` or a package manager. See our
`installation guide <https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html>`_ for details on installing Ansible
on a variety of platforms.
Power users and developers can run the ``devel`` branch, which has the latest
features and fixes, directly. Although it is reasonably stable, you are more likely to encounter
breaking changes when running the ``devel`` branch. We recommend getting involved
in the Ansible community if you want to run the ``devel`` branch.
Get Involved
============
* Read `Community
Information <https://docs.ansible.com/ansible/latest/community>`_ 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.
* Join a `Working Group
<https://github.com/ansible/community/wiki>`_, an organized community devoted to a specific technology domain or platform.
* Submit a proposed code update through a pull request to the ``devel`` branch.
* Talk to us before making larger changes
to avoid duplicate efforts. This not only helps everyone
know what is going on, but it also helps save time and effort if we decide
some changes are needed.
* For a list of email lists, IRC channels and Working Groups, see the
`Communication page <https://docs.ansible.com/ansible/latest/community/communication.html>`_
Coding Guidelines
=================
We document our Coding Guidelines in the `Developer Guide <https://docs.ansible.com/ansible/devel/dev_guide/>`_. We particularly suggest you review:
* `Contributing your module to Ansible <https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_checklist.html>`_
* `Conventions, tips, and pitfalls <https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_best_practices.html>`_
Branch Info
===========
* The ``devel`` branch corresponds to the release actively under development.
* The ``stable-2.X`` branches correspond to stable releases.
* Create a branch based on ``devel`` and set up a `dev environment <https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_general.html#common-environment-setup>`_ if you want to open a PR.
* See the `Ansible release and maintenance <https://docs.ansible.com/ansible/devel/reference_appendices/release_and_maintenance.html>`_ page for information about active branches.
Roadmap
=======
Based on team and community feedback, an initial roadmap will be published for a major or minor version (ex: 2.7, 2.8).
The `Ansible Roadmap page <https://docs.ansible.com/ansible/devel/roadmap/>`_ details what is planned and how to influence the roadmap.
Authors
=======
Ansible was created by `Michael DeHaan <https://github.com/mpdehaan>`_
and has contributions from over 5000 users (and growing). Thanks everyone!
`Ansible <https://www.ansible.com>`_ is sponsored by `Red Hat, Inc.
<https://www.redhat.com>`_
License
=======
GNU General Public License v3.0 or later
See `COPYING <COPYING>`_ to see the full text.
.. |PyPI version| image:: https://img.shields.io/pypi/v/ansible-core.svg
:target: https://pypi.org/project/ansible-core
.. |Docs badge| image:: https://img.shields.io/badge/docs-latest-brightgreen.svg
:target: https://docs.ansible.com/ansible/latest/
.. |Build Status| image:: https://dev.azure.com/ansible/ansible/_apis/build/status/CI?branchName=devel
:target: https://dev.azure.com/ansible/ansible/_build/latest?definitionId=20&branchName=devel
.. |Chat badge| image:: https://img.shields.io/badge/chat-IRC-brightgreen.svg
:target: https://docs.ansible.com/ansible/latest/community/communication.html
.. |Code Of Conduct| image:: https://img.shields.io/badge/code%20of%20conduct-Ansible-silver.svg
:target: https://docs.ansible.com/ansible/latest/community/code_of_conduct.html
:alt: Ansible Code of Conduct
.. |Mailing Lists| image:: https://img.shields.io/badge/mailing%20lists-Ansible-orange.svg
:target: https://docs.ansible.com/ansible/latest/community/communication.html#mailing-list-information
:alt: Ansible mailing lists
.. |License| image:: https://img.shields.io/badge/license-GPL%20v3.0-brightgreen.svg
:target: COPYING
:alt: Repository License
.. |CII Best Practices| image:: https://bestpractices.coreinfrastructure.org/projects/2372/badge
:target: https://bestpractices.coreinfrastructure.org/projects/2372
:alt: Ansible CII Best Practices certification

48
RELEASES.txt Normal file
View File

@ -0,0 +1,48 @@
Ansible Releases at a Glance
============================
Active Development
++++++++++++++++++
1.7 "Summer Nights" -------- CURRENT DEVEL BRANCH
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

1
VERSION Normal file
View File

@ -0,0 +1 @@
1.6.5

View File

@ -1 +0,0 @@
../lib/ansible/cli/scripts/ansible_cli_stub.py

231
bin/ansible Executable file
View File

@ -0,0 +1,231 @@
#!/usr/bin/env python
# (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
#
# 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 <http://www.gnu.org/licenses/>.
########################################################
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 <host-pattern> [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")
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 options.vault_password_file:
this_path = os.path.expanduser(options.vault_password_file)
try:
f = open(this_path, "rb")
tmp_vault_pass=f.read().strip()
f.close()
except (OSError, IOError), e:
raise errors.AnsibleError("Could not read %s: %s" % (this_path, e))
if not options.ask_vault_pass:
vault_pass = tmp_vault_pass
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")
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)

View File

@ -1 +0,0 @@
ansible

View File

@ -1 +0,0 @@
../lib/ansible/cli/scripts/ansible_connection_cli_stub.py

View File

@ -1 +0,0 @@
ansible

View File

@ -1 +0,0 @@
ansible

291
bin/ansible-doc Executable file
View File

@ -0,0 +1,291 @@
#!/usr/bin/env python
# (c) 2012, Jan-Piet Mens <jpmens () gmail.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
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 + ")"
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 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)
pass
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()

View File

@ -1 +0,0 @@
ansible

814
bin/ansible-galaxy Executable file
View File

@ -0,0 +1,814 @@
#!/usr/bin/env python
########################################################################
#
# (C) 2013, James Cammarata <jcammarata@ansible.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
########################################################################
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 <command> --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()
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
if member.isreg():
member.name = "/".join(member.name.split("/")[1:])
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()

View File

@ -1 +0,0 @@
ansible

View File

@ -1 +0,0 @@
ansible

324
bin/ansible-playbook Executable file
View File

@ -0,0 +1,324 @@
#!/usr/bin/env python
# (C) 2012, Michael DeHaan, <michael.dehaan@gmail.com>
# 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 <http://www.gnu.org/licenses/>.
#######################################################
#__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")
inventory = ansible.inventory.Inventory(options.inventory)
inventory.subset(options.subset)
if len(inventory.list_hosts()) == 0:
raise errors.AnsibleError("provided hosts list is empty")
sshpass = None
sudopass = None
su_pass = None
vault_pass = None
if not options.listhosts and not options.syntax and not options.listtasks:
options.ask_pass = options.ask_pass or C.DEFAULT_ASK_PASS
options.ask_vault_pass = options.ask_vault_pass or C.DEFAULT_ASK_VAULT_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)
options.sudo_user = options.sudo_user or C.DEFAULT_SUDO_USER
options.su_user = options.su_user or C.DEFAULT_SU_USER
if options.vault_password_file:
this_path = os.path.expanduser(options.vault_password_file)
try:
f = open(this_path, "rb")
tmp_vault_pass=f.read().strip()
f.close()
except (OSError, IOError), e:
raise errors.AnsibleError("Could not read %s: %s" % (this_path, e))
if not options.ask_vault_pass:
vault_pass = tmp_vault_pass
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)
# run all playbooks specified on the command line
for playbook in args:
# let inventory know which playbooks are using so it can know the basedirs
inventory.set_playbook_basedir(os.path.dirname(playbook))
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)
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)

View File

@ -1 +0,0 @@
ansible

230
bin/ansible-pull Executable file
View File

@ -0,0 +1,230 @@
#!/usr/bin/env python
# (c) 2012, Stephen Fromm <sfromm@gmail.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
# 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")
inv_opts = 'localhost,'
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)

View File

@ -1 +0,0 @@
../test/lib/ansible_test/_util/target/cli/ansible_test_cli_stub.py

View File

@ -1 +0,0 @@
ansible

219
bin/ansible-vault Executable file
View File

@ -0,0 +1,219 @@
#!/usr/bin/env python
# (c) 2014, James Tanner <tanner.jc@gmail.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
# 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
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 <command> --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")
# 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 _read_password(filename):
f = open(filename, "rb")
data = f.read()
f.close
data = data.strip()
return data
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 = _read_password(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 = _read_password(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 = _read_password(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 = _read_password(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 = _read_password(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()
# 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()

View File

@ -1,630 +0,0 @@
====================================================
ansible-core 2.12 "Dazed and Confused" Release Notes
====================================================
.. contents:: Topics
v2.12.6
=======
Release Summary
---------------
| Release Date: 2022-05-23
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
Bugfixes
--------
- Prevent losing unsafe on results returned from lookups (https://github.com/ansible/ansible/issues/77535)
- arg_spec - Fix incorrect ``no_log`` warning when a parameter alias is used (https://github.com/ansible/ansible/pull/77576)
- plugin loader will now load config data for plugin by name instead of by file to avoid issues with the same file being loaded under different names (fqcn + short name).
- variablemanager, more efficient read of vars files
v2.12.5
=======
Release Summary
---------------
| Release Date: 2022-04-25
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
Bugfixes
--------
- Ansible.ModuleUtils.SID - Use user principal name as is for lookup in the ``Convert-ToSID`` function - https://github.com/ansible/ansible/issues/77316
- Fix traceback when installing a collection from a git repository and git is not installed (https://github.com/ansible/ansible/issues/77479).
- ansible-test - Correctly detect when running as the ``root`` user (UID 0) on the origin host. The result of the detection was incorrectly being inverted.
- ansible-test - Fix skipping of tests marked ``needs/python`` on the origin host.
- ansible-test - Fix skipping of tests marked ``needs/root`` on the origin host.
- ansible-test compile sanity test - do not crash if a column could not be determined for an error (https://github.com/ansible/ansible/pull/77465).
- hostname - use ``file_get_content()`` to read the file containing the host name in the ``FileStrategy.get_permanent_hostname()`` method. This prevents a ``TypeError`` from being raised when the strategy is used (https://github.com/ansible/ansible/issues/77025).
- script - skip in check mode since the plugin cannot determine if a change will occur.
- shell/command - only skip in check mode if the options `creates` and `removes` are both None.
- winrm - Ensure ``kinit`` is run with the same ``PATH`` env var as the Ansible process
v2.12.4
=======
Release Summary
---------------
| Release Date: 2022-03-28
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
Bugfixes
--------
- Add a YAML representer for ``NativeJinjaText``
- Add a YAML representer for ``NativeJinjaUnsafeText``
- AnsiballZ - Ensure we use the full python package in the module cache filename to avoid a case where ``collections:`` is used to execute a module via short name, where the short name duplicates another module from ``ansible.builtin`` or another collection that was executed previously.
- Fix collection filter/test plugin redirects (https://github.com/ansible/ansible/issues/77192).
- ansible-galaxy collection verify - display files/directories not included in the FILES.json as modified content.
- ansible-test - Fix ``windows-integration`` and ``network-integration`` when used with the ``--docker`` option and user-provided inventory.
- extend timeout for ansible-galaxy when communicating with the galaxy server api, and apply it to all interactions with the api
- first_found - fix to allow for spaces in file names (https://github.com/ansible/ansible/issues/77136)
- unarchive - the ``io_buffer_size`` option added in 2.12 was not accepted by the module (https://github.com/ansible/ansible/pull/77271).
v2.12.3
=======
Release Summary
---------------
| Release Date: 2022-02-28
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
Minor Changes
-------------
- The collection loader now reports a Python warning if an attempt is made to install the Ansible collection loader a second time. Previously this condition was reported using an Ansible warning.
- ansible-test - Installation of ``cryptography`` is no longer version constrained when ``openssl`` 1.1.0 or later is installed.
- ansible-test - Requirements for the plugin import test are now frozen.
- ansible-test - The ``pip`` and ``wheel`` packages are removed from all sanity test virtual environments after installation completes to reduce their size. Previously they were only removed from the environments used for the ``import`` sanity test.
- ansible-test - The hash for all managed sanity test virtual environments has changed. Containers that include ``ansible-test sanity --prime-venvs`` will need to be rebuilt to continue using primed virtual environments.
- ansible-test - Update ``pip`` used to bootstrap remote FreeBSD instances from version 20.3.4 to 21.3.1.
- ansible-test - Update the ``alpine`` container to version 3.3.0. This updates the base image from 3.14.2 to 3.15.0, which includes support for installing binary wheels using pip.
- ansible-test - Update the ``galaxy`` test plugin to get its container from a copy on quay.io.
- ansible-test - Update the ``openshift`` test plugin to get its container from a copy on quay.io.
- junit callback - Add support for replacing the directory portion of out-of-tree relative task paths with a placeholder.
Bugfixes
--------
- ansible-test - All virtual environments managed by ansible-test are marked as usable after being bootstrapped, to avoid errors caused by use of incomplete environments. Previously this was only done for sanity tests. Existing environments from previous versions of ansible-test will be recreated on demand due to lacking the new marker.
- ansible-test - Fix the ``validate-modules`` sanity test to avoid double-loading the collection loader and possibly failing on import of the ``packaging`` module.
- ansible-test - Import ``yaml.cyaml.CParser`` instead of ``_yaml.CParser`` in the ``yamllint`` sanity test.
- ansible-test - Replace the directory portion of out-of-tree paths in JUnit files from integration tests with the ``out-of-tree:`` prefix.
- ansible-test - Sanity tests run with the ``--requirements` option for Python 2.x now install ``virtualenv`` when it is missing or too old. Previously it was only installed if missing. Version 16.7.12 is now installed instead of the latest version on Python 2.7.
- ansible-test - The ``import`` sanity test no longer reports errors about ``packaging`` being missing when testing collections.
- ansible-test - Update the ``default`` containers to version 4.2.0.
- ansible-test - Use https://ci-files.testing.ansible.com/ for instance bootstrapping instead of an S3 endpoint.
- ansible-test - Use relative paths in JUnit files generated during integration test runs.
- ansible-test - Virtual environments managed by ansible-test now use consistent versions of ``pip``, ``setuptools`` and ``wheel``. This avoids issues with virtual environments containing outdated or dysfunctional versions of these tools. The initial bootstrapping of ``pip`` is done by ansible-test from an HTTPS endpoint instead of creating the virtual environment with it already present.
- cleaning facts will now only warn about the variable name and not post the content, which can be undesireable to disclose
- correctly inherit vars from parent in block (https://github.com/ansible/ansible/issues/75286).
- gather_facts action now handles the move of base connection plugin types into collections to add/prevent subset argument correctly
- junit callback - Fix traceback during automatic fact gathering when using relative paths.
- junit callback - Fix unicode error when handling non-ASCII task paths.
- ssh connection now uses more correct host source as play_context can ignore loop/delegation variations.
- task_executor reverts the change to push facts into delegated vars on loop finalization as result managing code already handles this and was duplicating effort to wrong result.
- template lookup - restore inadvertently deleted default for ``convert_data`` (https://github.com/ansible/ansible/issues/77004)
- unarchive - Make extraction work when the LANGUAGE environment variable is set to a non-English locale.
v2.12.2
=======
Release Summary
---------------
| Release Date: 2022-01-31
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
Bugfixes
--------
- Fix ``AttributeError`` when providing password file via ``--connection-password-file`` (https://github.com/ansible/ansible/issues/76530)
- Fix ``end_play`` to end the current play only (https://github.com/ansible/ansible/issues/76672)
- Templating - Ensure we catch exceptions when getting ``.filters`` and ``.tests`` attributes on their respective plugins and properly error, instead of aborting which results in no filters being added to the jinja2 environment
- ``Templar.copy_with_new_env`` - set the ``finalize`` method of the new ``Templar`` object for the new environment (https://github.com/ansible/ansible/issues/76379)
- ansible-config avoid showing _terms and _input when --only-changed.
- ansible-galaxy - Fix using the '--ignore-certs' option when there is no server-specific configuration for the Galaxy server.
- ansible-galaxy collection build - Ignore any existing ``MANIFEST.json`` and ``FILES.json`` in the root directory when building a collection.
- ansible-test - Fix the ``import`` sanity test to work properly when Ansible's built-in vendoring support is in use.
- ansible-test - Fix traceback in the ``validate-modules`` sanity test when testing an Ansible module without any callables.
- ansible-test - Fix traceback when running from an install and delegating execution to a different Python interpreter.
- ansible-test - Show an error message instead of a traceback when running outside of a supported directory.
- ansible-test - Update help links to reference ``ansible-core`` instead of ``ansible``.
- ansible-test - Update unit tests to use the ``--forked`` option instead of the deprecated ``--boxed`` option.
- async - Improve performance of sending async callback events by never sending the full task through the queue (https://github.com/ansible/ansible/issues/76729)
- default callback - Ensure we compare FQCN also in lockstep logic, to ensure using the FQCN of a strategy plugin triggers the correct behavior in the default callback plugin. (https://github.com/ansible/ansible/issues/76782)
- hostname - Do not require SystemdStrategy subclasses for every distro (https://github.com/ansible/ansible/issues/76792)
- include_vars, properly initialize variable as there is corner case in which it can end up referenced and not defined
- ssh connection - properly quote controlpersist path given by user to avoid issues with spaces and other characters
- ssh connection avoid parsing ssh cli debug lines as they can match expected output at high verbosities.
- sudo become plugin, fix handling of non interactive flags, previous substitution was too naive
- unarchive - Fix zip archive file listing that caused issues with content postprocessing (https://github.com/ansible/ansible/issues/76067).
- yum - prevent storing unnecessary cache data by running `yum makecache fast` (https://github.com/ansible/ansible/issues/76336)
v2.12.1
=======
Release Summary
---------------
| Release Date: 2021-12-06
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
Minor Changes
-------------
- jinja2_native - keep same behavior on Python 3.10.
Bugfixes
--------
- Ansible.ModuleUtils.LinkUtil - Ignore the ``LIB`` environment variable when loading the ``LinkUtil`` code
- ansible-test - Automatic target requirements installation is now based on the target environment instead of the controller environment.
- ansible-test - Fix Python real prefix detection when running in a ``venv`` virtual environment.
- ansible-test - Fix installation and usage of ``pyyaml`` requirement for the ``import`` sanity test for collections.
- ansible-test - Fix traceback in ``import`` sanity test on Python 2.7 when ``pip`` is not available.
- ansible-test - Relocate constants to eliminate symlink.
- ansible-test - Target integration test requirements are now correctly installed for target environments running on the controller.
- ansible-test - Update the ``default`` containers to version 4.1.1, which includes the updated ``import`` sanity test requirements.
- ansible-test - Use the legacy collection loader for ``import`` sanity tests on target-only Python versions.
- set_fact/include_vars correctly handle delegation assignments within loops
- setup - detect docker container with check for ./dockerenv or ./dockinit (https://github.com/ansible/ansible/pull/74349).
- validate_argument_spec - Skip suboption validation if the top level option is an invalid type (https://github.com/ansible/ansible/issues/75612).
v2.12.0
=======
Release Summary
---------------
| Release Date: 2021-11-05
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
Major Changes
-------------
- Python Controller Requirement - Python 3.8 or newer is required for the control node (the machine that runs Ansible) (https://github.com/ansible/ansible/pull/74013)
- ansible-test - All "cloud" plugins which use containers can now be used with all POSIX and Windows hosts. Previously the plugins did not work with Windows at all, and support for hosts created with the ``--remote`` option was inconsistent.
- ansible-test - Collections can now specify controller and target specific integration test requirements and constraints. If provided, they take precedence over the previously available requirements and constraints files.
- ansible-test - Integration tests run with the ``integration`` command can now be executed on two separate hosts instead of always running on the controller. The target host can be one provided by ``ansible-test`` or by the user, as long as it is accessible using SSH.
- ansible-test - Most container features are now supported under Podman. Previously a symbolic link for ``docker`` pointing to ``podman`` was required.
- ansible-test - New ``--controller`` and ``--target`` / ``--target-python`` options have been added to allow more control over test environments.
- ansible-test - Python 3.8 - 3.10 are now required to run ``ansible-test``, thus matching the Ansible controller Python requirements. Older Python versions (2.6 - 2.7 and 3.5 - 3.10) can still be the target for relevant tests.
- ansible-test - SSH port forwarding and redirection is now used exclusively to make container ports available on non-container hosts. When testing on POSIX systems this requires SSH login as root. Previously SSH port forwarding was combined with firewall rules or other port redirection methods, with some platforms being unsupported.
- ansible-test - Sanity tests always run in isolated Python virtual environments specific to the requirements of each test. The environments are cached.
- ansible-test - Sanity tests are now separated into two categories, controller and target. All tests except ``import`` and ``compile`` are controller tests. The controller tests always run using the same Python version used to run ``ansible-test``. The target tests use the Python version(s) specified by the user, or all available Python versions.
- ansible-test - Sanity tests now use fully pinned requirements that are independent of each other and other test types.
- ansible-test - Tests run with the ``centos6`` and ``default`` test containers now use a PyPI proxy container to access PyPI when Python 2.6 is used. This allows tests running under Python 2.6 to continue functioning even though PyPI is discontinuing support for non-SNI capable clients.
- ansible-test - The ``future-import-boilerplate`` and ``metaclass-boilerplate`` sanity tests are limited to remote-only code. Additionally, they are skipped for collections which declare no support for Python 2.x.
- ansible-test - The ``import`` and ``compile`` sanity tests limit remote-only Python version checks to remote-only code.
- ansible-test - Unit tests for controller-only code now require Python 3.8 or later.
- ansible-test - Version neutral sanity tests now require Python 3.8 or later.
- junit callback - The ``junit_xml`` and ``ordereddict`` Python modules are no longer required to use the ``junit`` callback plugin.
Minor Changes
-------------
- Add ``end_batch`` meta task.
- Allow connection and become passwords to be set by file/executable script. Also document this was already the case for vault.
- CLI - Remove ``__requires__`` attribute for ``pkg_resources``
- Collections can define action_groups in ``meta/runtime.yml``.
- Introduce a config option to enable/disable emitting warning about Jinja2 version being old for ``jinja2_native``. The option is on by default, only in CI it is off.
- Make the code structure of ansible-doc's generic snippet feature more maintainable.
- On RHEL 9, CentOS Stream 9 etc., use /usr/bin/python3 as the default interpreter; /usr/libexec/platform-python is just a backwards-compatibility symbolic link there.
- PowerShell - Added support for optional module_util imports by scanning for ``-Optional`` at the end of the import declaration
- Python 2.6 Target Support - Deprecate Python 2.6 for targets, requiring Python 2.7 or newer. ``ansible-core==2.13`` will drop support for Python 2.6. (https://github.com/ansible/ansible/pull/74165)
- Task - Add a resolved_action attribute for Task objects to get the final resolved plugin.
- Templar - remove ``_fail_on_lookup_errors`` and ``_fail_on_filter_errors`` instance variables that were never used. (https://github.com/ansible/ansible/pull/73785)
- The AnsiballZ Python wrapper now changes the working directory to ``~`` or ``/`` if the current one is not accessible. This allows become to drop privileges on macOS when using pipelining.
- Update test container ansible-core-test-container to version 3.6.0
- Update test container ansible-core-test-container to version 3.7.0
- Update test container default-test-container to version 3.6.0
- Update test container default-test-container to version 3.7.0
- Update vendored copy of ``six`` to 1.16.0 to eliminate warnings for deprecated python loader methods in Python 3.10+ (https://github.com/ansible/ansible/issues/74659)
- Update vendored copy of distro to 1.6.0
- Vendor ``distutils.version`` due to it's deprecation in Python 3.10 and impending removal in Python 3.12 (https://github.com/ansible/ansible/issues/74599)
- YAML parsing - Create common utils for loading and dumping YAML that prefer the C extensions if available
- ``include_role`` - Allow use of ``omit`` in the ``from_*`` arguments (https://github.com/ansible/ansible/issues/66349)
- ``uri``/``get_url`` - Expose ``unredirected_headers`` to modules to allow user control
- `ansible.plugins.callback.CallbackBase.host_label()` has been factored out as a static method (https://github.com/ansible/ansible/pull/73814).
- action_groups can include actions from other groups by using the special ``metadata`` dictionary field.
- add a quick short circuit when checking if a string is a template to improve performance on large strings (https://github.com/ansible/ansible/issues/74336)
- add host label to retry print statements
- added new function to module utils to choose best possible locale.
- adds the ``undef`` keyword to the templating environment. This allows for directly creating Undefined values in templates. It is most useful for providing a hint for variables which must be overridden.
- ansbile-doc now also shows snippets for inventory and lookup, adding to existing modules.
- ansible adhoc, clarified the help to some options, also added some comments to code.
- ansible-cli - remove unnecessary trailing space in ``ansible --version`` (https://github.com/ansible/ansible/issues/74875).
- ansible-config can now list and dump for specific documentable plugins by specifying them in the command line
- ansible-config has new 'init' option to create, highly commented, example configurations as ini (ansible.cfg), environment variables (shell) or Ansible variable files (YAML)
- ansible-config now supports displaying plugin configuration info.
- ansible-doc - ``version_added`` in ``attributes`` now comes with ``version_added_collection`` (https://github.com/ansible/ansible/pull/74602).
- ansible-doc - show ``version_added`` for the plugin/module itself in text output, and improve ``version_added`` formatting (https://github.com/ansible/ansible/pull/73602).
- ansible-doc now supports 'attributes' for plugins as per proposal.
- ansible-doc pretty cli options output.
- ansible-doc, improve handling of rstisms, try to make the display more meaningfull for the terminal users.
- ansible-galaxy - Allow specification of client_id override value for Keycloak Token (https://github.com/ansible/ansible/issues/75593).
- ansible-galaxy - Allow validate_certs to be configured for individual Galaxy servers (https://github.com/ansible/ansible/issues/75677).
- ansible-galaxy - Installing a collection from a git repository without specifying a version (or using the version ``HEAD``) will clone the repository using --depth=1.
- ansible-galaxy - Non-HTTP exceptions from Galaxy servers are now a warning and only fatal if the collection to download|install|verify is not available from any of the servers (https://github.com/ansible/ansible/issues/75443).
- ansible-test - A new ``base`` test container is available. It is similar to the ``default`` test container, but contains no pre-installed Python packages other than ``pip`` and its dependencies.
- ansible-test - Add RHEL 8.4 as a remote.
- ansible-test - Add ``--prime-venvs`` option to create virtual environments without running tests.
- ansible-test - Add constraint for ``decorator`` for Python versions prior to 3.5.
- ansible-test - Add support for Windows Server 2022.
- ansible-test - Add support for an ansible-test configuration file in collections under ``tests/config.yml``.
- ansible-test - Add support for testing with Python 3.10.
- ansible-test - Added a ``--prime-containers`` option to support downloading containers without running tests.
- ansible-test - Adding DigitalOcean cloud support to ansible-test (https://github.com/ansible/ansible/pull/74222).
- ansible-test - All "cloud" plugins have been refactored for more consistency. For those that use docker containers, management of the containers has been standardized.
- ansible-test - All "cloud" plugins now use fixed hostnames and ports in tests. Previously some tests used IP addresses and/or randomly assigned ports.
- ansible-test - Changes made to the ``hosts`` file on test systems are now done using an Ansible playbook for both POSIX and Windows systems. Changes are applied before a test target runs and are reverted after the test target finishes.
- ansible-test - Clean up code in the cloud plugins.
- ansible-test - Collections can declare their remote-only code (modules/module_utils and related tests) as controller-only.
- ansible-test - Collections can limit the Python versions used for testing their remote-only code (modules/module_utils and related tests).
- ansible-test - Command line help has been updated to hide the ``--remote`` option (and related options) when the user lacks an API key to use the feature.
- ansible-test - Constraints provided by ``ansible-test`` for Python package installs have been reduced.
- ansible-test - Default settings are now applied to unknown versions of known ``--remote`` platforms.
- ansible-test - Distribution specific test containers have been updated to version 3.0.0.
- ansible-test - Environment checking (``pip``, ``python``, ``~/.ssh/known_hosts``, etc.) is no longer performed when running integration tests.
- ansible-test - Environment variables exposed by "cloud" plugins are now available to the controller for role based tests. Previously only script based tests had access to the exposed environment variables.
- ansible-test - Fedora 32 and 33 (``fedora32`` and ``fedora33``) containers have been updated and now allow for ssh in more container environments.
- ansible-test - Fedora 34 (``fedora34``) container has been added.
- ansible-test - Installation of ``cryptography`` no longer occurs when it is already installed. This avoids downgrading existing OS packages.
- ansible-test - Minor code cleanup.
- ansible-test - More efficient string splitting.
- ansible-test - Most scripts used internally by ``ansible-test`` no longer have a shebang or the executable bit set.
- ansible-test - Move code from ``_data`` directory to ``_util`` directory.
- ansible-test - Relocate change classification code.
- ansible-test - Remove CI provider support for Shippable, now that the service has been discontinued.
- ansible-test - Remove check for legacy ``core`` and ``extras`` directories.
- ansible-test - Remove deprecated container ``fedora32``.
- ansible-test - Remove deprecated remote platforms ``freebsd/11.4`` and ``rhel/8.3```.
- ansible-test - Removed the warning filter for ``PyYAML`` in the ``import`` sanity test.
- ansible-test - Removed unused pip constraints. Collections may need to add their own constraints if they depended on any which were removed.
- ansible-test - Reorganize code for individual commands.
- ansible-test - Reorganize integration test implementation by command.
- ansible-test - Rewrite the ``compile`` sanity test to improve error handling and support Python 3.10.
- ansible-test - Sanity test warnings relating to Python version support have been improved.
- ansible-test - Set minimum version constraints for ``pytest``.
- ansible-test - Split out shell command implementation.
- ansible-test - The "injector" scripts are now generated at runtime to avoid issues with symlinks and shebangs.
- ansible-test - The HTTP Tester can now be used without the ``--docker`` or `--remote`` options. It still requires use of the ``docker`` command to run the container.
- ansible-test - The HTTP Tester has been converted to a "cloud" plugin and can now be requested using the ``cloud/httptester`` alias. The original ``needs/httptester`` alias is still supported for backwards compatibility.
- ansible-test - The ``--docker-keep-git`` option (used only for testing ansible-core) has been renamed to ``--keep-git``.
- ansible-test - The ``--python`` option can be used without another delegation option such as the ``--venv`` or ``--docker`` options.
- ansible-test - The ``ansible-test coverage`` commands ``combine``, ``report``, ``html`` and ``xml`` now support delegation.
- ansible-test - The ``default`` test container has been updated to version 3.4.0 and now uses Python 3.9 by default instead of Python 3.6.
- ansible-test - The ``docker run`` option ``--link`` is no longer used to connect test containers. As a result, changes are made to the ``/etc/hosts`` file as needed on all test containers. Previously containers which were used with the ``--link`` option did not require changes to the ``/etc/hosts`` file.
- ansible-test - The ``import`` sanity test now requires that Ansible modules guard instantiation of ``AnsibleModule`` with a ``if __name__ == '__main__'`` conditional, or equivalent logic.
- ansible-test - The ``import`` sanity test now requires that non-modules do not instantiate ``AnsibleModule`` on import.
- ansible-test - The ``validate-modules`` sanity test codes ``ansible-deprecated-module`` and ``collection-deprecated-module`` have been added.
- ansible-test - The ``validate-modules`` sanity test codes ``last-line-main-call``, ``missing-if-name-main`` and ``missing-main-call`` have been removed.
- ansible-test - The ``validate-modules`` sanity test no longer enforces the ``missing-if-name-main``, ``last-line-main-call`` or ``missing-main-call`` checks on non-deleted Ansible modules. Modules are still required to instantiate ``AnsibleModule`` when ``__name__ == '__main__'``.
- ansible-test - Unit tests are now run in separate contexts (``controller``, ``modules``, ``module_utils``), each using separate invocations of ``pytest``.
- ansible-test - Unit tests other than ``modules`` and ``module_utils`` are now run only on Python versions supported by the controller (Python 3.8+).
- ansible-test - Update ``typed-ast`` constraint to version 1.4.3 for compatibility with Python 3.10.
- ansible-test - Update distribution test containers from version 2.0.1 to 2.0.2.
- ansible-test - Update the Ansible Core and Ansible Collection default test containers to 3.2.0 and 3.2.2 respectively.
- ansible-test - Update the ``base`` and ``default`` containers from Python 3.10.0rc2 to 3.10.0.
- ansible-test - Update the ``import`` sanity test to avoid a new warning in Python 3.10.
- ansible-test - Update the ``runtime-metadata`` sanity test to handle a new warning on Python 3.10.
- ansible-test - Updated the ``default`` containers to version 4.0.1.
- ansible-test - Updated the help message for failed tests in the ``azure`` test plugin.
- ansible-test - Upgrade ``pylint`` to version 2.9.3 and update its dependencies to the latest versions as well.
- ansible-test - Using an unknown ``--docker`` or ``--remote`` environment now requires specifying a Python version.
- ansible-test - add freebsd/13.0 as a remote option.
- ansible-test - aws creates and exposes a new tiny_prefix variable to provide a shorter prefix for the AWS tests.
- ansible-test - display recent ``ssh`` debug logs after connection failures (https://github.com/ansible/ansible/pull/75374)
- ansible-test - validate-modules now properly checks ``attributes`` for plugins (https://github.com/ansible/ansible/pull/74602).
- ansible-test - virtualenv-isolated.sh is no longer provided. Prefer virtualenv.sh in its place.
- ansible-test validate-modules - enforce that ``_info`` and ``_facts`` modules set ``supports_check_mode=True`` (https://github.com/ansible/ansible/pull/75324).
- ansible-vault - remove support for ``PyCrypto`` (https://github.com/ansible/ansible/issues/72646)
- apt - added an ``allow_downgrade`` option to enable safe downgrade of packages without using ``force`` which doesn't verify signatures (https://github.com/ansible/ansible/issues/29451, https://github.com/ansible/ansible/pull/74852).
- apt, added a 'lock_timeout' to be more resilient when encountering the apt db already locked and handle it w/o haveing to rerun task.
- async tasks - the use of the task-level ``ANSIBLE_ASYNC_DIR`` variable within ``environment:`` is no longer valid. Use the shell configuration variable ``async_dir`` instead.
- async_wrapper, better reporting on timeout, slight refactor on reporting itself.
- basic module_util - Clean up ``selinux`` compat import.
- blockinfile - Remove unused code for Ansible 1.x.
- cache base - More efficient string splitting.
- callback API - implemented ``v2_runner_on_async_ok`` and ``v2_runner_on_async_failed`` callbacks (https://github.com/ansible/ansible/pull/74953).
- cli scripts - remove trailing blank space in help after newline when outputting.
- collection - match skip message as per role installation.
- command - update the user warning message to point out command name (https://github.com/ansible/ansible/pull/74475).
- config lookup now can handle plugin settings.
- config, default site for ansible-core is now under /ansbile-core/.
- connection base - Avoid using deprecated ``@abstractproperty`` decorator.
- constructed - a new options ``trailing_separator`` and ``default_value`` to deal with key's value empty on keyed group.
- cron - ``name`` is now a required parameter always
- cron - ``reboot`` parameter has been dropped in favor of ``special_time: reboot``
- cron, removed previously deprecated 'reboot' and now requires either 'name' as unique identifier.
- default callback plugin - displays output for ``v2_runner_on_async_ok`` and ``v2_runner_on_async_failed`` callbacks.
- deprecate ``_remote_checksum()`` and remove all internal uses (https://github.com/ansible/ansible/pull/74848)
- dnf - Add ``cacheonly`` option (https://github.com/ansible/ansible/issues/69397).
- dnf - allow for ``download_only`` to be run without root privileges (https://github.com/ansible/ansible/issues/75530)
- encrypt - add new parameter ``ident`` to specify version of BCrypt algorithm to be used (https://github.com/ansible/ansible/issues/74571).
- fact cache - Remove deprecated backwards compatibility shim for the FactCache `update` method to accept multiple arguments.
- fact cache - Remove the deprecated location for FactCache. Import FactCache from `ansible.vars.fact_cache` instead.
- facts - add fiber channel facts for HP-UX (https://github.com/ansible/ansible/pull/57406)
- galaxy - support role artifact download from API response ``download_url`` location (https://github.com/ansible/ansible/issues/73103).
- get_distribution - ``lib.ansible.module_utils.common.sys_info.get_distribution`` now returns distribution information for all platforms not just Linux (https://github.com/ansible/ansible/issues/17587)
- get_distribution_version - ``lib.ansible.module_utils.common.sys_info.get_distribution_version`` now returns the version for all platfroms not just Linux (https://github.com/ansible/ansible/issues/17587)
- git - Add ``accept_newhostkey`` option (https://github.com/ansible/ansible/issues/69846).
- hostname - add support RedOS (https://github.com/ansible/ansible/issues/74779).
- import_role - Template tasks_from, vars_from, defaults_from, and handlers_from with --extra-vars (https://github.com/ansible/ansible/issues/69097).
- include_vars - add ``hash_behaviour`` option (https://github.com/ansible/ansible/pull/72944).
- ini - added new parameter ``allow_no_value`` to ini lookup plugin (https://github.com/ansible/ansible/issues/50594).
- ini lookup - add case sensitive option (https://github.com/ansible/ansible/issues/74601)
- interpreter discovery - allow the default list of ``INTERPRETER_PYTHON_FALLBACK`` to be changed using a variable
- interpreter discovery - prefer Python 3 over Python 2
- inventory plugins - Remove the deprecated cache interface. Set top level keys in the inventory plugin's `_cache` attribute (a dictionary) instead.
- jinja2_native - short-circuit ``ast.literal_eval`` for non-string values
- module_utils distro - when a 'distro' package/module is in PYTHONPATH but isn't the real 'distro' package/module that we expect, gracefully fall back to our own bundled distro.
- modules - add Anolis distro in hostname.py. project website https://openanolis.org/
- move all builtin modules to use the best possible locale function instead of hardcoding 'C'.
- password - add new parameter ``ident`` to specify version of BCrypt algorithm to be used (https://github.com/ansible/ansible/issues/74571).
- password - add new parameter ``seed`` in lookup plugin (https://github.com/ansible/ansible/pull/69775).
- password_hash uses passlib default if option isn't set
- playbook - Error if a playbook is an empty list instead of just skipping
- playbook - Error if using ``include`` instead of ``import_playbook``
- replaced examples/ansible.cfg with instructions on how to generate an up to date copy.
- service - add description how service module works internally (https://github.com/ansible/ansible/issues/74507).
- service_facts now handles more states/statuses from systemd and in a more reliable way (failed, not-found, masked).
- setup - add ``epoch_int`` option to date_time facts (https://github.com/ansible/ansible/pull/73822).
- ssh - added pkcs11 support by adding the pkcs11_provider option in the ssh connection module. (https://www.github.com/ansible/ansible/pull/32829)
- ssh connection, can not configure ssh_transfer_method with a variable.
- ssh connection, ssh_transfer_method is now configurable via variable.
- subelements lookup - Use generator in instance type check.
- tempfile - Remove unnecessary conditional for creating a temporary directory.
- template - Add comment attributes (``comment_start_string`` and ``comment_end_string``)
- unicode utils - Fix ``__all__`` which was incorrectly declared as a string instead of a tuple.
- user - Add ``umask`` option (https://github.com/ansible/ansible/issues/40359).
- user module - Remove unused code.
- validation testcases for check_* APIs (https://github.com/ansible/ansible/issues/55994).
- winrm - Allow explicit environment variables to be passed through to the ``kinit`` call for Kerberos authentication
- yaml dumper - YAML representer for AnsibleUndefined (https://github.com/ansible/ansible/issues/75072).
- yum - Add ``cacheonly`` option (https://github.com/ansible/ansible/issues/69397).
Breaking Changes / Porting Guide
--------------------------------
- Action, module, and group names in module_defaults must be static values. Their values can still be templates.
- Fully qualified 'ansible.legacy' plugin names are not included implicitly in action_groups.
- Unresolvable groups, action plugins, and modules in module_defaults are an error.
- ansible-test - Automatic installation of requirements for "cloud" test plugins no longer occurs. The affected test plugins are ``aws``, ``azure``, ``cs``, ``hcloud``, ``nios``, ``opennebula``, ``openshift`` and ``vcenter``. Collections should instead use one of the supported integration test requirements files, such as the ``tests/integration/requirements.txt`` file.
- ansible-test - The HTTP Tester is no longer available with the ``ansible-test shell`` command. Only the ``integration`` and ``windows-integration`` commands provide HTTP Tester.
- ansible-test - The ``--disable-httptester`` option is no longer available. The HTTP Tester is no longer optional for tests that specify it.
- ansible-test - The ``--httptester`` option is no longer available. To override the container used for HTTP Tester tests, set the ``ANSIBLE_HTTP_TEST_CONTAINER`` environment variable instead.
- ansible-test - Unit tests for ``modules`` and ``module_utils`` are now limited to importing only ``ansible.module_utils`` from the ``ansible`` module.
- conditionals - ``when`` conditionals no longer automatically parse string booleans such as ``"true"`` and ``"false"`` into actual booleans. Any non-empty string is now considered true. The ``CONDITIONAL_BARE_VARS`` configuration variable no longer has any effect.
- hostname - Drops any remaining support for Python 2.4 by using ``with open()`` to simplify exception handling code which leaked file handles in several spots
- hostname - On FreeBSD, the string ``temporarystub`` no longer gets written to the hostname file in the get methods (and in check_mode). As a result, the default hostname will now appear as ``''`` (empty string) instead of ``temporarystub`` for consistency with other strategies. This means the ``before`` result will be different.
- hostname - On OpenRC systems and Solaris, the ``before`` value will now be ``''`` (empty string) if the permanent hostname file does not exist, for consistency with other strategies.
- intersect, difference, symmetric_difference, union filters - the default behavior is now to be case-sensitive (https://github.com/ansible/ansible/issues/74255)
- unique filter - the default behavior is now to fail if Jinja2's filter fails and explicit ``case_sensitive=False`` as the Ansible's fallback is case-sensitive (https://github.com/ansible/ansible/pull/74256)
Deprecated Features
-------------------
- ansible-test - The ``--docker-no-pull`` option is deprecated and has no effect.
- ansible-test - The ``--no-pip-check`` option is deprecated and has no effect.
- include action is deprecated in favor of include_tasks, import_tasks and import_playbook.
- module_utils' FileLock is scheduled to be removed, it is not used due to its unreliable nature.
Removed Features (previously deprecated)
----------------------------------------
- The built-in module_util ``ansible.module_utils.common.removed`` was previously deprecated and has been removed.
- connections, removed password check stubs that had been moved to become plugins.
- task, inline parameters being auto coerced into variables has been removed.
Security Fixes
--------------
- Do not include params in exception when a call to ``set_options`` fails. Additionally, block the exception that is returned from being displayed to stdout. (CVE-2021-3620)
- templating engine fix for not preserving usnafe status when trying to preserve newlines. CVE-2021-3583
Bugfixes
--------
- Add RockyLinux to fact gathering (https://github.com/ansible/ansible/pull/74530).
- Add unicode support to ``ansible-inventory`` CLI (https://github.com/ansible/ansible/issues/57378)
- Add yaml representer for VarsWithSources (https://github.com/ansible/ansible/pull/68525).
- Added page describing terminal plugins to docsite
- AnsibleModule.set_mode_if_different - don't check file existence when check_mode is activated (https://github.com/ansible/ansible/issues/61185).
- Apply ``display_failed_stderr`` callback option on loop item results. (https://github.com/ansible/ansible/issues/74864)
- Binary GnuPG keys downloaded via URLs by the 'ansible.builtin.apt_key' module were corrupted so 'gpg' could not import them (https://github.com/ansible/ansible/issues/74424).
- Ensure end_play ends play, not batch (https://github.com/ansible/ansible/issues/73971)
- Ensure we get full path for extra vars into cliargs to avoid realpath issues after initial load.
- Fix ``keys()`` implementation of ``BaseFileCacheModule`` to strip the prefix from the key and only return keys that share the same prefix as the cache.
- Fix ``when`` evaluation on Native Jinja and Python 3.10.
- Fix templating task action with host-specific vars (https://github.com/ansible/ansible/issues/75568)
- Fully qualified 'ansible.legacy' and 'ansible.builtin' plugin names work in conjunction with module_defaults.
- Give a warning instead of an error if a handler name contains undefined variables and has no listen topics (https://github.com/ansible/ansible/issues/58841).
- Improve resilience of ``ansible-galaxy collection`` by increasing the page size to make fewer requests overall and retrying queries with a jittered exponential backoff when rate limiting HTTP codes (520 and 429) occur. (https://github.com/ansible/ansible/issues/74191)
- Jinja2 globals should be accessible even when importing a template without the context (https://github.com/ansible/ansible/issues/75371)
- PlayContext - Remove deprecated ``make_become_cmd`` (https://github.com/ansible/ansible/issues/74136)
- PowerShell - Ignore the ``LIB`` environment variable when compiling C# Ansible code
- Prevent ``ansible_failed_task`` from further templating (https://github.com/ansible/ansible/issues/74036)
- Remove 'default' from ssh plugin as we want to rely on default from ssh itself or ssh/config.
- Replace usage of private dnf.Base() attribute by future dnf API
- Save unreachable hosts between plays by adding them to the PlayIterator's _play._removed_hosts (https://github.com/ansible/ansible/issues/66945).
- Solaris - correct version check in svcadm_supports_sync (https://github.com/ansible/ansible/pull/73860).
- Task depth - Prevent exception when the task depth exceeds Pythons recursion depth (https://github.com/ansible/ansible/issues/73996)
- Templating - Ensure we catch exceptions when calling ``.filters()`` or ``.tests()`` on their respective plugins and properly error, instead of aborting which results in no filters being added to the jinja2 environment (https://github.com/ansible/ansible/pull/74127)
- The ``apt_key`` module did not properly handle GnuPG errors (https://github.com/ansible/ansible/issues/74477)
- The error message about the failure to import a ```gpg`` key by the ``apt_key`` module was incorrect (https://github.com/ansible/ansible/issues/74423).
- Update network user guide to explain use of cli_parse and validate plugins.
- Variable Manager - Only check if ``play.hosts`` is a template when the play hasn't been finalized (https://github.com/ansible/ansible/issues/73926)
- WorkerProcess - Python 3.5 fix for workaround for stdout deadlock in multiprocessing shutdown to avoid process hangs. (https://github.com/ansible/ansible/issues/74149)
- ``AnsibleModule.run_command`` - Address thread safety issues, concerning mutating the environment, current working directory, and umask. (https://github.com/ansible/ansible/issues/74783)
- ``failed_when``/``changed_when`` - Catch templating errors to prevent masking of module output (https://github.com/ansible/ansible/issues/37187)
- ``heuristic_log_sanitize`` - Return the full string if there is no password (https://github.com/ansible/ansible/issues/75542)
- ``pip`` now uses the ``pip`` Python module installed for the Ansible module's Python interpreter, if available, unless ``executable`` or ``virtualenv`` were specified.
- advanced_host_list inventory plugin - Fixed variable referenced before assignment when hostname/range could not be parsed.
- ansiballz - avoid treating path to site_packages as regex; escape it. This prevents a crash when ansible is installed to, or running from, an oddly named directory like ``ansi[ble``
- ansible-doc - in text output, do not show empty ``version_added_collection`` values (https://github.com/ansible/ansible/pull/74999).
- ansible-doc can now dump kewyords with --metadata-dump (still just for internal use)
- ansible-doc, fix output for internal metadata dump option
- ansible-doc, make inventory plugin selection for snippets generic and not a hardcoded list
- ansible-galaxy - Fix a bug with build_ignore when installing collections from source (https://github.com/ansible/ansible/issues/75528).
- ansible-galaxy - Fix handling HTTP exceptions from Galaxy servers. Continue to the next server in the list until the collection is found.
- ansible-galaxy - Improve error message from dependency resolution when a candidate has inconsistent requirements (https://github.com/ansible/ansible/issues/75139).
- ansible-inventory - handle an exception while parsing inventory in toml format (https://github.com/ansible/ansible/issues/74404).
- ansible-playbook, more robust handling of --list-hosts and undefined vars in hosts keyword.
- ansible-pull - update documentation for ``--directory`` option to clarify path must be absolute.
- ansible-pull, restore other options to use as repo other than git.
- ansible-test - Add constraint for ``pyspnego>=0.1.6`` for Python 3.10 - https://github.com/ansible/ansible/pull/74612
- ansible-test - Avoid publishing the port used by the ``pypi-test-container`` since it is only accessed by other containers. This avoids issues when trying to run tests in parallel on a single host.
- ansible-test - Failure to download test results from a remote host no longer hide test failures. If a download failure occurs after tests fail, a warning will be issued instead.
- ansible-test - Fix docker container IP address detection. The ``bridge`` network is no longer assumed to be the default.
- ansible-test - Fix path to inventory file for ``windows-integration`` and ``network-integration`` commands for collections.
- ansible-test - Fix traceback when generating coverage reports and no coverage directory exists.
- ansible-test - Random port selection is no longer handled by ``ansible-test``, avoiding possible port conflicts. Previously ``ansible-test`` would, under some circumstances, use one host's available ports to determine those of another host.
- ansible-test - Running tests in a single test run with multiple "cloud" plugins no longer results in port conflicts. Previously two or more containers with overlapping ports could not be used in the same test run.
- ansible-test - Tab completion after options like ``--docker`` which accept an optional argument will no longer provide incorrect completions.
- ansible-test - The ``--python`` and ``--venv`` options are no longer ignored by some commands, such as ``coverage``.
- ansible-test - The ``docker inspect`` command is now used to check for existing images instead of the ``docker images`` command. This resolves an issue where a ``docker pull`` would be unnecessarily executed for an image referenced by checksum.
- ansible-test - Update distribution test containers to version 3.1.0.
- ansible-test - Use ``--strict`` for ``pytest`` on Python 2.6 since ``--strict-markers`` is not available.
- ansible-test - Use documented API to retrieve build information from Azure Pipelines.
- ansible-test - Use pwsh to generate correct coverage line counts for stub files to get a more accurate coverage result
- ansible-test - Use the correct variable to reference the client's SSH key when generating inventory.
- ansible-test - add packaging python module to ``ansible-doc`` sanity test requirements.
- ansible-test - allow the same listening port on all container interfaces
- ansible-test - ensure the correct unit test target is given when the ``__init__.py`` file is modified inside the connection plugins directory
- ansible-test - make the ``a/`` and ``b/`` prefixes an optional match since these can be turned off with the ``diff.noprefix`` setting in ``git``
- ansible-test - restrict ``packaging`` to ``< 21.0`` for Python ``< 3.6`` (https://github.com/ansible/ansible/pull/75186).
- ansible-test pslint - Fix error when encountering validation results that are highly nested - https://github.com/ansible/ansible/issues/74151
- ansible-test validate-modules - EXAMPLES will no longer be marked as invalid YAML when it uses Ansible-specific YAML tags (https://github.com/ansible/ansible/pull/74384).
- ansible-test validate-modules - correctly validate positional parameters to ``AnsibleModules`` (https://github.com/ansible/ansible/pull/75332).
- ansible.builtin.cron - Keep non-empty crontabs, when removing cron jobs (https://github.com/ansible/ansible/pull/74497).
- ansible.utils.encrypt now handles missing or unusable 'crypt' library.
- ansible_test - add constraint for ``MarkupSafe`` (https://github.com/ansible/ansible/pull/74666)
- apt_key - set --recv argument as last one in apt-key command when using env var HTTP_PROXY (https://github.com/ansible/ansible/issues/74946)
- arg_spec - remove unused imports
- async_status, ensure we always get documented returns
- async_status, resurrected module to deprecate for those that were invoking it directly.
- basic - skip over module parameters which are used in ``journal.send`` API call (https://github.com/ansible/ansible/issues/71343).
- become - fix a regression on Solaris where chmod can return 5 which we interpret as auth failure and stop trying become tmpdir permission fallbacks
- become - work around setfacl not existing on modern Solaris (and possibly failing on some filesystems even when it does exist)
- callbacks, restore displaying delegation to host as host label.
- cli defaults for ssh args set to None as '' was bypassing normal default.
- command - remove unreachable code path when trying to convert the value for ``chdir`` to bytes (https://github.com/ansible/ansible/pull/75036)
- command module, clarify order of remove/creates checks.
- command module, correctly handles chdir to symlinks.
- command module, move to standarized messages in 'msg' vs abusing 'stdout'.
- command module, now all options work in ad-hoc execution.
- command module, now always returns what we documented as 'returns always'.
- config - use ``callbacks_enabled`` instead ``callback_enabled`` in a deprecated message (https://github.com/ansible/ansible/issues/70028).
- config lookup, can also handle collection plugins now
- config, ensure 'quoted' lists from ini or env do not take the quotes literally as part of the list item.
- connection ssh, no ssh_args cli option, so removed doc entry.
- constants, internal _deprecated function always requires version.
- correct doc links for become on warnings over world readable settings.
- correctly use world readable setting since old constant is not 'settable' anymore.
- dnf - align the return value of the list argument with the ``yum`` module (https://github.com/ansible/ansible/issues/75483)
- dnf - properly capture transaction error (https://github.com/ansible/ansible/issues/72651)
- dnf - refactor code to use `dnf whatprovides` API (https://github.com/ansible/ansible/issues/73503).
- dnf - support non-english environments (https://github.com/ansible/ansible/issues/75021)
- dnf module - Use all components of a package name to determine if it's installed (https://github.com/ansible/ansible/issues/75311).
- do not trigger interpreter discovery in the forced_local module path as they should use the ansible playbook python unless otherwise configured.
- facts - detect homebrew installed at /opt/homebrew/bin/brew
- facts, service_mgr, handle issues if ps command fails or returns empty.
- filter plugins - patch new versions of Jinja2 to prevent warnings/errors on renamed filter decorators (https://github.com/ansible/ansible/issues/74667)
- find - fix a bug where ``size`` argument was ignored for regular files with ``file_type`` of ``any``.
- find action, correctly convert path to text when warning about skiping.
- find does not ignore errors from os.walk anymore and issues warnings as expected.
- gather_facts, improved message on timeout.
- gather_facts, package, service - fix using module_defaults for the modules in addition to the action plugins. (https://github.com/ansible/ansible/issues/72918)
- get_bin_path, clarify with quotes what the missing required executable is.
- get_url - Fixed checksum validation for binary files (leading asterisk) in checksum files (https://github.com/ansible/ansible/pull/74502).
- getent, fix return data for when there are multiple results for the same key
- git - Fix git path used when .git file is present (https://github.com/ansible/ansible/issues/75608).
- host_group_vars vars plugin fixed ini entry, section and key were reversed.
- hostname - Add Rocky Linux support
- hostname - No longer modifies system files in get_* methods and therefore when consulted in check_mode (https://github.com/ansible/ansible/issues/66432)
- include - Remove deprecated ``static`` argument for ``include`` (https://github.com/ansible/ansible/issues/74135)
- includes - Remove the deprecated ability to specify ``tags`` as ``vars`` on includes (https://github.com/ansible/ansible/issues/74144)
- ini lookup - better error on mixed/bad parameters
- ini lookup - handle errors for duplicate keys and missing sections (https://github.com/ansible/ansible/issues/74601)
- interpreter discovery - Debian 8 and lower will avoid unsupported Python3 version in interpreter discovery
- interpreter discovery is now handling special (ansible_network_os) cases in less noisy ways.
- interpreter_discovery - hide warning 'No python interpreters...' when ANSIBLE_PYTHON_INTERPRETER=auto_silent (https://github.com/ansible/ansible/issues/74274).
- module_common - handle exception when multiple workers try to create the cache directory
- module_defaults - Fix action defaults for legacy actions/modules (https://github.com/ansible/ansible/issues/75279).
- module_utils - detect symlinked init systems, even if unable to read /proc/1/comm (https://github.com/ansible/ansible/issues/74866).
- netconf - catch and handle exception to prevent stack trace when running in FIPS mode
- network module_utils - fix bug where ``to_bits()`` returned the ``str`` type instead of a useful value.
- paramiko_ssh - mark connection as connected when ``_connect()`` is called (https://github.com/ansible/ansible/issues/74081)
- password - Handle passlib wrapped algos bsd_nthash, django_argon2, django_bcrypt, ldap_bcrypt, ldap_bsdi_crypt, ldap_des_crypt, ldap_hex_md5, ldap_hex_sha1, ldap_md5_crypt, ldap_pbkdf2_sha1, ldap_pbkdf2_sha256, ldap_pbkdf2_sha512, ldap_sha1_crypt, ldap_sha256_crypt, ldap_sha512_crypt, roundup_plaintext (https://github.com/ansible/ansible/pull/75527).
- pause - ensure control characters are always set to an appropriate value (https://github.com/ansible/ansible/issues/73264)
- pkg_mgr.py - Lower the priority of rpm-ostree detection to avoid false positives on systems not using it as the main package manager (https://github.com/ansible/ansible/issues/74578)
- play - validate the ``hosts`` entry in a play (https://github.com/ansible/ansible/issues/65386)
- playbook loaded from collection subdir now does not ignore subdirs.
- plugin config now allows list type options to have multiple valid choices (#74225).
- psrp - Always cleanup the last run pipeline if a second pipeline is invoked to avoid violating any resource limits.
- psrp - Fix error when resetting a connection that was initialised but not connected - (https://github.com/ansible/ansible/issues/74092).
- psrp - Try to clean up any server-side resources when resetting a connection.
- recursive_diff - handle condition when parameters are not dict (https://github.com/ansible/ansible/issues/56249).
- register - Ensure that ``register`` used on ``set_fact`` or ``include_vars`` does not automatically wrap the facts as unsafe. (https://github.com/ansible/ansible/issues/21088)
- rekey_on_member - handle undefined positional arguments better.
- remote tmpdir permissions - fix type error in macOS chmod ACL fallback (https://github.com/ansible/ansible/pull/74613).
- replace - better handling of file operation exceptions (https://github.com/ansible/ansible/pull/74686).
- roles - allow for role arg specs in new meta file (https://github.com/ansible/ansible/issues/74525).
- roles - fix unexpected ``AttributeError`` when an empty ``argument_specs.yml`` is present (https://github.com/ansible/ansible/pull/75604).
- roles - make sure argspec validation task is tagged with ``always`` (https://github.com/ansible/ansible/pull/74994).
- roles - make sure argspec validation task templates suboptions (https://github.com/ansible/ansible/issues/75070).
- schema validation now uses dynamic range of versions for valid deprecation entries vs hardcoded out of date list.
- script inventory plugin - Remove deprecated caching support (https://github.com/ansible/ansible/issues/74143)
- sequence - fix error message so that unrecognized options to the plugin display correctly as a list and normalize error messages.
- service - compare version without LooseVersion API (https://github.com/ansible/ansible/issues/74488).
- set ssh host_key_checking defaults to True, restoring original behaviour (https://github.com/ansible/ansible/issues/75168)
- setup module should now not truncate hpux interface names.
- setup module, fix filter to adjust for missing ``ansible_`` prefix on query.
- setup, while gathering linux hardware facts be more resilient to errors and try to return more info.
- slurp - Fix error messages for unreadable files and directories(https://github.com/ansible/ansible/issues/67340).
- slurp - handle error when ``path`` is a directory and not a file (https://github.com/ansible/ansible/pull/74930).
- slurp - improve the logic in the error handling and remove ``os.stat()`` call (https://github.com/ansible/ansible/pull/75038)
- ssh connection now correctly handle ssh_transfer_method and scp_if_ssh interactions.
- ssh connection, fix interaction between trasnfer settings options.
- ssh connection, use self.host which has the most up2date info instead of pc.remote_addr
- ssh_connection - rename ``retries`` to ``reconnection_retries`` to avoid conflicts with task vars (https://github.com/ansible/ansible/issues/75142).
- ssh_connection - set the default for ``reconnection_retries`` back to ``0`` (https://github.com/ansible/ansible/issues/75142).
- subversion - fix stack trace when getting information about the repository (https://github.com/ansible/ansible/issues/36498)
- system_service - use a context manager for file handling.
- task_executor, Actions using AnsibleActionFail/Skip will now propagate 'results' if given
- task_executor/ssh_connection - use the ``retries`` value from ``ssh_connection`` settings, not the default from the ``Task`` field attributes (https://github.com/ansible/ansible/issues/75142).
- template - ensure Jinja2 overrides from template header are used (https://github.com/ansible/ansible/issues/75275)
- unarchive - allow extracting archives that contain files which size exceeds free system memory (https://github.com/ansible/ansible/issues/73985).
- unarchive - fail when zipinfo binary is not found in executable paths (https://github.com/ansible/ansible/issues/39029).
- unarchive - move failure for missing binary to ``can_handle_archive()`` rather than ``__init__()``
- uri - Fix traceback and provide error message when trying to use non-string or mapping for ``form-multipart`` body - https://github.com/ansible/ansible/issues/74276
- urls - Fix logic in matching ``unredirected_headers`` to perform case insensitive matching
- validate_argument_spec, correct variable precedence and merge method and add missing examples
- variable manager, avoid sourcing delegated variables when no inventory hostname is present. This affects scenarios like syntax check and imports.
- version test - improve error message when an empty version is provided
- yum - Fixed typo in failure message (https://github.com/ansible/ansible/pull/72964).
- yum - When upgrading, every architecture of a package is now included in the module results, instead of just one (https://github.com/ansible/ansible/issues/73284).
- yum - fix ``yumstate`` return value when wildcards are used in the ``list`` argument (https://github.com/ansible/ansible/issues/74557)
- yum - fix parsing of multiple subsequent empty lines from ``yum check-update`` output (https://github.com/ansible/ansible/issues/70949)
- yum - yum action plugin changes to support 'use' as an alias of 'use_backend' (https://github.com/ansible/ansible/issues/70774).
Known Issues
------------
- ansible-test - Tab completion anywhere other than the end of the command with the new composite options will provide incorrect results. See https://github.com/kislyuk/argcomplete/issues/351 for additional details.

View File

@ -1,6 +0,0 @@
Placeholder changelog
=====================
This file is a placeholder; a version-specific ``CHANGELOG-vX.Y.rst`` will be generated during releases from fragments
under changelogs/fragments. On release branches once a release has been created, consult the branch's version-specific
file for changes that have occurred in that branch.

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +0,0 @@
---
title: ansible-core
release_tag_re: '(v(?:[\d.ab\-]|rc)+)'
pre_release_tag_re: '(?P<pre_release>(?:[ab]|rc)+\d*)$'
changes_file: changelog.yaml
changes_format: combined
keep_fragments: true
always_refresh: true
ignore_other_fragment_extensions: true
mention_ancestor: false
notesdir: fragments
prelude_section_name: release_summary
new_plugins_after_name: removed_features
sections:
- ['major_changes', 'Major Changes']
- ['minor_changes', 'Minor Changes']
- ['breaking_changes', 'Breaking Changes / Porting Guide']
- ['deprecated_features', 'Deprecated Features']
- ['removed_features', 'Removed Features (previously deprecated)']
- ['security_fixes', 'Security Fixes']
- ['bugfixes', 'Bugfixes']
- ['known_issues', 'Known Issues']

View File

@ -1,7 +0,0 @@
minor_changes:
- >
get_distribution - ``lib.ansible.module_utils.common.sys_info.get_distribution`` now returns
distribution information for all platforms not just Linux (https://github.com/ansible/ansible/issues/17587)
- >
get_distribution_version - ``lib.ansible.module_utils.common.sys_info.get_distribution_version`` now
returns the version for all platfroms not just Linux (https://github.com/ansible/ansible/issues/17587)

View File

@ -1,4 +0,0 @@
bugfixes:
- register - Ensure that ``register`` used on ``set_fact`` or ``include_vars``
does not automatically wrap the facts as unsafe.
(https://github.com/ansible/ansible/issues/21088)

View File

@ -1,4 +0,0 @@
minor_changes:
- Python 2.6 Target Support - Deprecate Python 2.6 for targets, requiring Python 2.7 or newer.
``ansible-core==2.13`` will drop support for Python 2.6.
(https://github.com/ansible/ansible/pull/74165)

View File

@ -1,2 +0,0 @@
minor_changes:
- deprecate ``_remote_checksum()`` and remove all internal uses (https://github.com/ansible/ansible/pull/74848)

View File

@ -1,3 +0,0 @@
minor_changes:
- ssh - added pkcs11 support by adding the pkcs11_provider option in the
ssh connection module. (https://www.github.com/ansible/ansible/pull/32829)

View File

@ -1,2 +0,0 @@
bugfixes:
- subversion - fix stack trace when getting information about the repository (https://github.com/ansible/ansible/issues/36498)

View File

@ -1,4 +0,0 @@
bugfixes:
- >-
``failed_when``/``changed_when`` - Catch templating errors to prevent masking of module output
(https://github.com/ansible/ansible/issues/37187)

View File

@ -1,2 +0,0 @@
bugfixes:
- unarchive - fail when zipinfo binary is not found in executable paths (https://github.com/ansible/ansible/issues/39029).

View File

@ -1,2 +0,0 @@
minor_changes:
- ini - added new parameter ``allow_no_value`` to ini lookup plugin (https://github.com/ansible/ansible/issues/50594).

View File

@ -1,3 +0,0 @@
---
minor_changes:
- validation testcases for check_* APIs (https://github.com/ansible/ansible/issues/55994).

View File

@ -1,2 +0,0 @@
bugfixes:
- recursive_diff - handle condition when parameters are not dict (https://github.com/ansible/ansible/issues/56249).

View File

@ -1,2 +0,0 @@
bugfixes:
- Add unicode support to ``ansible-inventory`` CLI (https://github.com/ansible/ansible/issues/57378)

View File

@ -1,2 +0,0 @@
minor_changes:
- facts - add fiber channel facts for HP-UX (https://github.com/ansible/ansible/pull/57406)

View File

@ -1,2 +0,0 @@
bugfixes:
- AnsibleModule.set_mode_if_different - don't check file existence when check_mode is activated (https://github.com/ansible/ansible/issues/61185).

View File

@ -1,2 +0,0 @@
bugfixes:
- system_service - use a context manager for file handling.

View File

@ -1,2 +0,0 @@
bugfixes:
- play - validate the ``hosts`` entry in a play (https://github.com/ansible/ansible/issues/65386)

View File

@ -1,4 +0,0 @@
minor_changes:
- >-
``include_role`` - Allow use of ``omit`` in the ``from_*`` arguments
(https://github.com/ansible/ansible/issues/66349)

View File

@ -1,7 +0,0 @@
bugfixes:
- hostname - No longer modifies system files in get_* methods and therefore when consulted in check_mode (https://github.com/ansible/ansible/issues/66432)
breaking_changes:
- hostname - Drops any remaining support for Python 2.4 by using ``with open()`` to simplify exception handling code which leaked file handles in several spots
- hostname - On FreeBSD, the string ``temporarystub`` no longer gets written to the hostname file in the get methods (and in check_mode). As a result, the default hostname will now appear as ``''`` (empty string) instead of ``temporarystub`` for consistency with other strategies. This means the ``before`` result will be different.
- hostname - On OpenRC systems and Solaris, the ``before`` value will now be ``''`` (empty string) if the permanent hostname file does not exist, for consistency with other strategies.

View File

@ -1,2 +0,0 @@
bugfixes:
- "slurp - Fix error messages for unreadable files and directories(https://github.com/ansible/ansible/issues/67340)."

View File

@ -1,3 +0,0 @@
---
minor_changes:
- collection - match skip message as per role installation.

View File

@ -1,2 +0,0 @@
bugfixes:
- Add yaml representer for VarsWithSources (https://github.com/ansible/ansible/pull/68525).

View File

@ -1,2 +0,0 @@
minor_changes:
- template - Add comment attributes (``comment_start_string`` and ``comment_end_string``)

View File

@ -1,2 +0,0 @@
bugfixes:
- config - use ``callbacks_enabled`` instead ``callback_enabled`` in a deprecated message (https://github.com/ansible/ansible/issues/70028).

View File

@ -1,2 +0,0 @@
bugfixes:
- yum - yum action plugin changes to support 'use' as an alias of 'use_backend' (https://github.com/ansible/ansible/issues/70774).

View File

@ -1,2 +0,0 @@
bugfixes:
- yum - fix parsing of multiple subsequent empty lines from ``yum check-update`` output (https://github.com/ansible/ansible/issues/70949)

View File

@ -1,2 +0,0 @@
bugfixes:
- basic - skip over module parameters which are used in ``journal.send`` API call (https://github.com/ansible/ansible/issues/71343).

View File

@ -1,2 +0,0 @@
minor_changes:
- YAML parsing - Create common utils for loading and dumping YAML that prefer the C extensions if available

View File

@ -1,2 +0,0 @@
bugfixes:
- dnf - properly capture transaction error (https://github.com/ansible/ansible/issues/72651)

View File

@ -1,2 +0,0 @@
minor_changes:
- include_vars - add ``hash_behaviour`` option (https://github.com/ansible/ansible/pull/72944).

View File

@ -1,2 +0,0 @@
bugfixes:
- yum - Fixed typo in failure message (https://github.com/ansible/ansible/pull/72964).

View File

@ -1,2 +0,0 @@
minor_changes:
- galaxy - support role artifact download from API response ``download_url`` location (https://github.com/ansible/ansible/issues/73103).

View File

@ -1,2 +0,0 @@
bugfixes:
- pause - ensure control characters are always set to an appropriate value (https://github.com/ansible/ansible/issues/73264)

View File

@ -1,2 +0,0 @@
bugfixes:
- yum - When upgrading, every architecture of a package is now included in the module results, instead of just one (https://github.com/ansible/ansible/issues/73284).

View File

@ -1,2 +0,0 @@
bugfixes:
- dnf - refactor code to use `dnf whatprovides` API (https://github.com/ansible/ansible/issues/73503).

View File

@ -1,2 +0,0 @@
minor_changes:
- "ansible-doc - show ``version_added`` for the plugin/module itself in text output, and improve ``version_added`` formatting (https://github.com/ansible/ansible/pull/73602)."

View File

@ -1,4 +0,0 @@
minor_changes:
- >-
`ansible.plugins.callback.CallbackBase.host_label()` has been factored out
as a static method (https://github.com/ansible/ansible/pull/73814).

View File

@ -1,3 +0,0 @@
---
minor_changes:
- git - Add ``accept_newhostkey`` option (https://github.com/ansible/ansible/issues/69846).

View File

@ -1,4 +0,0 @@
---
minor_changes:
- yum - Add ``cacheonly`` option (https://github.com/ansible/ansible/issues/69397).
- dnf - Add ``cacheonly`` option (https://github.com/ansible/ansible/issues/69397).

View File

@ -1,3 +0,0 @@
---
minor_changes:
- user - Add ``umask`` option (https://github.com/ansible/ansible/issues/40359).

View File

@ -1,3 +0,0 @@
---
minor_changes:
- setup - add ``epoch_int`` option to date_time facts (https://github.com/ansible/ansible/pull/73822).

View File

@ -1,2 +0,0 @@
bugfixes:
- Solaris - correct version check in svcadm_supports_sync (https://github.com/ansible/ansible/pull/73860).

View File

@ -1,2 +0,0 @@
bugfixes:
- gather_facts, package, service - fix using module_defaults for the modules in addition to the action plugins. (https://github.com/ansible/ansible/issues/72918)

View File

@ -1,3 +0,0 @@
---
bugfixes:
- facts - detect homebrew installed at /opt/homebrew/bin/brew

View File

@ -1,3 +0,0 @@
bugfixes:
- Variable Manager - Only check if ``play.hosts`` is a template when the play
hasn't been finalized (https://github.com/ansible/ansible/issues/73926)

Some files were not shown because too many files have changed in this diff Show More