mirror of
https://github.com/munki/munki.git
synced 2026-01-06 22:49:58 -06:00
135 lines
4.2 KiB
Python
135 lines
4.2 KiB
Python
# encoding: utf-8
|
|
#
|
|
# Copyright 2009-2018 Greg Neagle.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the 'License');
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# https://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an 'AS IS' BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""
|
|
scriptutils.py
|
|
|
|
Created by Greg Neagle on 2016-12-14.
|
|
|
|
|
|
Functions to run scripts inside Munki
|
|
"""
|
|
|
|
import os
|
|
import subprocess
|
|
|
|
from . import osutils
|
|
from . import display
|
|
from . import munkilog
|
|
from . import munkistatus
|
|
|
|
|
|
def _writefile(stringdata, path):
|
|
'''Writes string data to path.
|
|
Returns the path on success, empty string on failure.'''
|
|
try:
|
|
fileobject = open(path, mode='w', buffering=1)
|
|
# write line-by-line to ensure proper UNIX line-endings
|
|
for line in stringdata.splitlines():
|
|
print >> fileobject, line.encode('UTF-8')
|
|
fileobject.close()
|
|
return path
|
|
except (OSError, IOError):
|
|
display.display_error("Couldn't write %s" % stringdata)
|
|
return ""
|
|
|
|
|
|
def run_embedded_script(scriptname, pkginfo_item, suppress_error=False):
|
|
'''Runs a script embedded in the pkginfo.
|
|
Returns the result code.'''
|
|
|
|
# get the script text from the pkginfo
|
|
script_text = pkginfo_item.get(scriptname)
|
|
itemname = pkginfo_item.get('name')
|
|
if not script_text:
|
|
display.display_error(
|
|
'Missing script %s for %s' % (scriptname, itemname))
|
|
return -1
|
|
|
|
# write the script to a temp file
|
|
scriptpath = os.path.join(osutils.tmpdir(), scriptname)
|
|
if _writefile(script_text, scriptpath):
|
|
cmd = ['/bin/chmod', '-R', 'o+x', scriptpath]
|
|
retcode = subprocess.call(cmd)
|
|
if retcode:
|
|
display.display_error(
|
|
'Error setting script mode in %s for %s'
|
|
% (scriptname, itemname))
|
|
return -1
|
|
else:
|
|
display.display_error(
|
|
'Cannot write script %s for %s' % (scriptname, itemname))
|
|
return -1
|
|
|
|
# now run the script
|
|
return run_script(
|
|
itemname, scriptpath, scriptname, suppress_error=suppress_error)
|
|
|
|
|
|
def run_script(itemname, path, scriptname, suppress_error=False):
|
|
'''Runs a script, Returns return code.'''
|
|
if suppress_error:
|
|
display.display_detail(
|
|
'Running %s for %s ' % (scriptname, itemname))
|
|
else:
|
|
display.display_status_minor(
|
|
'Running %s for %s ' % (scriptname, itemname))
|
|
if display.munkistatusoutput:
|
|
# set indeterminate progress bar
|
|
munkistatus.percent(-1)
|
|
|
|
scriptoutput = []
|
|
try:
|
|
proc = subprocess.Popen(path, shell=False, bufsize=1,
|
|
stdin=subprocess.PIPE,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.STDOUT)
|
|
except OSError, err:
|
|
display.display_error(
|
|
'Error executing script %s: %s' % (scriptname, str(err)))
|
|
return -1
|
|
|
|
while True:
|
|
msg = proc.stdout.readline().decode('UTF-8')
|
|
if not msg and (proc.poll() != None):
|
|
break
|
|
# save all script output in case there is
|
|
# an error so we can dump it to the log
|
|
scriptoutput.append(msg)
|
|
msg = msg.rstrip("\n")
|
|
display.display_info(msg)
|
|
|
|
retcode = proc.poll()
|
|
if retcode and not suppress_error:
|
|
display.display_error(
|
|
'Running %s for %s failed.' % (scriptname, itemname))
|
|
display.display_error("-"*78)
|
|
for line in scriptoutput:
|
|
display.display_error("\t%s" % line.rstrip("\n"))
|
|
display.display_error("-"*78)
|
|
elif not suppress_error:
|
|
munkilog.log(
|
|
'Running %s for %s was successful.' % (scriptname, itemname))
|
|
|
|
if display.munkistatusoutput:
|
|
# clear indeterminate progress bar
|
|
munkistatus.percent(0)
|
|
|
|
return retcode
|
|
|
|
|
|
if __name__ == '__main__':
|
|
print 'This is a library of support tools for the Munki Suite.'
|