Extend ansible-pull to support other source repositories
This extends ansible-pull so that it can support using other source_control modules for checking out a playbook repository (issue #3372). This will check to see if the module exists before it attempts to do the checkout and will exit if the module is not found. It requires that the module used to check out the repository support the parameters 'name' and 'version'. The option -C, --checkout is now optional and defaults to the module's default behavior for selecting a branch, tag, or commit value. For git, this continues to be HEAD. Other changes include: * Remove git from help and use generic term(s) where needed. * Use SortedOptParser from ansible.utils * More abstraction of common options used between ansible and ansible-playbook.
This commit is contained in:
parent
cc58403e48
commit
cc3651592b
1 changed files with 28 additions and 15 deletions
|
@ -14,8 +14,9 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
# ansible-pull is a script that runs ansible in local mode
|
# ansible-pull is a script that runs ansible in local mode
|
||||||
# after checking out a playbooks directory from git. There is an
|
# after checking out a playbooks directory from source repo. There is an
|
||||||
# example playbook to bootstrap this script in the examples/ dir which
|
# example playbook to bootstrap this script in the examples/ dir which
|
||||||
# installs ansible and sets it up to run on cron.
|
# installs ansible and sets it up to run on cron.
|
||||||
|
|
||||||
|
@ -27,14 +28,14 @@
|
||||||
# the -d and -U arguments are required; the -C argument is optional.
|
# the -d and -U arguments are required; the -C argument is optional.
|
||||||
#
|
#
|
||||||
# ansible-pull accepts an optional argument to specify a playbook
|
# ansible-pull accepts an optional argument to specify a playbook
|
||||||
# location underneath the workdir and then searches the git repo
|
# location underneath the workdir and then searches the source repo
|
||||||
# for playbooks in the following order, stopping at the first match:
|
# for playbooks in the following order, stopping at the first match:
|
||||||
#
|
#
|
||||||
# 1. $workdir/path/playbook.yml, if specified
|
# 1. $workdir/path/playbook.yml, if specified
|
||||||
# 2. $workdir/$hostname.yml
|
# 2. $workdir/$hostname.yml
|
||||||
# 3. $workdir/local.yml
|
# 3. $workdir/local.yml
|
||||||
#
|
#
|
||||||
# the git repo must contain at least one of these playbooks.
|
# the source repo must contain at least one of these playbooks.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
@ -42,8 +43,9 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
import datetime
|
import datetime
|
||||||
import socket
|
import socket
|
||||||
from optparse import OptionParser
|
from ansible import utils
|
||||||
|
|
||||||
|
DEFAULT_REPO_TYPE = 'git'
|
||||||
DEFAULT_PLAYBOOK = 'local.yml'
|
DEFAULT_PLAYBOOK = 'local.yml'
|
||||||
PLAYBOOK_ERRORS = {1: 'File does not exist',
|
PLAYBOOK_ERRORS = {1: 'File does not exist',
|
||||||
2: 'File is not readable'}
|
2: 'File is not readable'}
|
||||||
|
@ -96,20 +98,24 @@ def select_playbook(path, args):
|
||||||
def main(args):
|
def main(args):
|
||||||
""" Set up and run a local playbook """
|
""" Set up and run a local playbook """
|
||||||
usage = "%prog [options] [playbook.yml]"
|
usage = "%prog [options] [playbook.yml]"
|
||||||
parser = OptionParser(usage=usage)
|
parser = utils.SortedOptParser(usage=usage)
|
||||||
parser.add_option('--purge', default=False, action='store_true',
|
parser.add_option('--purge', default=False, action='store_true',
|
||||||
help='purge git checkout after playbook run')
|
help='purge checkout after playbook run')
|
||||||
parser.add_option('-o', '--only-if-changed', dest='ifchanged', default=False, action='store_true',
|
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')
|
help='only run the playbook if the repository has been updated')
|
||||||
parser.add_option('-d', '--directory', dest='dest', default=None,
|
parser.add_option('-d', '--directory', dest='dest', default=None,
|
||||||
help='directory to clone the git repository to')
|
help='directory to checkout repository to')
|
||||||
parser.add_option('-U', '--url', dest='url', default=None,
|
parser.add_option('-U', '--url', dest='url', default=None,
|
||||||
help='URL of the git repository')
|
help='URL of the playbook repository')
|
||||||
parser.add_option('-C', '--checkout', dest='checkout',
|
parser.add_option('-C', '--checkout', dest='checkout',
|
||||||
default="HEAD",
|
help='branch/tag/commit to checkout. '
|
||||||
help='branch/tag/commit to checkout; defaults to HEAD')
|
'Defaults to behavior of repository module.')
|
||||||
parser.add_option('-i', '--inventory-file', dest='inventory',
|
parser.add_option('-i', '--inventory-file', dest='inventory',
|
||||||
help="location of the inventory host file")
|
help="location of the inventory host file")
|
||||||
|
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)
|
||||||
options, args = parser.parse_args(args)
|
options, args = parser.parse_args(args)
|
||||||
|
|
||||||
if not options.dest:
|
if not options.dest:
|
||||||
|
@ -119,7 +125,7 @@ def main(args):
|
||||||
options.dest = os.path.abspath(options.dest)
|
options.dest = os.path.abspath(options.dest)
|
||||||
|
|
||||||
if not options.url:
|
if not options.url:
|
||||||
parser.error("URL for git repo not specified, use -h for help")
|
parser.error("URL for repository not specified, use -h for help")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
|
@ -127,9 +133,16 @@ def main(args):
|
||||||
|
|
||||||
inv_opts = 'localhost,'
|
inv_opts = 'localhost,'
|
||||||
limit_opts = 'localhost:%s:127.0.0.1' % socket.getfqdn()
|
limit_opts = 'localhost:%s:127.0.0.1' % socket.getfqdn()
|
||||||
git_opts = "repo=%s dest=%s version=%s" % (options.url, options.dest, options.checkout)
|
base_opts = '-c local --limit "%s"' % limit_opts
|
||||||
cmd = 'ansible all -c local -i "%s" --limit "%s" -m git -a "%s"' % (
|
repo_opts = "name=%s dest=%s" % (options.url, options.dest)
|
||||||
inv_opts, limit_opts, git_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
|
||||||
)
|
)
|
||||||
rc, out = _run(cmd)
|
rc, out = _run(cmd)
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
|
@ -144,7 +157,7 @@ def main(args):
|
||||||
print >>sys.stderr, "Could not find a playbook to run."
|
print >>sys.stderr, "Could not find a playbook to run."
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
cmd = 'ansible-playbook -c local --limit "%s" %s' % (limit_opts, playbook)
|
cmd = 'ansible-playbook %s %s' % (base_opts, playbook)
|
||||||
if options.inventory:
|
if options.inventory:
|
||||||
cmd += ' -i "%s"' % options.inventory
|
cmd += ' -i "%s"' % options.inventory
|
||||||
os.chdir(options.dest)
|
os.chdir(options.dest)
|
||||||
|
|
Loading…
Reference in a new issue