/tmp with noexec fix

Adds option to specify tmp folder prefix and also defines a
default tmp folder outside of /tmp.

There's also a new validation that makes sure that scripts
are executable.

Change-Id: Icc568d0750826b2da24e7fa3bfa6def0fb151209
Closes-Bug: #1796220
This commit is contained in:
David Vallee Delisle 2018-10-08 21:59:07 -04:00
parent bbd29e1814
commit e945184cdc
3 changed files with 28 additions and 12 deletions

View File

@ -69,6 +69,10 @@ def load_args(argv):
parser.add_argument(
'--no-cleanup', action='store_true',
help=("Do not cleanup tmp directories"))
parser.add_argument(
'--tmp-folder', action='store', type=str,
default=os.path.join(os.path.expanduser('~'), '.instack/tmp'),
help=("Temporary folder prefix"))
parser.add_argument(
'-l', '--logfile', action='store',
default=os.path.join(os.path.expanduser('~'), '.instack/instack.log'),
@ -131,7 +135,14 @@ def cleanup(tmp_dir):
def main(argv=sys.argv):
args = load_args(argv[1:])
tmp_dir = tempfile.mkdtemp(prefix='instack.')
try:
os.makedirs(args.tmp_folder)
except OSError as e:
if e.errno != errno.EEXIST:
raise
tmp_dir = tempfile.mkdtemp(prefix=os.path.join(args.tmp_folder,
'instack.'))
try:
os.makedirs(os.path.dirname(args.logfile))
except OSError as e:
@ -164,13 +175,13 @@ def main(argv=sys.argv):
if "name" in run:
LOG.info("Running %s" % run["name"])
em = runner.ElementRunner(
run['element'], run['hook'], args.element_path,
run['element'], run['hook'], tmp_dir, args.element_path,
run.get('blacklist', []), run.get('exclude-element', []),
args.dry_run, args.interactive, args.no_cleanup)
em.run()
else:
em = runner.ElementRunner(
args.element, args.hook, args.element_path,
args.element, args.hook, tmp_dir, args.element_path,
args.blacklist, args.exclude_element,
args.dry_run, args.interactive,
args.no_cleanup)

View File

@ -44,9 +44,9 @@ LOG = logging.getLogger()
class ElementRunner(object):
def __init__(self, elements, hooks, element_paths=None, blacklist=None,
exclude_elements=None, dry_run=False, interactive=False,
no_cleanup=False):
def __init__(self, elements, hooks, tmp_folder, element_paths=None,
blacklist=None, exclude_elements=None, dry_run=False,
interactive=False, no_cleanup=False):
"""Element Runner initialization.
:param elements: Element names to apply.
@ -66,7 +66,8 @@ class ElementRunner(object):
self.interactive = interactive
self.no_cleanup = no_cleanup
self.loaded_elements = {}
self.tmp_hook_dir = tempfile.mkdtemp()
self.tmp_hook_dir = tempfile.mkdtemp(prefix='hook',
dir=''.join(tmp_folder))
self.environment_file = os.path.join(self.tmp_hook_dir,
'environment.d',
'00-dib-v2-env')
@ -192,10 +193,14 @@ class ElementRunner(object):
"exist at %s" % (hook, hook_dir))
return
for blacklisted_script in self.blacklist:
if blacklisted_script in os.listdir(hook_dir):
LOG.debug(" Blacklisting %s" % blacklisted_script)
os.unlink(os.path.join(hook_dir, blacklisted_script))
for script in os.listdir(hook_dir):
script_fullpath = os.path.join(hook_dir, script)
if script in self.blacklist:
LOG.debug(" Blacklisting %s" % script)
os.unlink(script_fullpath)
if not os.access(script_fullpath, os.X_OK):
LOG.debug("Script %s not executable" % script)
command = [_DIB_RUN_PARTS, hook_dir]
if self.dry_run:

View File

@ -36,7 +36,7 @@ class TestRunner(testtools.TestCase):
'generate_environment')
self.mock_env = self.patcher.start()
self.runner = runner.ElementRunner(['dep2', 'echo', 'os'], [],
self.element_paths)
'/tmp', self.element_paths)
tmp_dir = tempfile.mkdtemp()
self.runner.tmp_hook_dir = tmp_dir