Misc refactoring, updated TODO to reflect new templating features being completed

This commit is contained in:
Michael DeHaan 2012-02-05 13:25:10 -05:00
parent ba9468266f
commit de80166b6d
2 changed files with 51 additions and 52 deletions

22
TODO.md
View file

@ -4,30 +4,22 @@ TODO list and plans
Playbook TODO: Playbook TODO:
* error codes and failure summaries * error codes and failure summaries
* create modules that return 'changed' attributes * handle 'changed' attributes
* fail nodes on errors, i.e. remove from host list, rather than continuing to pound them * fail nodes on errors, i.e. remove from host list, rather than continuing to pound them
* further improve output * further improve output
* more conditional capability * more conditional capability (if statement) (?)
* very good logging * very good logging
Command module: Command module:
* allow additional key/value options to be passed to any module (via ENV vars?) * magic to pull async & timeout options off of the command line and not feed them
* allow this to be expressed in playbook as a 4th option after the array options list to the app we're executing
* use this to pass timeout and async params to the command module
default timeouts will be infinite, async False
General: General:
* logging * better logging
* async options * async options
* modules for users, groups, and files, using puppet style ensure mechanics * modules for users, groups, and files, using puppet style ensure mechanics
* very simple option constructing/parsing for modules * think about how to build idempotency (aka Puppet-style 'creates') around command module?
* templating module (how might this work syntax wise?) with facter/ohai awareness
* probably could lay down a values.json file
* use copy capabilities to move files to tmp, run python templating
* maybe support templating engine of choice
* think about how to build idempotency guards around command module?
* think about how to feed extra JSON data onto system
Bonus utilities: Bonus utilities:

View file

@ -24,11 +24,8 @@ import multiprocessing
import os import os
import json import json
import traceback import traceback
import paramiko # non-core dependency
# non-core import ansible.constants as C
import paramiko
import constants as C
def _executor_hook(x): def _executor_hook(x):
''' callback used by multiprocessing pool ''' ''' callback used by multiprocessing pool '''
@ -48,10 +45,17 @@ class Runner(object):
remote_user=C.DEFAULT_REMOTE_USER, remote_user=C.DEFAULT_REMOTE_USER,
remote_pass=C.DEFAULT_REMOTE_PASS, remote_pass=C.DEFAULT_REMOTE_PASS,
verbose=False): verbose=False):
'''
''' Constructor
Constructor. host_list -- file on disk listing hosts to manage, or an array of hostnames
pattern ------ a fnmatch pattern selecting some of the hosts in host_list
module_path -- location of ansible library on disk
module_name -- which module to run
module_args -- arguments to pass to module
forks -------- how parallel should we be? 1 is extra debuggable.
remote_user -- who to login as (default root)
remote_pass -- provide only if you don't want to use keys or ssh-agent
''' '''
self.host_list = self._parse_hosts(host_list) self.host_list = self._parse_hosts(host_list)
@ -109,44 +113,52 @@ class Runner(object):
for filename in files: for filename in files:
self._exec_command(conn, "rm -f %s" % filename) self._exec_command(conn, "rm -f %s" % filename)
def _transfer_file(self, conn, source, dest):
self.remote_log(conn, 'COPY remote:%s local:%s' % (source, dest))
ftp = conn.open_sftp()
ftp.put(source, dest)
ftp.close()
def _transfer_module(self, conn):
outpath = self._copy_module(conn)
self._exec_command(conn, "chmod +x %s" % outpath)
return outpath
def _execute_module(self, conn, outpath):
cmd = self._command(outpath)
result = self._exec_command(conn, cmd)
self._delete_remote_files(conn, [ outpath ])
return result
def _execute_normal_module(self, conn, host): def _execute_normal_module(self, conn, host):
''' transfer a module, set it executable, and run it ''' ''' transfer a module, set it executable, and run it '''
outpath = self._copy_module(conn) module = self._transfer_module(conn)
self._exec_command(conn, "chmod +x %s" % outpath) result = self._execute_module(conn, module)
cmd = self._command(outpath)
result = self._exec_command(conn, cmd)
self._delete_remote_files(conn, outpath)
return self._return_from_module(conn, host, result) return self._return_from_module(conn, host, result)
def _execute_copy(self, conn, host): def _execute_copy(self, conn, host):
''' transfer a file + copy module, run copy module, clean up ''' ''' handler for file transfer operations '''
self.remote_log(conn, 'COPY remote:%s local:%s' % (self.module_args[0], self.module_args[1])) # transfer the file to a remote tmp location
source = self.module_args[0] source = self.module_args[0]
dest = self.module_args[1] dest = self.module_args[1]
tmp_dest = self._get_tmp_path(conn, dest.split("/")[-1]) tmp_dest = self._get_tmp_path(conn, dest.split("/")[-1])
self._transfer_file(conn, source, tmp_dest)
ftp = conn.open_sftp()
ftp.put(source, tmp_dest)
ftp.close()
# install the copy module # install the copy module
self.module_name = 'copy' self.module_name = 'copy'
outpath = self._copy_module(conn) module = self._transfer_module(conn)
self._exec_command(conn, "chmod +x %s" % outpath)
# run the copy module # run the copy module
self.module_args = [ tmp_dest, dest ] self.module_args = [ tmp_dest, dest ]
cmd = self._command(outpath) result = self._execute_module(conn, module)
result = self._exec_command(conn, cmd) self._delete_remote_files(conn, tmp_dest)
self._delete_remote_files(conn, [outpath, tmp_dest])
return self._return_from_module(conn, host, result) return self._return_from_module(conn, host, result)
def _execute_template(self, conn, host): def _execute_template(self, conn, host):
''' handler for template operations '''
source = self.module_args[0] source = self.module_args[0]
dest = self.module_args[1] dest = self.module_args[1]
metadata = '/etc/ansible/setup' metadata = '/etc/ansible/setup'
@ -154,21 +166,16 @@ class Runner(object):
# first copy the source template over # first copy the source template over
tempname = os.path.split(source)[-1] tempname = os.path.split(source)[-1]
temppath = self._get_tmp_path(conn, tempname) temppath = self._get_tmp_path(conn, tempname)
self.remote_log(conn, 'COPY remote:%s local:%s' % (source, temppath)) self._transfer_file(conn, source, temppath)
ftp = conn.open_sftp()
ftp.put(source, temppath)
ftp.close()
# install the template module # install the template module
self.module_name = 'template' self.module_name = 'template'
outpath = self._copy_module(conn) module = self._transfer_module(conn)
self._exec_command(conn, "chmod +x %s" % outpath)
# run the template module # run the template module
self.module_args = [ temppath, dest, metadata ] self.module_args = [ temppath, dest, metadata ]
result = self._exec_command(conn, self._command(outpath)) result = self._execute_module(conn, module)
# clean up self._delete_remote_files(conn, [ temppath ])
self._delete_remote_files(conn, [ outpath, temppath ])
return self._return_from_module(conn, host, result) return self._return_from_module(conn, host, result)