Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
ansible
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
ansible
Commits
0b836262
Commit
0b836262
authored
May 01, 2015
by
Brian Coca
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
draft ansible pull uspport
parent
c926bb68
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
167 additions
and
17 deletions
+167
-17
v2/ansible/cli/pull.py
+167
-17
No files found.
v2/ansible/cli/pull.py
View file @
0b836262
...
...
@@ -16,54 +16,204 @@
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
########################################################
import
datetime
import
os
import
sys
import
random
import
shutil
import
socket
from
ansible
import
constants
as
C
from
ansible.errors
import
*
from
ansible.errors
import
AnsibleError
,
AnsibleOptionsError
from
ansible.cli
import
CLI
from
ansible.executor.task_queue_manager
import
TaskQueueManager
from
ansible.inventory
import
Inventory
from
ansible.parsing
import
DataLoader
from
ansible.parsing.splitter
import
parse_kv
from
ansible.playbook.play
import
Play
from
ansible.utils.display
import
Display
from
ansible.utils.vault
import
read_vault_file
from
ansible.vars
import
VariableManager
########################################################
class
PullCLI
(
CLI
):
''' code behind ansible ad-hoc cli'''
DEFAULT_REPO_TYPE
=
'git'
DEFAULT_PLAYBOOK
=
'local.yml'
PLAYBOOK_ERRORS
=
{
1
:
'File does not exist'
,
2
:
'File is not readable'
}
SUPPORTED_REPO_MODULES
=
[
'git'
]
def
parse
(
self
):
''' create an options parser for bin/ansible '''
self
.
parser
=
CLI
.
base_parser
(
usage
=
'
%
prog <host-pattern> [options]'
,
runas_opts
=
True
,
async_opts
=
True
,
output_opts
=
True
,
connect_opts
=
True
,
check_opts
=
True
,
runtask_opts
=
True
,
vault_opts
=
True
,
)
# options unique to pull
self
.
parser
.
add_option
(
'--purge'
,
default
=
False
,
action
=
'store_true'
,
help
=
'purge checkout after playbook run'
)
self
.
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'
)
self
.
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'
)
self
.
parser
.
add_option
(
'-f'
,
'--force'
,
dest
=
'force'
,
default
=
False
,
action
=
'store_true'
,
help
=
'run the playbook even if the repository could not be updated'
)
self
.
parser
.
add_option
(
'-d'
,
'--directory'
,
dest
=
'dest'
,
default
=
None
,
help
=
'directory to checkout repository to'
)
self
.
parser
.
add_option
(
'-U'
,
'--url'
,
dest
=
'url'
,
default
=
None
,
help
=
'URL of the playbook repository'
)
self
.
parser
.
add_option
(
'-C'
,
'--checkout'
,
dest
=
'checkout'
,
help
=
'branch/tag/commit to checkout. '
'Defaults to behavior of repository module.'
)
self
.
parser
.
add_option
(
'--accept-host-key'
,
default
=
False
,
dest
=
'accept_host_key'
,
action
=
'store_true'
,
help
=
'adds the hostkey for the repo url if not already added'
)
self
.
parser
.
add_option
(
'-m'
,
'--module-name'
,
dest
=
'module_name'
,
default
=
self
.
DEFAULT_REPO_TYPE
,
help
=
'Repository module name, which ansible will use to check out the repo. Default is
%
s.'
%
self
.
DEFAULT_REPO_TYPE
)
self
.
options
,
self
.
args
=
self
.
parser
.
parse_args
()
if
self
.
options
.
sleep
:
try
:
secs
=
random
.
randint
(
0
,
int
(
self
.
options
.
sleep
))
self
.
options
.
sleep
=
secs
except
ValueError
:
raise
AnsibleOptionsError
(
"
%
s is not a number."
%
self
.
options
.
sleep
)
if
not
self
.
options
.
url
:
raise
AnsibleOptionsError
(
"URL for repository not specified, use -h for help"
)
if
len
(
self
.
args
)
!=
1
:
raise
AnsibleOptionsError
(
"Missing target hosts"
)
if
self
.
options
.
module_name
not
in
self
.
SUPPORTED_REPO_MODULES
:
raise
AnsibleOptionsError
(
"Unsuported repo module
%
s, choices are
%
s"
%
(
self
.
options
.
module_name
,
','
.
join
(
self
.
SUPPORTED_REPO_MODULES
)))
self
.
display
.
verbosity
=
self
.
options
.
verbosity
self
.
validate_conflicts
()
return
True
def
run
(
self
):
''' use Runner lib to do SSH things '''
raise
AnsibleError
(
"Not ported to v2 yet"
)
# log command line
now
=
datetime
.
datetime
.
now
()
self
.
display
.
display
(
now
.
strftime
(
"Starting Ansible Pull at
%
F
%
T"
))
self
.
display
.
display
(
' '
.
join
(
sys
.
argv
))
# Build Checkout command
# Now construct the ansible command
limit_opts
=
'localhost:
%
s:127.0.0.1'
%
socket
.
getfqdn
()
base_opts
=
'-c local --limit "
%
s"'
%
limit_opts
if
self
.
options
.
verbosity
>
0
:
base_opts
+=
' -
%
s'
%
''
.
join
([
"v"
for
x
in
range
(
0
,
self
.
options
.
verbosity
)
])
# Attempt to use the inventory passed in as an argument
# It might not yet have been downloaded so use localhost if note
if
not
self
.
options
.
inventory
or
not
os
.
path
.
exists
(
self
.
options
.
inventory
):
inv_opts
=
'localhost,'
else
:
inv_opts
=
self
.
options
.
inventory
#TODO: enable more repo modules hg/svn?
if
self
.
options
.
module_name
==
'git'
:
repo_opts
=
"name=
%
s dest=
%
s"
%
(
self
.
options
.
url
,
self
.
options
.
dest
)
if
self
.
options
.
checkout
:
repo_opts
+=
' version=
%
s'
%
self
.
options
.
checkout
if
self
.
options
.
accept_host_key
:
repo_opts
+=
' accept_hostkey=yes'
if
self
.
options
.
key_file
:
repo_opts
+=
' key_file=
%
s'
%
options
.
key_file
path
=
utils
.
plugins
.
module_finder
.
find_plugin
(
options
.
module_name
)
if
path
is
None
:
raise
AnsibleOptionsError
((
"module '
%
s' not found.
\n
"
%
options
.
module_name
))
bin_path
=
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))
cmd
=
'
%
s/ansible localhost -i "
%
s"
%
s -m
%
s -a "
%
s"'
%
(
bin_path
,
inv_opts
,
base_opts
,
self
.
options
.
module_name
,
repo_opts
)
for
ev
in
self
.
options
.
extra_vars
:
cmd
+=
' -e "
%
s"'
%
ev
# Nap?
if
self
.
options
.
sleep
:
self
.
display
.
display
(
"Sleeping for
%
d seconds..."
%
self
.
options
.
sleep
)
time
.
sleep
(
self
.
options
.
sleep
);
# RUN the Checkout command
rc
,
out
,
err
=
cmd_functions
.
run_cmd
(
cmd
,
live
=
True
)
if
rc
!=
0
:
if
self
.
options
.
force
:
self
.
display
.
warning
(
"Unable to update repository. Continuing with (forced) run of playbook."
)
else
:
return
rc
elif
self
.
options
.
ifchanged
and
'"changed": true'
not
in
out
:
self
.
display
.
display
(
"Repository has not changed, quitting."
)
return
0
playbook
=
self
.
select_playbook
(
path
)
if
playbook
is
None
:
raise
AnsibleOptionsError
(
"Could not find a playbook to run."
)
# Build playbook command
cmd
=
'
%
s/ansible-playbook
%
s
%
s'
%
(
bin_path
,
base_opts
,
playbook
)
if
self
.
options
.
vault_password_file
:
cmd
+=
" --vault-password-file=
%
s"
%
self
.
options
.
vault_password_file
if
self
.
options
.
inventory
:
cmd
+=
' -i "
%
s"'
%
self
.
options
.
inventory
for
ev
in
self
.
options
.
extra_vars
:
cmd
+=
' -e "
%
s"'
%
ev
if
self
.
options
.
ask_sudo_pass
:
cmd
+=
' -K'
if
self
.
options
.
tags
:
cmd
+=
' -t "
%
s"'
%
self
.
options
.
tags
os
.
chdir
(
self
.
options
.
dest
)
# RUN THE PLAYBOOK COMMAND
rc
,
out
,
err
=
cmd_functions
.
run_cmd
(
cmd
,
live
=
True
)
if
self
.
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
def
try_playbook
(
self
,
path
):
if
not
os
.
path
.
exists
(
path
):
return
1
if
not
os
.
access
(
path
,
os
.
R_OK
):
return
2
return
0
def
select_playbook
(
self
,
path
):
playbook
=
None
if
len
(
self
.
args
)
>
0
and
self
.
args
[
0
]
is
not
None
:
playbook
=
os
.
path
.
join
(
path
,
self
.
args
[
0
])
rc
=
self
.
try_playbook
(
playbook
)
if
rc
!=
0
:
self
.
display
.
warning
(
"
%
s:
%
s"
%
(
playbook
,
self
.
PLAYBOOK_ERRORS
[
rc
]))
return
None
return
playbook
else
:
fqdn
=
socket
.
getfqdn
()
hostpb
=
os
.
path
.
join
(
path
,
fqdn
+
'.yml'
)
shorthostpb
=
os
.
path
.
join
(
path
,
fqdn
.
split
(
'.'
)[
0
]
+
'.yml'
)
localpb
=
os
.
path
.
join
(
path
,
DEFAULT_PLAYBOOK
)
errors
=
[]
for
pb
in
[
hostpb
,
shorthostpb
,
localpb
]:
rc
=
self
.
try_playbook
(
pb
)
if
rc
==
0
:
playbook
=
pb
break
else
:
errors
.
append
(
"
%
s:
%
s"
%
(
pb
,
self
.
PLAYBOOK_ERRORS
[
rc
]))
if
playbook
is
None
:
self
.
display
.
warning
(
"
\n
"
.
join
(
errors
))
return
playbook
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment