Refactor salt.utils.filecopy() out of salt.utils

Done to ease the use of salt.modules.selinux here. Added better checking
for selinux to fix #16999
This commit is contained in:
Mike Place 2014-10-29 14:32:31 -06:00
parent 0d0f2ddb7e
commit a774266f6f
4 changed files with 74 additions and 58 deletions

View File

@ -2963,7 +2963,7 @@ def manage_file(name,
transfer the file to the minion again.
This file is then grabbed and if it has template set, it renders the file to be placed
into the correct place on the system using salt.utils.copyfile()
into the correct place on the system using salt.files.utils.copyfile()
source
file reference on the master
@ -3065,7 +3065,7 @@ def manage_file(name,
# Pre requisites are met, and the file needs to be replaced, do it
try:
salt.utils.copyfile(sfn,
salt.utils.files.copyfile(sfn,
real_name,
__salt__['config.backup_mode'](backup),
__opts__['cachedir'])
@ -3103,7 +3103,7 @@ def manage_file(name,
# Pre requisites are met, the file needs to be replaced, do it
try:
salt.utils.copyfile(tmp,
salt.utils.files.copyfile(tmp,
real_name,
__salt__['config.backup_mode'](backup),
__opts__['cachedir'])
@ -3134,7 +3134,7 @@ def manage_file(name,
return ret
try:
salt.utils.copyfile(sfn,
salt.utils.files.copyfile(sfn,
name,
__salt__['config.backup_mode'](backup),
__opts__['cachedir'])
@ -3255,14 +3255,14 @@ def manage_file(name,
with salt.utils.fopen(tmp, 'w') as tmp_:
tmp_.write(str(contents))
# Copy into place
salt.utils.copyfile(tmp,
salt.utils.files.copyfile(tmp,
name,
__salt__['config.backup_mode'](backup),
__opts__['cachedir'])
__clean_tmp(tmp)
# Now copy the file contents if there is a source file
elif sfn:
salt.utils.copyfile(sfn,
salt.utils.files.copyfile(sfn,
name,
__salt__['config.backup_mode'](backup),
__opts__['cachedir'])

View File

@ -29,6 +29,7 @@ except ImportError:
# Import salt libs
import salt.utils
import salt.utils.files
import salt.utils.templates
import salt.utils.validate.net
from salt._compat import StringIO as _StringIO
@ -573,7 +574,7 @@ def init(name,
if not os.path.isdir(img_dir):
os.makedirs(img_dir)
try:
salt.utils.copyfile(sfn, img_dest)
salt.utils.files.copyfile(sfn, img_dest)
mask = os.umask(0)
os.umask(mask)
# Apply umask and remove exec bit

View File

@ -672,56 +672,6 @@ def check_or_die(command):
raise CommandNotFoundError(command)
def copyfile(source, dest, backup_mode='', cachedir=''):
'''
Copy files from a source to a destination in an atomic way, and if
specified cache the file.
'''
if not os.path.isfile(source):
raise IOError(
'[Errno 2] No such file or directory: {0}'.format(source)
)
if not os.path.isdir(os.path.dirname(dest)):
raise IOError(
'[Errno 2] No such file or directory: {0}'.format(dest)
)
bname = os.path.basename(dest)
dname = os.path.dirname(os.path.abspath(dest))
tgt = mkstemp(prefix=bname, dir=dname)
shutil.copyfile(source, tgt)
bkroot = ''
if cachedir:
bkroot = os.path.join(cachedir, 'file_backup')
if backup_mode == 'minion' or backup_mode == 'both' and bkroot:
if os.path.exists(dest):
backup_minion(dest, bkroot)
if backup_mode == 'master' or backup_mode == 'both' and bkroot:
# TODO, backup to master
pass
# Get current file stats to they can be replicated after the new file is
# moved to the destination path.
fstat = None
if not salt.utils.is_windows():
try:
fstat = os.stat(dest)
except OSError:
pass
shutil.move(tgt, dest)
if fstat is not None:
os.chown(dest, fstat.st_uid, fstat.st_gid)
os.chmod(dest, fstat.st_mode)
# If SELINUX is available run a restorecon on the file
rcon = which('restorecon')
if rcon:
with fopen(os.devnull, 'w') as dev_null:
cmd = [rcon, dest]
subprocess.call(cmd, stdout=dev_null, stderr=dev_null)
if os.path.isfile(tgt):
# The temp file failed to move
try:
os.remove(tgt)
except Exception:
pass
def backup_minion(path, bkroot):

View File

@ -1,6 +1,13 @@
# -*- coding: utf-8 -*-
# Import Python libs
import os
import shutil
import subprocess
# Import salt libs
import salt.utils
import salt.modules.selinux
def recursive_copy(source, dest):
@ -10,7 +17,7 @@ def recursive_copy(source, dest):
(identical to cp -r on a unix machine)
'''
for root, dirs, files in os.walk(source):
for root, _, files in os.walk(source):
path_from_source = root.replace(source, '').lstrip('/')
target_directory = os.path.join(dest, path_from_source)
if not os.path.exists(target_directory):
@ -19,3 +26,61 @@ def recursive_copy(source, dest):
file_path_from_source = os.path.join(source, path_from_source, name)
target_path = os.path.join(target_directory, name)
shutil.copyfile(file_path_from_source, target_path)
def copyfile(source, dest, backup_mode='', cachedir=''):
'''
Copy files from a source to a destination in an atomic way, and if
specified cache the file.
'''
if not os.path.isfile(source):
raise IOError(
'[Errno 2] No such file or directory: {0}'.format(source)
)
if not os.path.isdir(os.path.dirname(dest)):
raise IOError(
'[Errno 2] No such file or directory: {0}'.format(dest)
)
bname = os.path.basename(dest)
dname = os.path.dirname(os.path.abspath(dest))
tgt = salt.utils.mkstemp(prefix=bname, dir=dname)
shutil.copyfile(source, tgt)
bkroot = ''
if cachedir:
bkroot = os.path.join(cachedir, 'file_backup')
if backup_mode == 'minion' or backup_mode == 'both' and bkroot:
if os.path.exists(dest):
salt.utils.backup_minion(dest, bkroot)
if backup_mode == 'master' or backup_mode == 'both' and bkroot:
# TODO, backup to master
pass
# Get current file stats to they can be replicated after the new file is
# moved to the destination path.
fstat = None
if not salt.utils.is_windows():
try:
fstat = os.stat(dest)
except OSError:
pass
shutil.move(tgt, dest)
if fstat is not None:
os.chown(dest, fstat.st_uid, fstat.st_gid)
os.chmod(dest, fstat.st_mode)
# If SELINUX is available run a restorecon on the file
rcon = salt.utils.which('restorecon')
if rcon:
policy = False
try:
policy = salt.modules.selinux.getenforce()
except ImportError:
pass
if policy == 'Enforcing':
with salt.utils.fopen(os.devnull, 'w') as dev_null:
cmd = [rcon, dest]
subprocess.call(cmd, stdout=dev_null, stderr=dev_null)
if os.path.isfile(tgt):
# The temp file failed to move
try:
os.remove(tgt)
except Exception:
pass