diff --git a/salt/fileclient.py b/salt/fileclient.py index 2b2df0cc8f..996a4831ad 100644 --- a/salt/fileclient.py +++ b/salt/fileclient.py @@ -140,7 +140,7 @@ class Client(object): ret.append(self.cache_file('salt://{0}'.format(path), env)) return ret - def cache_dir(self, path, env='base'): + def cache_dir(self, path, env='base', include_empty=False): ''' Download all of the files in a subdir of the master ''' @@ -152,6 +152,27 @@ class Client(object): if not fn_.strip(): continue ret.append(local) + + if include_empty: + # Break up the path into a list containing the bottom-level directory + # (the one being recursively copied) and the directories preceding it + separated = string.rsplit(path,'/',1) + if len(separated) != 2: + # No slashes in path. (This means all files in env will be copied) + prefix = '' + else: + prefix = separated[0] + for fn_ in self.file_list_emptydirs(env): + if fn_.startswith(path): + dest = os.path.normpath( + os.sep.join([ + self.opts['cachedir'], + 'files', + env])) + minion_dir = '%s/%s' % (dest,fn_) + if not os.path.isdir(minion_dir): + os.makedirs(minion_dir) + ret.append(minion_dir) return ret def cache_local_file(self, path, **kwargs): diff --git a/salt/modules/cp.py b/salt/modules/cp.py index bf3da89c8a..3b2c2022d5 100644 --- a/salt/modules/cp.py +++ b/salt/modules/cp.py @@ -123,7 +123,7 @@ def cache_files(paths, env='base'): return client.cache_files(paths, env) -def cache_dir(path, env='base'): +def cache_dir(path, env='base', include_empty=False): ''' Download and cache everything under a directory from the master @@ -132,7 +132,7 @@ def cache_dir(path, env='base'): salt '*' cp.cache_dir salt://path/to/dir ''' client = salt.fileclient.get_file_client(__opts__) - return client.cache_dir(path, env) + return client.cache_dir(path, env, include_empty) def cache_master(env='base'): diff --git a/salt/states/file.py b/salt/states/file.py index c2dfd12198..4f75d4a040 100644 --- a/salt/states/file.py +++ b/salt/states/file.py @@ -88,6 +88,7 @@ import copy # Import Salt libs import salt.utils.templates +import pdb logger = logging.getLogger(__name__) @@ -415,14 +416,15 @@ def _check_recurse( group, dir_mode, file_mode, - env): + env, + include_empty): ''' Check what files will be changed by a recurse call ''' vdir = set() keep = set() changes = {} - for fn_ in __salt__['cp.cache_dir'](source, env): + for fn_ in __salt__['cp.cache_dir'](source, env, include_empty): if not fn_.strip(): continue dest = os.path.join(name, @@ -1210,6 +1212,7 @@ def recurse(name, dir_mode=None, file_mode=None, env=None, + include_empty=False, **kwargs): ''' Recurse through a subdirectory on the master and copy said subdirecory @@ -1245,6 +1248,10 @@ def recurse(name, file_mode The permissions mode to set any files created + + include_empty + Set this to True if empty directories should also be created + (default is False) ''' ret = {'name': name, 'changes': {}, @@ -1274,10 +1281,11 @@ def recurse(name, group, dir_mode, file_mode, - env) + env, + include_empty) return ret vdir = set() - for fn_ in __salt__['cp.cache_dir'](source, env): + for fn_ in __salt__['cp.cache_dir'](source, env, include_empty): if not fn_.strip(): continue dest = os.path.join(name, @@ -1317,11 +1325,21 @@ def recurse(name, # FIXME: no metadata (ownership, permissions) available shutil.copyfile(fn_, dest) ret['changes'][dest] = 'updated' + elif os.path.isdir(dest) and include_empty: + #check perms + _ret, perms = _check_perms(dest, {}, user, group, dir_mode) + if _ret['changes']: + ret['changes'][dest] = 'updated' + keep.add(dest) else: keep.add(dest) - # The destination file is not present, make it - # FIXME: no metadata (ownership, permissions) available - shutil.copyfile(fn_, dest) + if os.path.isdir(fn_) and include_empty: + #create empty dir + os.mkdir(dest,dir_mode) + else: + # The destination file is not present, make it + # FIXME: no metadata (ownership, permissions) available + shutil.copyfile(fn_, dest) ret['changes'][dest] = 'new' keep = list(keep) if clean: