Convert all print statements to Python3-compatible print functions

This commit is contained in:
Greg Neagle
2019-05-03 19:47:37 -07:00
parent 2ad27ff411
commit 531d99a01a
72 changed files with 452 additions and 383 deletions

View File

@@ -24,6 +24,7 @@ Much code based on and adapted from autopkgserver by Per Olofsson
A privileged daemon that records app usage events and install requests to our
app usage database.
"""
from __future__ import print_function
import os
import sys
@@ -262,7 +263,7 @@ def main():
'''Start our daemon, connect to socket and process events'''
# Make sure we're launched as root
if os.geteuid() != 0:
print >> sys.stderr, '%s must be run as root.' % APPNAME
print('%s must be run as root.' % APPNAME, file=sys.stderr)
# Sleep to avoid respawn.
time.sleep(10)
return 1
@@ -278,13 +279,14 @@ def main():
while True:
info = os.stat(exepath)
if info.st_uid != root_uid:
print >> sys.stderr, '%s must be owned by root.' % exepath
print('%s must be owned by root.' % exepath, file=sys.stderr)
path_ok = False
if info.st_gid not in (wheel_gid, admin_gid):
print >> sys.stderr, '%s must have group wheel or admin.' % exepath
print('%s must have group wheel or admin.' % exepath,
file=sys.stderr)
path_ok = False
if info.st_mode & stat.S_IWOTH:
print >> sys.stderr, '%s mustn\'t be world writeable.' % exepath
print('%s mustn\'t be world writeable.' % exepath, file=sys.stderr)
path_ok = False
exepath = os.path.dirname(exepath)
if exepath == '/':
@@ -301,7 +303,7 @@ def main():
# Get socket file descriptors from launchd.
socket_fd = launchd.get_socket_fd(APPNAME)
if not socket_fd:
print >> sys.stderr, 'No socket provided to us by launchd'
print('No socket provided to us by launchd', file=sys.stderr)
time.sleep(10)
return 1

View File

@@ -27,6 +27,7 @@ Root user can trigger an authrestart, possibly using the password stored
earlier by a non-privileged user.
"""
from __future__ import print_function
import os
import sys
@@ -336,7 +337,7 @@ def main():
'''Start our daemon, connect to socket and process requests'''
# Make sure we're launched as root
if os.geteuid() != 0:
print >>sys.stderr, '%s must be run as root.' % APPNAME
print('%s must be run as root.' % APPNAME, file=sys.stderr)
# Sleep to avoid respawn.
time.sleep(10)
return 1
@@ -352,13 +353,14 @@ def main():
while True:
info = os.stat(exepath)
if info.st_uid != root_uid:
print >> sys.stderr, '%s must be owned by root.' % exepath
print('%s must be owned by root.' % exepath, file=sys.stderr)
path_ok = False
if info.st_gid not in (wheel_gid, admin_gid):
print >> sys.stderr, '%s must have group wheel or admin.' % exepath
print('%s must have group wheel or admin.' % exepath,
file=sys.stderr)
path_ok = False
if info.st_mode & stat.S_IWOTH:
print >> sys.stderr, '%s mustn\'t be world writeable.' % exepath
print('%s mustn\'t be world writeable.' % exepath, file=sys.stderr)
path_ok = False
exepath = os.path.dirname(exepath)
if exepath == '/':
@@ -375,7 +377,7 @@ def main():
# Get socket file descriptors from launchd.
socket_fd = launchd.get_socket_fd('authrestartd')
if not socket_fd:
print >> sys.stderr, 'No socket provided to us by launchd'
print('No socket provided to us by launchd', file=sys.stderr)
time.sleep(10)
return 1

View File

@@ -25,6 +25,7 @@ Prevents multiple copies of the app from being launched
when Fast User Switching is in use
Intended for use by a launchd LaunchAgent.
"""
from __future__ import print_function
import sys
import os
@@ -62,7 +63,7 @@ def main():
if len(sys.argv) > 1:
cmd.extend(sys.argv[1:])
else:
print >> sys.stderr, "Must specify an app to launch!"
print("Must specify an app to launch!", file=sys.stderr)
exit(-1)
retcode = subprocess.call(cmd)
# sleep 10 secs to make launchd happy

View File

@@ -26,6 +26,7 @@ Assumes a pkgsinfo directory under repopath.
User calling this needs to be able to write to repo/catalogs.
"""
from __future__ import print_function
import optparse
import sys
@@ -58,7 +59,7 @@ def main():
options, arguments = parser.parse_args()
if options.version:
print get_version()
print(get_version())
exit(0)
# backwards compatibility
@@ -79,8 +80,8 @@ def main():
try:
repo = munkirepo.connect(options.repo_url, options.plugin)
except munkirepo.RepoError as err:
print >> sys.stderr, (u'Could not connect to munki repo: %s'
% unicode(err))
print(u'Could not connect to munki repo: %s' % unicode(err),
file=sys.stderr)
exit(-1)
# Make the catalogs
@@ -88,7 +89,7 @@ def main():
if errors:
# group all errors at the end for better visibility
print
print()
for error in errors:
print_err_utf8(error)
exit(-1)

View File

@@ -31,6 +31,7 @@ The generated plist is printed to STDOUT.
Usage: makepkginfo /path/to/package_or_dmg [-f /path/to/item/it/installs ...]
"""
from __future__ import print_function
# standard libs
import optparse
@@ -73,7 +74,7 @@ def main():
options, arguments = parser.parse_args()
if options.version:
print info.get_version()
print(info.get_version())
exit(0)
if (len(arguments) == 0 and
@@ -93,14 +94,14 @@ def main():
if (options.minimum_os_version and
not options.minimum_os_version[0].isdigit()):
print >> sys.stderr, (
'Minimum OS Version must start with a number, e.g. 10.7.2.')
print('Minimum OS Version must start with a number, e.g. 10.7.2.',
file=sys.stderr)
exit(-1)
if len(arguments) > 1:
print >> sys.stderr, 'Can process only one installer item at a time.'
print >> sys.stderr, 'Ignoring additional installer items:'
print >> sys.stderr, '\t', '\n\t'.join(arguments[1:])
print('Can process only one installer item at a time.', file=sys.stderr)
print('Ignoring additional installer items:', file=sys.stderr)
print('\t', '\n\t'.join(arguments[1:]), file=sys.stderr)
os_version = osutils.getOsVersion(
only_major_minor=False, as_tuple=True)
@@ -115,7 +116,7 @@ def main():
try:
pkginfo = pkginfolib.makepkginfo(installeritem, options)
except pkginfolib.PkgInfoGenerationError as err:
print >> sys.stderr, err
print(err, file=sys.stderr)
exit(-1)
if (len(arguments) == 1 and
@@ -132,10 +133,10 @@ def main():
" This can result in repeated installation attempts or failure "
"to attempt\n"
" installation at all.")
print >> sys.stderr, msg % item
print(msg % item, file=sys.stderr)
# and now, what we've all been waiting for...
print FoundationPlist.writePlistToString(pkginfo)
print(FoundationPlist.writePlistToString(pkginfo))
if __name__ == '__main__':

View File

@@ -17,6 +17,7 @@
"""
managedsoftwareupdate
"""
from __future__ import print_function
import optparse
import os
@@ -43,16 +44,16 @@ try:
except ImportError:
# Python is missing ObjC bindings. Run external report script.
from munkilib import utils
print >> sys.stderr, 'Python is missing ObjC bindings.'
print('Python is missing ObjC bindings.', file=sys.stderr)
_scriptdir = os.path.realpath(os.path.dirname(sys.argv[0]))
_script = os.path.join(_scriptdir, 'report_broken_client')
try:
_result, _stdout, _stderr = utils.runExternalScript(_script)
print >> sys.stderr, _result, _stdout, _stderr
print(_result, _stdout, _stderr, file=sys.stderr)
except utils.ScriptNotFoundError:
pass # script is not required, so pass
except utils.RunExternalScriptError as err:
print >> sys.stderr, str(err)
print(str(err), file=sys.stderr)
sys.exit(200)
else:
from munkilib import appleupdates
@@ -144,7 +145,7 @@ def createDirsIfNeeded(dirlist):
try:
os.mkdir(directory)
except (OSError, IOError):
print >> sys.stderr, 'ERROR: Could not create %s' % directory
print('ERROR: Could not create %s' % directory, file=sys.stderr)
return False
return True
@@ -369,7 +370,7 @@ def doRestart(shutdown=False):
# this restart (perhaps by force-quitting the app),
# that's their problem...
else:
print 'Please restart immediately.'
print('Please restart immediately.')
def munkiUpdatesAvailable():
@@ -641,12 +642,12 @@ def main():
options, dummy_arguments = parser.parse_args()
if options.version:
print info.get_version()
print(info.get_version())
exit(0)
# check to see if we're root
if os.geteuid() != 0:
print >> sys.stderr, 'You must run this as root!'
print('You must run this as root!', file=sys.stderr)
exit(constants.EXIT_STATUS_ROOT_REQUIRED)
if options.show_config:
@@ -656,19 +657,19 @@ def main():
if options.set_bootstrap_mode:
try:
bootstrapping.set_bootstrap_mode()
print 'Bootstrap mode is set.'
print('Bootstrap mode is set.')
exit(0)
except bootstrapping.SetupError as err:
print >> sys.stderr, err
print(err, file=sys.stderr)
exit(-1)
if options.clear_bootstrap_mode:
try:
bootstrapping.clear_bootstrap_mode()
print 'Bootstrap mode cleared.'
print('Bootstrap mode cleared.')
exit(0)
except bootstrapping.SetupError as err:
print >> sys.stderr, err
print(err, file=sys.stderr)
exit(-1)
# check to see if another instance of this script is running
@@ -682,8 +683,8 @@ def main():
% (myname, other_managedsoftwareupdate_pid))
munkilog.log('pid %s exiting.' % os.getpid())
munkilog.log('*' * 60)
print >> sys.stderr, (
'Another instance of %s is running. Exiting.' % myname)
print('Another instance of %s is running. Exiting.' % myname,
file=sys.stderr)
osutils.cleanUpTmpDir()
exit(0)
@@ -773,8 +774,8 @@ def main():
options.verbose = 0
if options.checkonly and options.installonly:
print >> sys.stderr, \
'--checkonly and --installonly options are mutually exclusive!'
print('--checkonly and --installonly options are mutually exclusive!',
file=sys.stderr)
exit(constants.EXIT_STATUS_INVALID_PARAMETERS)
# set munkicommon globals
@@ -801,9 +802,9 @@ def main():
munkilog.log("### Starting managedsoftwareupdate run: %s ###" % runtype)
if options.verbose:
print 'Managed Software Update Tool'
print 'Copyright 2010-2019 The Munki Project'
print 'https://github.com/munki/munki\n'
print('Managed Software Update Tool')
print('Copyright 2010-2019 The Munki Project')
print('https://github.com/munki/munki\n')
display.display_status_major('Starting...')
sendStartNotification()
@@ -1060,7 +1061,7 @@ def main():
else:
# no updates available
if options.installonly and not options.quiet:
print 'Nothing to install or remove.'
print('Nothing to install or remove.')
if runtype == 'checkandinstallatstartup':
# we have nothing to do, clear the bootstrapping mode
# so we'll stop running at startup/logout
@@ -1076,7 +1077,7 @@ def main():
munkilog.log("### Ending managedsoftwareupdate run ###")
if options.verbose:
print 'Done.'
print('Done.')
if notify_user:
# it may have been more than a minute since we ran our original

View File

@@ -19,6 +19,7 @@ manifestutil
Created by Greg Neagle on 2011-03-04.
"""
from __future__ import print_function
# TODO: add support for delete-manifest
@@ -48,8 +49,8 @@ def get_installer_item_names(repo, catalog_limit_list):
try:
catalogs_list = repo.itemlist('catalogs')
except munkirepo.RepoError as err:
print >> sys.stderr, (
'Could not retrieve catalogs: %s' % unicode(err))
print((
'Could not retrieve catalogs: %s' % unicode(err)), file=sys.stderr)
return []
for catalog_name in catalogs_list:
if catalog_name in catalog_limit_list:
@@ -57,9 +58,9 @@ def get_installer_item_names(repo, catalog_limit_list):
data = repo.get(os.path.join('catalogs', catalog_name))
catalog = plistlib.readPlistFromString(data)
except munkirepo.RepoError as err:
print >> sys.stderr, (
print((
'Could not retrieve catalog %s: %s'
% (catalog_name, unicode(err)))
% (catalog_name, unicode(err))), file=sys.stderr)
except (IOError, OSError, ExpatError):
# skip items that aren't valid plists
# or that we can't read
@@ -78,8 +79,8 @@ def get_manifest_names(repo):
try:
manifest_names = repo.itemlist('manifests')
except munkirepo.RepoError as err:
print >> sys.stderr, (
'Could not retrieve manifests: %s' % unicode(err))
print((
'Could not retrieve manifests: %s' % unicode(err)), file=sys.stderr)
manifest_names = []
manifest_names.sort()
return manifest_names
@@ -90,8 +91,8 @@ def get_catalogs(repo):
try:
catalog_names = repo.itemlist('catalogs')
except munkirepo.RepoError as err:
print >> sys.stderr, (
'Could not retrieve catalogs: %s' % unicode(err))
print((
'Could not retrieve catalogs: %s' % unicode(err)), file=sys.stderr)
catalog_names = []
catalog_names.sort()
return catalog_names
@@ -109,24 +110,24 @@ def printplistitem(label, value, indent=0):
"""Prints a plist item in an 'attractive' way"""
indentspace = ' '
if value is None:
print indentspace*indent, '%s: !NONE!' % label
print(indentspace*indent, '%s: !NONE!' % label)
elif isinstance(value, list) or type(value).__name__ == 'NSCFArray':
if label:
print indentspace*indent, '%s:' % label
print(indentspace*indent, '%s:' % label)
for item in value:
printplistitem('', item, indent+1)
elif isinstance(value, dict) or type(value).__name__ == 'NSCFDictionary':
if label:
print indentspace*indent, '%s:' % label
print(indentspace*indent, '%s:' % label)
keys = list(value.keys())
keys.sort()
for subkey in keys:
printplistitem(subkey, value[subkey], indent+1)
else:
if label:
print indentspace*indent, '%s: %s' % (label, value)
print(indentspace*indent, '%s: %s' % (label, value))
else:
print indentspace*indent, '%s' % value
print(indentspace*indent, '%s' % value)
def printplist(plistdict):
@@ -144,12 +145,12 @@ def get_manifest(repo, manifest_name):
data = repo.get(manifest_ref)
return plistlib.readPlistFromString(data)
except munkirepo.RepoError as err:
print >> sys.stderr, (u'Could not retrieve manifest %s: %s'
% (manifest_name, unicode(err)))
print(u'Could not retrieve manifest %s: %s'
% (manifest_name, unicode(err)), file=sys.stderr)
return None
except (IOError, OSError, ExpatError) as err:
print >> sys.stderr, (
u'Could not read manifest %s: %s' % (manifest_name, unicode(err)))
print(u'Could not read manifest %s: %s' % (manifest_name, unicode(err)),
file=sys.stderr)
return None
@@ -158,7 +159,7 @@ def save_manifest(repo, manifest_dict, manifest_name, overwrite_existing=False):
existing_manifest_names = get_manifest_names(repo)
if not overwrite_existing:
if manifest_name in existing_manifest_names:
print >> sys.stderr, '%s already exists!' % manifest_name
print('%s already exists!' % manifest_name, file=sys.stderr)
return False
manifest_ref = os.path.join('manifests', manifest_name)
try:
@@ -166,8 +167,8 @@ def save_manifest(repo, manifest_dict, manifest_name, overwrite_existing=False):
repo.put(manifest_ref, data)
return True
except (IOError, OSError, ExpatError, munkirepo.RepoError) as err:
print >> sys.stderr, (
u'Saving %s failed: %s' % (manifest_name, unicode(err)))
print(u'Saving %s failed: %s' % (manifest_name, unicode(err)),
file=sys.stderr)
return False
@@ -181,7 +182,7 @@ def manifest_rename(repo, source_manifest_name, dest_manifest_name,
existing_manifest_names = get_manifest_names(repo)
if not overwrite_existing:
if dest_manifest_name in existing_manifest_names:
print >> sys.stderr, u'%s already exists!' % dest_manifest_name
print(u'%s already exists!' % dest_manifest_name, file=sys.stderr)
return False
try:
source_data = repo.get(source_manifest_ref)
@@ -189,8 +190,9 @@ def manifest_rename(repo, source_manifest_name, dest_manifest_name,
repo.delete(source_manifest_ref)
return True
except munkirepo.RepoError as err:
print >> sys.stderr, u'Renaming %s to %s failed: %s' % (
source_manifest_name, dest_manifest_name, unicode(err))
print(u'Renaming %s to %s failed: %s'
% (source_manifest_name, dest_manifest_name, unicode(err)),
file=sys.stderr)
return False
@@ -246,9 +248,9 @@ def version(repo, args):
# we ignore repo arg but subcommand dispatcher sends it to all
# subcommands
if len(args) != 0:
print >> sys.stderr, 'Usage: version'
print('Usage: version', file=sys.stderr)
return 22 # Invalid argument
print get_version()
print(get_version())
return 0
@@ -256,7 +258,7 @@ def configure(repo, args):
'''Allow user to configure tool options'''
# we ignore the repo arg, but all the other subcommands require it
if len(args):
print >> sys.stderr, 'Usage: configure'
print('Usage: configure', file=sys.stderr)
return 22 # Invalid argument
prompt_list = [
('repo_url', 'Repo URL (example: afp://munki.example.com/repo)'),
@@ -277,7 +279,7 @@ def list_catalogs(repo, args):
try:
_, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -286,7 +288,7 @@ def list_catalogs(repo, args):
parser.print_usage(sys.stderr)
return 22 # Invalid argument
for item in get_catalogs(repo):
print item
print(item)
return 0
@@ -298,7 +300,7 @@ def list_catalog_items(repo, args):
try:
_, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -309,10 +311,10 @@ def list_catalog_items(repo, args):
available_catalogs = get_catalogs(repo)
for catalog in arguments:
if catalog not in available_catalogs:
print >> sys.stderr, '%s: no such catalog!' % catalog
print('%s: no such catalog!' % catalog, file=sys.stderr)
return 2 # No such file or directory
for pkg in get_installer_item_names(repo, arguments):
print pkg
print(pkg)
return 0
@@ -325,7 +327,7 @@ def list_manifests(repo, args):
try:
_, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -339,7 +341,7 @@ def list_manifests(repo, args):
return 7 # Argument list too long
for item in get_manifest_names(repo):
if fnmatch.fnmatch(item, list_filter):
print item
print(item)
return 0
@@ -357,7 +359,7 @@ def find(repo, args):
try:
options, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -378,8 +380,8 @@ def find(repo, args):
data = repo.get(manifest_ref)
manifest = plistlib.readPlistFromString(data)
except (IOError, OSError, ExpatError, munkirepo.RepoError) as err:
print >> sys.stderr, (
u'Error reading %s: %s' % (manifest_ref, unicode(err)))
print(u'Error reading %s: %s' % (manifest_ref, unicode(err)),
file=sys.stderr)
continue
if keyname:
if keyname in manifest:
@@ -388,12 +390,12 @@ def find(repo, args):
for item in value:
try:
if findtext.upper() in item.upper():
print '%s: %s' % (name, item)
print('%s: %s' % (name, item))
count += 1
except AttributeError:
pass
elif findtext.upper() in value.upper():
print '%s: %s' % (name, value)
print('%s: %s' % (name, value))
count += 1
else:
for key in manifest.keys():
@@ -402,15 +404,15 @@ def find(repo, args):
for item in value:
try:
if findtext.upper() in item.upper():
print '%s (%s): %s' % (name, key, item)
print('%s (%s): %s' % (name, key, item))
count += 1
except AttributeError:
pass
elif findtext.upper() in value.upper():
print '%s (%s): %s' % (name, key, value)
print('%s (%s): %s' % (name, key, value))
count += 1
print '%s matches found.' % count
print('%s matches found.' % count)
return 0
@@ -422,7 +424,7 @@ def display_manifest(repo, args):
try:
_, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -461,7 +463,7 @@ def expand_included_manifests(repo, args):
try:
_, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -485,7 +487,7 @@ def new_manifest(repo, args):
try:
_, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -514,7 +516,7 @@ def copy_manifest(repo, args):
try:
_, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -541,7 +543,7 @@ def rename_manifest(repo, args):
try:
_, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -578,7 +580,7 @@ def add_pkg(repo, args):
try:
options, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -600,18 +602,18 @@ def add_pkg(repo, args):
return 2 # No such file or directory
for section in get_manifest_pkg_sections():
if pkgname in manifest.get(section, []):
print >> sys.stderr, (
print((
'Package %s is already in section %s of manifest %s.'
% (pkgname, section, options.manifest))
% (pkgname, section, options.manifest)), file=sys.stderr)
return 1 # Operation not permitted
manifest_catalogs = manifest.get('catalogs', [])
available_pkgnames = get_installer_item_names(repo, manifest_catalogs)
if pkgname not in available_pkgnames:
print >> sys.stderr, (
print((
'WARNING: Package %s is not available in catalogs %s '
'of manifest %s.'
% (pkgname, manifest_catalogs, options.manifest))
% (pkgname, manifest_catalogs, options.manifest)), file=sys.stderr)
if not options.section in manifest:
manifest[options.section] = [pkgname]
else:
@@ -636,7 +638,7 @@ def move_install_to_uninstall(repo, args):
try:
options, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -659,11 +661,13 @@ def move_install_to_uninstall(repo, args):
else:
if pkgname in manifest['managed_installs']:
manifest['managed_installs'].remove(pkgname)
print ('Removed %s from section %s of manifest %s' % (pkgname, 'managed_installs', options.manifest))
print ('Removed %s from section %s of manifest %s'
% (pkgname, 'managed_installs', options.manifest))
else:
print >> sys.stderr, ('WARNING: Package %s is not in section %s '
'of manifest %s. No changes made.'
% (pkgname, 'managed_installs', options.manifest))
print('WARNING: Package %s is not in section %s '
'of manifest %s. No changes made.'
% (pkgname, 'managed_installs', options.manifest),
file=sys.stderr)
return 1 # Operation not permitted
if pkgname in manifest['managed_uninstalls']:
print ('%s is already in section managed_uninstalls of manifest %s.'
@@ -698,7 +702,7 @@ def remove_pkg(repo, args):
try:
options, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -719,13 +723,12 @@ def remove_pkg(repo, args):
if not manifest:
return 2 # No such file or directory
if not options.section in manifest:
print >> sys.stderr, ('Section %s is not in manifest %s.'
% (options.section, options.manifest))
print('Section %s is not in manifest %s.'
% (options.section, options.manifest), file=sys.stderr)
return 1 # Operation not permitted
if pkgname not in manifest[options.section]:
print >> sys.stderr, ('Package %s is not in section %s '
'of manifest %s.'
% (pkgname, options.section, options.manifest))
print('Package %s is not in section %s of manifest %s.'
% (pkgname, options.section, options.manifest), file=sys.stderr)
return 1 # Operation not permitted
else:
manifest[options.section].remove(pkgname)
@@ -749,7 +752,7 @@ def add_catalog(repo, args):
try:
options, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -768,7 +771,7 @@ def add_catalog(repo, args):
available_catalogs = get_catalogs(repo)
if catalogname not in available_catalogs:
print >> sys.stderr, 'Unknown catalog name: %s.' % catalogname
print('Unknown catalog name: %s.' % catalogname, file=sys.stderr)
return 2 # no such file or directory
manifest = get_manifest(repo, options.manifest)
@@ -777,9 +780,9 @@ def add_catalog(repo, args):
if not 'catalogs' in manifest:
manifest['catalogs'] = []
if catalogname in manifest['catalogs']:
print >> sys.stderr, (
print((
'Catalog %s is already in manifest %s.'
% (catalogname, options.manifest))
% (catalogname, options.manifest)), file=sys.stderr)
return 1 # Operation not permitted
else:
# put it at the front of the catalog list as that is usually
@@ -805,7 +808,7 @@ def remove_catalog(repo, args):
try:
options, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -826,9 +829,9 @@ def remove_catalog(repo, args):
if not manifest:
return 2 # no such file or directory
if catalogname not in manifest.get('catalogs', []):
print >> sys.stderr, (
print((
'Catalog %s is not in manifest %s.'
% (catalogname, options.manifest))
% (catalogname, options.manifest)), file=sys.stderr)
return 1 # Operation not permitted
else:
manifest['catalogs'].remove(catalogname)
@@ -853,7 +856,7 @@ def add_included_manifest(repo, args):
try:
options, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -872,12 +875,12 @@ def add_included_manifest(repo, args):
available_manifests = get_manifest_names(repo)
if manifest_to_include not in available_manifests:
print >> sys.stderr, ('Unknown manifest name: %s.'
% manifest_to_include)
print('Unknown manifest name: %s.' % manifest_to_include,
file=sys.stderr)
return 2 # no such file or directory
if manifest_to_include == options.manifest:
print >> sys.stderr, ('Can\'t include %s in itself!.'
% manifest_to_include)
print('Can\'t include %s in itself!.' % manifest_to_include,
file=sys.stderr)
return 1 # Operation not permitted
manifest = get_manifest(repo, options.manifest)
@@ -886,9 +889,8 @@ def add_included_manifest(repo, args):
if not 'included_manifests' in manifest:
manifest['included_manifests'] = []
if manifest_to_include in manifest['included_manifests']:
print >> sys.stderr, (
'Manifest %s is already included in manifest %s.'
% (manifest_to_include, options.manifest))
print('Manifest %s is already included in manifest %s.'
% (manifest_to_include, options.manifest), file=sys.stderr)
return 1 # Operation not permitted
else:
manifest['included_manifests'].append(manifest_to_include)
@@ -913,7 +915,7 @@ def remove_included_manifest(repo, args):
try:
options, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -934,16 +936,15 @@ def remove_included_manifest(repo, args):
if not manifest:
return 2 # no such file or directory
if included_manifest not in manifest.get('included_manifests', []):
print >> sys.stderr, (
'Manifest %s is not included in manifest %s.'
% (included_manifest, options.manifest))
print('Manifest %s is not included in manifest %s.'
% (included_manifest, options.manifest), file=sys.stderr)
return 1 # Operation not permitted
else:
manifest['included_manifests'].remove(included_manifest)
if save_manifest(repo, manifest, options.manifest,
overwrite_existing=True):
print ('Removed %s from included_manifests of manifest %s.'
% (included_manifest, options.manifest))
print('Removed %s from included_manifests of manifest %s.'
% (included_manifest, options.manifest))
return 0
else:
return 1 # Operation not permitted
@@ -958,7 +959,7 @@ def refresh_cache(repo, args):
try:
_, arguments = parser.parse_args(args)
except MyOptParseError as errmsg:
print >> sys.stderr, str(errmsg)
print(str(errmsg), file=sys.stderr)
return 22 # Invalid argument
except MyOptParseExit:
return 0
@@ -975,11 +976,11 @@ def refresh_cache(repo, args):
def show_help():
'''Prints available subcommands'''
print "Available sub-commands:"
print("Available sub-commands:")
subcommands = CMD_ARG_DICT['cmds'].keys()
subcommands.sort()
for item in subcommands:
print '\t%s' % item
print('\t%s' % item)
return 0
@@ -1054,7 +1055,7 @@ def handle_subcommand(repo, args):
except MyOptParseExit:
return 0
except (TypeError, KeyError):
print >> sys.stderr, 'Unknown subcommand: %s' % args[0]
print('Unknown subcommand: %s' % args[0], file=sys.stderr)
show_help()
return 2
else:
@@ -1069,14 +1070,14 @@ def connect_to_repo():
if not repo_url and repo_path:
repo_url = path2url(repo_path)
if not repo_url:
print >> sys.stderr, (
print((
u'No repo URL defined. Run %s --configure to define one.'
% os.path.basename(__file__))
% os.path.basename(__file__)), file=sys.stderr)
exit(-1)
try:
repo = munkirepo.connect(repo_url, repo_plugin)
except munkirepo.RepoError as err:
print >> sys.stderr, u'Repo error: %s' % unicode(err)
print(u'Repo error: %s' % unicode(err), file=sys.stderr)
exit(-1)
return repo
@@ -1133,13 +1134,13 @@ def main():
repo, CMD_ARG_DICT['catalogs'])
set_up_tab_completer()
print 'Entering interactive mode... (type "help" for commands)'
print('Entering interactive mode... (type "help" for commands)')
while 1:
try:
cmd = raw_input('> ')
except (KeyboardInterrupt, EOFError):
# React to Control-C and Control-D
print # so we finish off the raw_input line
print() # so we finish off the raw_input line
cleanup_and_exit(0)
args = shlex.split(cmd)
handle_subcommand(repo, args)

View File

@@ -22,6 +22,8 @@ Created by Greg Neagle on 2010-09-29.
Assists with importing installer items into the munki repo
"""
from __future__ import print_function
# std lib imports
import optparse
import os
@@ -53,7 +55,7 @@ def make_dmg(pkgpath):
Returns path to newly-created disk image."""
pkgname = os.path.basename(pkgpath)
print 'Making disk image containing %s...' % pkgname
print('Making disk image containing %s...' % pkgname)
diskimagename = os.path.splitext(pkgname)[0] + '.dmg'
diskimagepath = os.path.join(osutils.tmpdir(), diskimagename)
cmd = ['/usr/bin/hdiutil', 'create', '-fs', 'HFS+',
@@ -67,14 +69,14 @@ def make_dmg(pkgpath):
break
line = output.rstrip('\n').decode('UTF-8')
if len(line) > 0:
print line
print(line)
sys.stdout.flush()
retcode = proc.poll()
if retcode:
print >> sys.stderr, 'Disk image creation failed.'
print('Disk image creation failed.', file=sys.stderr)
return ''
else:
print 'Disk image created at: %s' % diskimagepath
print('Disk image created at: %s' % diskimagepath)
return diskimagepath
@@ -90,9 +92,8 @@ def edit_pkginfo_in_editor(pkginfo):
try:
FoundationPlist.writePlist(pkginfo, filepath)
except FoundationPlist.FoundationPlistException as err:
print >> sys.stderr, (
u'Could not save pkginfo to temp file: %s'
% unicode(err))
print(u'Could not save pkginfo to temp file: %s'
% unicode(err), file=sys.stderr)
return pkginfo
if editor.endswith('.app'):
@@ -102,8 +103,8 @@ def edit_pkginfo_in_editor(pkginfo):
try:
dummy_returncode = subprocess.check_call(cmd)
except (OSError, subprocess.CalledProcessError) as err:
print >> sys.stderr, (
'Problem running editor %s: %s.' % (editor, err))
print('Problem running editor %s: %s.' % (editor, err),
file=sys.stderr)
os.remove(filepath)
return pkginfo
else:
@@ -115,8 +116,8 @@ def edit_pkginfo_in_editor(pkginfo):
try:
edited_pkginfo = FoundationPlist.readPlist(filepath)
except FoundationPlist.FoundationPlistException as err:
print >> sys.stderr, (
u'Problem reading edited pkginfo: %s' % unicode(err))
print(u'Problem reading edited pkginfo: %s' % unicode(err),
file=sys.stderr)
os.remove(filepath)
return pkginfo
os.remove(filepath)
@@ -155,22 +156,22 @@ def prompt_for_subdirectory(repo, subdirectory):
def print_fn(text):
'''Wraps print in a function for make_catalogs'''
print text
print(text)
def make_catalogs(repo, options):
"""Rebuild our catalogs"""
if not options.verbose:
print 'Rebuilding catalogs at %s...' % options.repo_url
print('Rebuilding catalogs at %s...' % options.repo_url)
output_fn = None
else:
output_fn = print_fn
errors = makecatalogslib.makecatalogs(repo, {}, output_fn=output_fn)
if errors:
print '\nThe following issues occurred while building catalogs:\n'
print('\nThe following issues occurred while building catalogs:\n')
for error in errors:
print error
print(error)
def cleanup_and_exit(exitcode):
@@ -260,7 +261,7 @@ def main():
sys.argv = [unicode(item, 'utf-8') for item in sys.argv]
options, arguments = parser.parse_args()
# there are a lot of valid combinations of option flags and arguments
# but if there are no option flags or arguments we should print usage
if len(sys.argv) == 1:
@@ -268,7 +269,7 @@ def main():
exit(0)
if options.version:
print info.get_version()
print(info.get_version())
exit(0)
if options.configure:
@@ -281,9 +282,8 @@ def main():
options.repo_url = path2url(repo_path)
if not options.repo_url:
print >> sys.stderr, ('No repo URL found. Please run this tool with '
'the --configure option, or use the --repo-url '
'option.')
print('No repo URL found. Please run this tool with the --configure '
'option, or use the --repo-url option.', file=sys.stderr)
parser.print_help()
exit(-1)
@@ -291,7 +291,7 @@ def main():
options.plugin = 'FileRepo'
if options.icon_path and not os.path.isfile(options.icon_path):
print >> sys.stderr, ('The specified icon file does not exist.')
print('The specified icon file does not exist.', file=sys.stderr)
exit(-1)
if (options.apple_update and len(arguments) > 0) or len(arguments) > 1:
@@ -319,26 +319,27 @@ def main():
if (not pkgutils.hasValidInstallerItemExt(installer_item) and
not pkgutils.isApplication(installer_item)):
print >> sys.stderr, (
'Unknown installer item type: "%s"' % installer_item)
print('Unknown installer item type: "%s"' % installer_item,
file=sys.stderr)
exit(-1)
if not os.path.exists(installer_item):
print >> sys.stderr, '%s does not exist!' % installer_item
print('%s does not exist!' % installer_item, file=sys.stderr)
exit(-1)
try:
repo = munkirepo.connect(options.repo_url, options.plugin)
except munkirepo.RepoError as err:
print >> sys.stderr, (u'Could not connect to munki repo: %s'
% unicode(err))
print(u'Could not connect to munki repo: %s' % unicode(err),
file=sys.stderr)
exit(-1)
if not is_applemetadata:
if os.path.isdir(installer_item):
if pkgutils.hasValidDiskImageExt(installer_item):
# a directory named foo.dmg or foo.iso!
print >> sys.stderr, '%s is an unknown type.' % installer_item
print('%s is an unknown type.' % installer_item,
file=sys.stderr)
cleanup_and_exit(-1)
else:
# we need to convert to dmg
@@ -346,9 +347,8 @@ def main():
if dmg_path:
installer_item = dmg_path
else:
print >> sys.stderr, (
'Could not convert %s to a disk image.'
% installer_item)
print('Could not convert %s to a disk image.'
% installer_item, file=sys.stderr)
cleanup_and_exit(-1)
if uninstaller_item:
@@ -358,8 +358,8 @@ def main():
if os.path.isdir(uninstaller_item):
if pkgutils.hasValidDiskImageExt(uninstaller_item):
# a directory named foo.dmg or foo.iso!
print >> sys.stderr, (
'%s is an unknown type.' % uninstaller_item)
print('%s is an unknown type.' % uninstaller_item,
file=sys.stderr)
cleanup_and_exit(-1)
else:
# we need to convert to dmg
@@ -367,9 +367,8 @@ def main():
if dmg_path:
uninstaller_item = dmg_path
else:
print >> sys.stderr, (
'Could not convert %s to a disk image.'
% uninstaller_item)
print('Could not convert %s to a disk image.'
% uninstaller_item, file=sys.stderr)
cleanup_and_exit(-1)
options.uninstalleritem = uninstaller_item
@@ -384,8 +383,8 @@ def main():
pkginfo = pkginfolib.makepkginfo(installer_item, options)
except pkginfolib.PkgInfoGenerationError as err:
# makepkginfo returned an error
print >> sys.stderr, 'Getting package info failed.'
print >> sys.stderr, err
print('Getting package info failed.', file=sys.stderr)
print(err, file=sys.stderr)
cleanup_and_exit(-1)
if not options.nointeractive:
@@ -400,16 +399,16 @@ def main():
print ('***This item is identical to an existing item in '
'the repo***:')
else:
print 'This item is similar to an existing item in the repo:'
print('This item is similar to an existing item in the repo:')
fields = (('Item name', 'name'),
('Display name', 'display_name'),
('Description', 'description'),
('Version', 'version'),
('Installer item path', 'installer_item_location'))
for (name, key) in fields:
print '%21s: %s' % (
name, matchingpkginfo.get(key, '').encode('UTF-8'))
print
print('%21s: %s' % (
name, matchingpkginfo.get(key, '').encode('UTF-8')))
print()
if exactmatch:
answer = raw_input('Import this item anyway? [y/n] ')
if not answer.lower().startswith('y'):
@@ -442,7 +441,7 @@ def main():
'localized_strings',
'featured']:
if key in matchingpkginfo:
print 'Copying %s: %s' % (key, matchingpkginfo[key])
print('Copying %s: %s' % (key, matchingpkginfo[key]))
pkginfo[key] = matchingpkginfo[key]
# now let user do some basic editing
@@ -477,12 +476,12 @@ def main():
not pkginfo.get(
'installer_type') in ['profile', 'startosinstall']):
if 'receipts' not in pkginfo and 'installs' not in pkginfo:
print >> sys.stderr, ('WARNING: There are no receipts and no '
'\'installs\' items for this installer '
'item. You will need to add at least '
'one item to the \'installs\' list.')
print('WARNING: There are no receipts and no \'installs\' '
'items for this installer item. You will need to add at '
'least one item to the \'installs\' list.',
file=sys.stderr)
print
print()
#for (name, key, kind) in editfields:
# if kind == 'bool':
# print '%20s: %s' % (name, pkginfo.get(key, False))
@@ -522,17 +521,17 @@ def main():
munkiimportlib.convert_and_install_icon(repo, pkginfo,
options.icon_path)
except munkiimportlib.RepoCopyError as err:
print >> sys.stderr, err
print(err, file=sys.stderr)
elif options.extract_icon:
pass
elif (not options.nointeractive and
not munkiimportlib.icon_exists_in_repo(repo, pkginfo) and
not is_applemetadata and
not pkginfo.get('installer_type') == 'profile'):
print 'No existing product icon found.'
print('No existing product icon found.')
answer = raw_input('Attempt to create a product icon? [y/n] ')
if answer.lower().startswith('y'):
print 'Attempting to extract and upload icon...'
print('Attempting to extract and upload icon...')
options.extract_icon = True
if options.extract_icon:
@@ -540,11 +539,11 @@ def main():
imported_paths = munkiimportlib.extract_and_copy_icon(
repo, installer_item, pkginfo)
if imported_paths:
print 'Imported %s.' % imported_paths
print('Imported %s.' % imported_paths)
else:
print 'No icons found for import.'
print('No icons found for import.')
except munkiimportlib.RepoCopyError as err:
print >> sys.stderr, err
print(err, file=sys.stderr)
# fix in case user accidentally starts subdirectory with a slash
if options.subdirectory.startswith('/'):
@@ -552,14 +551,14 @@ def main():
if not is_applemetadata:
try:
print 'Copying %s to repo...' % os.path.basename(installer_item)
print('Copying %s to repo...' % os.path.basename(installer_item))
uploaded_pkgpath = munkiimportlib.copy_item_to_repo(
repo, installer_item, pkginfo.get('version'),
options.subdirectory)
print 'Copied %s to %s.' % (os.path.basename(installer_item),
uploaded_pkgpath)
print('Copied %s to %s.'
% (os.path.basename(installer_item), uploaded_pkgpath))
except munkiimportlib.RepoCopyError as errmsg:
print >> sys.stderr, errmsg
print(errmsg, file=sys.stderr)
cleanup_and_exit(-1)
# adjust the installer_item_location to match
@@ -568,15 +567,15 @@ def main():
if uninstaller_item:
try:
print 'Copying %s to repo...' % os.path.basename(
uninstaller_item)
print('Copying %s to repo...' % os.path.basename(
uninstaller_item))
uploaded_pkgpath = munkiimportlib.copy_item_to_repo(
repo, uninstaller_item, pkginfo.get('version'),
options.subdirectory)
print 'Copied %s to %s.' % (
os.path.basename(uninstaller_item), uploaded_pkgpath)
print('Copied %s to %s.' % (
os.path.basename(uninstaller_item), uploaded_pkgpath))
except munkiimportlib.RepoCopyError as errmsg:
print >> sys.stderr, errmsg
print(errmsg, file=sys.stderr)
cleanup_and_exit(-1)
# adjust the uninstaller_item_location to match
@@ -596,10 +595,11 @@ def main():
# possibly edit the pkginfo file in the user's editor
pkginfo = edit_pkginfo_in_editor(pkginfo)
try:
pkginfo_path = munkiimportlib.copy_pkginfo_to_repo(repo, pkginfo, options.subdirectory)
print 'Saved pkginfo to %s.' % pkginfo_path
pkginfo_path = munkiimportlib.copy_pkginfo_to_repo(
repo, pkginfo, options.subdirectory)
print('Saved pkginfo to %s.' % pkginfo_path)
except munkiimportlib.RepoCopyError as errmsg:
print >> sys.stderr, errmsg
print(errmsg, file=sys.stderr)
cleanup_and_exit(-1)
if not options.nointeractive:

View File

@@ -39,6 +39,7 @@ dictionary).
To work with plist data in strings, you can use readPlistFromString()
and writePlistToString().
"""
from __future__ import print_function
# PyLint cannot properly find names inside Cocoa libraries, so issues bogus
# No name 'Foo' in module 'Bar' warnings. Disable them.
@@ -145,4 +146,4 @@ def writePlistToString(rootObject):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -19,6 +19,7 @@ makecatalogslib
Created by Greg Neagle on 2017-11-19.
Routines used by makecatalogs
"""
from __future__ import print_function
# std libs
import hashlib
@@ -291,7 +292,7 @@ def makecatalogs(repo, options, output_fn=None):
icon_hashes = plistlib.writePlistToString(icons)
try:
repo.put(icon_hashes_plist, icon_hashes)
print "Created %s..." % (icon_hashes_plist)
print("Created %s..." % (icon_hashes_plist))
except munkirepo.RepoError as err:
errors.append(
u'Failed to create %s: %s' % (icon_hashes_plist, unicode(err)))

View File

@@ -19,6 +19,7 @@ munkiimportlib
Created by Greg Neagle on 2017-11-18.
Routines used by munkimport to import items into Munki repo
"""
from __future__ import print_function
# std lib imports
import os
@@ -157,7 +158,7 @@ def make_catalog_db(repo):
vers = item.get('version', 'NO VERSION')
if name == 'NO NAME' or vers == 'NO VERSION':
print >> sys.stderr, 'WARNING: Bad pkginfo: %s' % item
print('WARNING: Bad pkginfo: %s' % item, file=sys.stderr)
# add to hash table
if 'installer_item_hash' in item:
@@ -191,8 +192,8 @@ def make_catalog_db(repo):
pkgid_table[pkgid][pkgvers] = []
pkgid_table[pkgid][pkgvers].append(itemindex)
except TypeError:
print >> sys.stderr, (
'Bad receipt data for %s-%s: %s' % (name, vers, receipt))
print('Bad receipt data for %s-%s: %s' % (name, vers, receipt),
file=sys.stderr)
# add to table of installed applications
for install in item.get('installs', []):
@@ -205,8 +206,8 @@ def make_catalog_db(repo):
app_table[install['path']][vers] = []
app_table[install['path']][vers].append(itemindex)
except TypeError:
print >> sys.stderr, (
'Bad install data for %s-%s: %s' % (name, vers, install))
print('Bad install data for %s-%s: %s' % (name, vers, install),
file=sys.stderr)
# add to table of PayloadIdentifiers
if 'PayloadIdentifier' in item:
@@ -245,8 +246,8 @@ def find_matching_pkginfo(repo, pkginfo):
if len(pkgsinfo_items):
# there _are_ existing pkgsinfo items.
# warn about the problem since we can't seem to read catalogs/all
print (u'Could not get a list of existing items from the repo: %s'
% unicode(err))
print(u'Could not get a list of existing items from the repo: %s'
% unicode(err))
return {}
except CatalogDBException as err:
# other error while processing catalogs/all
@@ -478,7 +479,7 @@ def copy_icon_to_repo(repo, iconpath):
except munkirepo.RepoError as err:
raise RepoCopyError('Could not remove existing %s: %s'
% (destination_path_name, unicode(err)))
print 'Copying %s to %s...' % (icon_name, destination_path_name)
print('Copying %s to %s...' % (icon_name, destination_path_name))
try:
repo.put_from_local_file(destination_path_name, iconpath)
return destination_path_name

View File

@@ -19,6 +19,7 @@ pkginfolib
Created by Greg Neagle on 2017-11-18.
Routines used by makepkginfo to create pkginfo files
"""
from __future__ import print_function
# standard libs
import optparse
@@ -193,10 +194,9 @@ def get_catalog_info_from_dmg(dmgpath, options):
install_macos_app = osinstaller.find_install_macos_app(mountpoints[0])
if (install_macos_app and options.print_warnings and
osinstaller.install_macos_app_is_stub(install_macos_app)):
print >> sys.stderr, (
'WARNING: %s appears to be an Install macOS application, but '
'it does not contain Contents/SharedSupport/InstallESD.dmg'
% os.path.basename(install_macos_app))
print('WARNING: %s appears to be an Install macOS application, but '
'it does not contain Contents/SharedSupport/InstallESD.dmg'
% os.path.basename(install_macos_app), file=sys.stderr)
cataloginfo = osinstaller.get_catalog_info(mountpoints[0])
if not cataloginfo:
@@ -297,7 +297,7 @@ def readfile(path):
fileobject.close()
return data
except (OSError, IOError):
print >> sys.stderr, "Couldn't read %s" % path
print("Couldn't read %s" % path, file=sys.stderr)
return ""
@@ -409,12 +409,11 @@ def makepkginfo(installeritem, options):
if pkgutils.hasValidDiskImageExt(installeritem):
if dmgutils.DMGisWritable(installeritem) and options.print_warnings:
print >> sys.stderr, (
"WARNING: %s is a writable disk image. "
"Checksum verification is not supported." % installeritem)
print >> sys.stderr, (
"WARNING: Consider converting %s to a read-only disk"
"image." % installeritem)
print("WARNING: %s is a writable disk image. "
"Checksum verification is not supported." % installeritem,
file=sys.stderr)
print("WARNING: Consider converting %s to a read-only disk"
"image." % installeritem, file=sys.stderr)
itemhash = "N/A"
pkginfo = get_catalog_info_from_dmg(installeritem, options)
if (pkginfo and
@@ -437,10 +436,9 @@ def makepkginfo(installeritem, options):
"%s doesn't appear to be a valid installer item!"
% installeritem)
if os.path.isdir(installeritem) and options.print_warnings:
print >> sys.stderr, (
"WARNING: %s is a bundle-style package!\n"
"To use it with Munki, you should encapsulate it "
"in a disk image.\n") % installeritem
print("WARNING: %s is a bundle-style package!\n"
"To use it with Munki, you should encapsulate it "
"in a disk image.\n" % installeritem, file=sys.stderr)
# need to walk the dir and add it all up
for (path, dummy_dirs, files) in os.walk(installeritem):
for name in files:
@@ -454,7 +452,7 @@ def makepkginfo(installeritem, options):
try:
pkginfo = get_catalog_info_for_profile(installeritem)
except ProfileMetadataGenerationError as err:
print >> sys.stderr, err
print(err, file=sys.stderr)
raise PkgInfoGenerationError(
"%s doesn't appear to be a supported configuration "
"profile!" % installeritem)
@@ -484,11 +482,10 @@ def makepkginfo(installeritem, options):
# ADOBE STUFF - though maybe generalizable in the future?
if (pkginfo.get('installer_type') == "AdobeCCPInstaller" and
not options.uninstalleritem) and options.print_warnings:
print >> sys.stderr, (
"WARNING: This item appears to be an Adobe Creative "
"Cloud product install.\n"
"No uninstaller package was specified so product "
"removal will not be possible.")
print("WARNING: This item appears to be an Adobe Creative "
"Cloud product install.\n"
"No uninstaller package was specified so product "
"removal will not be possible.", file=sys.stderr)
pkginfo['uninstallable'] = False
if 'uninstall_method' in pkginfo:
del pkginfo['uninstall_method']
@@ -562,8 +559,8 @@ def makepkginfo(installeritem, options):
if fitem.startswith('/Library/Receipts'):
# no receipts, please!
if options.print_warnings:
print >> sys.stderr, (
"Item %s appears to be a receipt. Skipping." % fitem)
print("Item %s appears to be a receipt. Skipping." % fitem,
file=sys.stderr)
continue
if os.path.exists(fitem):
iteminfodict = getiteminfo(fitem)
@@ -575,8 +572,8 @@ def makepkginfo(installeritem, options):
maxfileversion = thisitemversion
installs.append(iteminfodict)
elif options.print_warnings:
print >> sys.stderr, (
"Item %s doesn't exist. Skipping." % fitem)
print("Item %s doesn't exist. Skipping." % fitem,
file=sys.stderr)
if installs:
pkginfo['installs'] = installs

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2017-01-06.
Utilities to get info about Adobe installers/uninstallers
"""
from __future__ import print_function
import os
import json
@@ -784,4 +785,4 @@ def getAdobeCatalogInfo(mountpoint, pkgname=""):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -19,6 +19,7 @@ Utilities to enable Munki to install/uninstall Adobe CS3/CS4/CS5 products
using the CS3/CS4/CS5 Deployment Toolkits.
"""
from __future__ import print_function
import os
@@ -386,7 +387,7 @@ def writefile(stringdata, path):
Returns the path on success, empty string on failure.'''
try:
fileobject = open(path, mode='w', buffering=1)
print >> fileobject, stringdata.encode('UTF-8')
print(stringdata.encode('UTF-8'), file=fileobject)
fileobject.close()
return path
except (OSError, IOError):
@@ -924,4 +925,4 @@ def do_adobe_install(item):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -23,6 +23,7 @@ Much code lifted from the application_usage scripts created by Google MacOps:
https://github.com/google/macops/tree/master/crankd
"""
from __future__ import print_function
# standard Python libs
import logging
@@ -508,4 +509,4 @@ class ApplicationUsageQuery(object):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2017-01-06.
AppleUpdates object defined here
"""
from __future__ import print_function
import glob
import hashlib
@@ -823,4 +824,4 @@ class AppleUpdates(object):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -18,6 +18,7 @@ appleupdates.py
Utilities for dealing with Apple Software Update.
"""
from __future__ import print_function
from . import au
from . import su_prefs
@@ -79,4 +80,4 @@ def displayAppleUpdateInfo():
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2017-01-04.
Utilities for working with Apple software update dist files
"""
from __future__ import print_function
import os
from xml.dom import minidom
@@ -259,4 +260,4 @@ def parse_su_dist(filename):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2017-01-06.
Utilities for working with Apple software update preferences
"""
from __future__ import print_function
import subprocess
@@ -180,4 +181,4 @@ def reset_original_catalogurl():
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2017-01-06.
Utilities for replicating and retrieving Apple software update metadata
"""
from __future__ import print_function
import gzip
import os
@@ -531,4 +532,4 @@ class AppleUpdateSync(object):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -21,6 +21,7 @@ Initial work by Wes Whetstone, Summer/Fall 2016
Functions supporting FileVault authrestart.
"""
from __future__ import print_function
import subprocess
@@ -214,4 +215,4 @@ def do_authorized_or_normal_restart(username=None,
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -21,12 +21,12 @@ Created by Greg Neagle on 2017-04-15.
Routines for communicating with authrestartd.
Socket communications code adapted from autopkg's PkgCreator by Per Olofsson
"""
from __future__ import print_function
import os
import plistlib
import select
import socket
import sys
AUTHRESTARTD_SOCKET = "/var/run/authrestartd"
@@ -63,8 +63,7 @@ class AuthRestartClient(object):
if reply:
return reply.rstrip()
else:
return "ERROR:No reply"
return "ERROR:No reply"
def disconnect(self):
'''Disconnect from authrestartd'''
@@ -175,26 +174,27 @@ def restart():
def test():
'''A function for doing some basic testing'''
import getpass
import pwd
print 'FileVault is active: %s' % fv_is_active()
print 'Recovery key is present: %s' % verify_recovery_key_present()
print('FileVault is active: %s' % fv_is_active())
print('Recovery key is present: %s' % verify_recovery_key_present())
username = pwd.getpwuid(os.getuid()).pw_name
print '%s is FV user: %s' % (username, verify_user(username))
print('%s is FV user: %s' % (username, verify_user(username)))
password = getpass.getpass('Enter password: ')
if password:
if username == 'root':
username = None
if store_password(password, username=username):
print 'store_password was successful'
print('store_password was successful')
else:
print 'store_password failed'
print 'Can attempt auth restart: %s' % verify_can_attempt_auth_restart()
print('store_password failed')
print('Can attempt auth restart: %s' % verify_can_attempt_auth_restart())
answer = raw_input('Test auth restart (y/n)? ')
if answer.lower().startswith('y'):
print 'Attempting auth restart...'
print('Attempting auth restart...')
if restart():
print 'restart was successfully triggered'
print('restart was successfully triggered')
else:
print 'restart failed'
print('restart failed')

View File

@@ -44,7 +44,7 @@ class SetupError(Exception):
def disable_fde_autologin():
'''Disables autologin to the unlocking user's account on a FileVault-
encrypted machines.'''
# See https://support.apple.com/en-us/HT202842
# We attempt to store the original value of com.apple.loginwindow
# DisableFDEAutoLogin so if the local admin has set it to True for #reasons
@@ -107,7 +107,7 @@ def set_bootstrap_mode():
except (OSError, IOError) as err:
reset_fde_autologin()
raise SetupError(
'Could not create bootstrapping flag file: %s', err)
'Could not create bootstrapping flag file: %s' % err)
def clear_bootstrap_mode():
@@ -118,4 +118,4 @@ def clear_bootstrap_mode():
os.unlink(constants.CHECKANDINSTALLATSTARTUPFLAG)
except OSError as err:
raise SetupError(
'Could not remove bootstrapping flag file: %s', err)
'Could not remove bootstrapping flag file: %s' % err)

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2017-03-12.
Functions supporting the admin command-line tools
"""
from __future__ import print_function
import ctypes
from ctypes.util import find_library
@@ -115,12 +116,12 @@ def path2url(path):
def print_utf8(text):
'''Print Unicode text as UTF-8'''
print text.encode('UTF-8')
print(text.encode('UTF-8'))
def print_err_utf8(text):
'''Print Unicode text to stderr as UTF-8'''
print >> sys.stderr, text.encode('UTF-8')
print(text.encode('UTF-8'), file=sys.stderr)
class TempFile(object):
@@ -212,7 +213,7 @@ def configure(prompt_list):
try:
CFPreferencesSetAppValue(key, value, BUNDLE_ID)
except BaseException:
print >> sys.stderr, 'Could not save configuration!'
print('Could not save configuration!', file=sys.stderr)
raise ConfigurationSaveError
# remove repo_path if it exists since we don't use that
# any longer (except for backwards compatibility) and we don't
@@ -231,10 +232,10 @@ def configure(prompt_list):
del existing_prefs['repo_path']
plistlib.writePlist(existing_prefs, PREFSPATH)
except (IOError, OSError, ExpatError):
print >> sys.stderr, (
'Could not save configuration to %s' % PREFSPATH)
print('Could not save configuration to %s' % PREFSPATH,
file=sys.stderr)
raise ConfigurationSaveError
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2016-12-14.
Commonly used constants
"""
from __future__ import print_function
# NOTE: it's very important that defined exit codes are never changed!
# Preflight exit codes.
@@ -59,4 +60,4 @@ POSTACTION_SHUTDOWN = 4
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2016-12-13.
Common output functions
"""
from __future__ import print_function
import sys
import warnings
@@ -124,9 +125,9 @@ def display_status_major(msg, *args):
munkistatus.percent(-1)
if verbose:
if msg.endswith('.') or msg.endswith(u''):
print '%s' % msg.encode('UTF-8')
print('%s' % msg.encode('UTF-8'))
else:
print '%s...' % msg.encode('UTF-8')
print('%s...' % msg.encode('UTF-8'))
sys.stdout.flush()
@@ -141,9 +142,9 @@ def display_status_minor(msg, *args):
munkistatus.detail(msg)
if verbose:
if msg.endswith('.') or msg.endswith(u''):
print ' %s' % msg.encode('UTF-8')
print(' %s' % msg.encode('UTF-8'))
else:
print ' %s...' % msg.encode('UTF-8')
print(' %s...' % msg.encode('UTF-8'))
sys.stdout.flush()
@@ -155,7 +156,7 @@ def display_info(msg, *args):
msg = _concat_message(msg, *args)
munkilog.log(u' ' + msg)
if verbose > 0:
print ' %s' % msg.encode('UTF-8')
print(' %s' % msg.encode('UTF-8'))
sys.stdout.flush()
@@ -168,7 +169,7 @@ def display_detail(msg, *args):
"""
msg = _concat_message(msg, *args)
if verbose > 1:
print ' %s' % msg.encode('UTF-8')
print(' %s' % msg.encode('UTF-8'))
sys.stdout.flush()
if prefs.pref('LoggingLevel') > 0:
munkilog.log(u' ' + msg)
@@ -180,7 +181,7 @@ def display_debug1(msg, *args):
"""
msg = _concat_message(msg, *args)
if verbose > 2:
print ' %s' % msg.encode('UTF-8')
print(' %s' % msg.encode('UTF-8'))
sys.stdout.flush()
if prefs.pref('LoggingLevel') > 1:
munkilog.log('DEBUG1: %s' % msg)
@@ -192,7 +193,7 @@ def display_debug2(msg, *args):
"""
msg = _concat_message(msg, *args)
if verbose > 3:
print ' %s' % msg.encode('UTF-8')
print(' %s' % msg.encode('UTF-8'))
if prefs.pref('LoggingLevel') > 2:
munkilog.log('DEBUG2: %s' % msg)
@@ -204,7 +205,7 @@ def display_warning(msg, *args):
msg = _concat_message(msg, *args)
warning = 'WARNING: %s' % msg
if verbose > 0:
print >> sys.stderr, warning.encode('UTF-8')
print(warning.encode('UTF-8'), file=sys.stderr)
munkilog.log(warning)
# append this warning to our warnings log
munkilog.log(warning, 'warnings.log')
@@ -221,7 +222,7 @@ def display_error(msg, *args):
msg = _concat_message(msg, *args)
errmsg = 'ERROR: %s' % msg
if verbose > 0:
print >> sys.stderr, errmsg.encode('UTF-8')
print(errmsg.encode('UTF-8'), file=sys.stderr)
munkilog.log(errmsg)
# append this error to our errors log
munkilog.log(errmsg, 'errors.log')
@@ -239,4 +240,4 @@ munkistatusoutput = True
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2016-12-13.
Utilities for working with disk images.
"""
from __future__ import print_function
import os
import subprocess
@@ -246,4 +247,4 @@ def unmountdmg(mountpoint):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -19,6 +19,7 @@ fetch.py
Created by Greg Neagle on 2011-09-29.
"""
from __future__ import print_function
# standard libs
import calendar
@@ -681,4 +682,4 @@ def check_server(url):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -21,6 +21,7 @@ Modified in Feb 2016 to add support for NSURLSession.
curl replacement using NSURLConnection and friends
"""
from __future__ import print_function
import os
from urlparse import urlparse
@@ -697,4 +698,4 @@ class Gurl(NSObject):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -21,6 +21,7 @@ Created by Greg Neagle on 2014-05-15.
Functions to work with product images ('icons') for Managed Software Center
"""
from __future__ import print_function
import glob
import os
@@ -267,4 +268,4 @@ def getAppInfoPathsFromBOM(bomfile):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2016-12-14.
Utilities that retrieve information from the current machine.
"""
from __future__ import print_function
# standard libs
import ctypes
import ctypes.util
@@ -690,7 +691,7 @@ def get_conditions():
except utils.ScriptNotFoundError:
pass # script is not required, so pass
except utils.RunExternalScriptError as err:
print >> sys.stderr, unicode(err)
print(unicode(err), file=sys.stderr)
else:
# /usr/local/munki/conditions does not exist
pass
@@ -821,4 +822,4 @@ def predicate_evaluates_as_true(predicate_string, additional_info=None):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -19,6 +19,7 @@ installer.core
munki module to automatically install pkgs, mpkgs, and dmgs
(containing pkgs and mpkgs) from a defined folder.
"""
from __future__ import print_function
import datetime
import os
@@ -758,4 +759,4 @@ def run(only_unattended=False):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2017-01-03.
Routines for copying items from disk images
"""
from __future__ import print_function
import os
import shutil
@@ -289,4 +290,4 @@ def copy_from_dmg(dmgpath, itemlist):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2017-01-03.
Routines for installing Apple pkgs
"""
from __future__ import print_function
import os
import pwd
@@ -310,4 +311,4 @@ def installall(dirpath, options=None):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -23,6 +23,7 @@ is made to revert to older versions of a file when uninstalling;
only file removals are done.
"""
from __future__ import print_function
import os
import subprocess
@@ -817,7 +818,7 @@ def removepackages(pkgnames, forcedeletebundles=False, listfiles=False,
if listfiles:
removalpaths.sort()
for item in removalpaths:
print "/" + item.encode('UTF-8')
print("/" + item.encode('UTF-8'))
else:
munkistatus.disableStopButton()
remove_filesystem_items(removalpaths, forcedeletebundles)
@@ -838,4 +839,4 @@ PACKAGEDB = os.path.join(prefs.pref('ManagedInstallDir'), "b.receiptdb")
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2017-01-01.
Functions for getting data from the InstallInfo.plist, etc
"""
from __future__ import print_function
# standard libs
import os
@@ -288,4 +289,4 @@ def force_install_package_check():
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -22,6 +22,7 @@ Incorporating work and ideas from Michael Lynn here:
and here:
https://gist.github.com/pudquick/836a19b5ff17c5b7640d#file-cert_tricks-py
"""
from __future__ import print_function
import base64
import hashlib
@@ -584,4 +585,4 @@ class MunkiKeychain(object):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -25,6 +25,7 @@ Returns a file descriptor for a socket defined in a launchd plist.
A wrapper for using launchd to run a process as root outside of Munki's
process space. Needed to properly run /usr/sbin/softwareupdate, for example.
"""
from __future__ import print_function
import os
import subprocess
@@ -231,4 +232,4 @@ class Job(object):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2008-11-18.
Common functions used by the munki tools.
"""
from __future__ import print_function
# this module currently exists purely for backwards compatibility so that
# anything calling munkicommon functions will still work (for now)
@@ -42,4 +43,4 @@ from .scriptutils import *
# pylint: enable=wildcard-import
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -21,6 +21,7 @@ Created by Greg Neagle on 2016-12-14.
Munki's hash functions
"""
from __future__ import print_function
import hashlib
import os
@@ -67,4 +68,4 @@ def getsha256hash(filename):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -21,6 +21,7 @@ Created by Greg Neagle on 2016-12-14.
Logging functions for Munki
"""
from __future__ import print_function
import logging
import logging.handlers
@@ -52,7 +53,7 @@ def log(msg, logname=''):
try:
fileobj = open(logpath, mode='a', buffering=1)
try:
print >> fileobj, time.strftime(formatstr), msg.encode('UTF-8')
print(time.strftime(formatstr), msg.encode('UTF-8'), file=fileobj)
except (OSError, IOError):
pass
fileobj.close()
@@ -130,4 +131,4 @@ def reset_errors():
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -1,5 +1,6 @@
# encoding: utf-8
'''Defines FileRepo plugin. See docstring for FileRepo class'''
from __future__ import print_function
import errno
import getpass
@@ -166,7 +167,7 @@ class FileRepo(Repo):
'''If self.root is present, return. Otherwise, if the url scheme is not
"file:" then try to mount the share url.'''
if not os.path.exists(self.root) and self.url_scheme != 'file':
print u'Attempting to mount fileshare %s:' % self.baseurl
print(u'Attempting to mount fileshare %s:' % self.baseurl)
if NETFSMOUNTURLSYNC_AVAILABLE:
try:
self.root = mount_share_url(self.baseurl)
@@ -187,7 +188,7 @@ class FileRepo(Repo):
elif self.baseurl.startswith('nfs://'):
cmd = ['/sbin/mount_nfs', self.baseurl[6:], self.root]
else:
print >> sys.stderr, 'Unsupported filesystem URL!'
print('Unsupported filesystem URL!', file=sys.stderr)
return
retcode = subprocess.call(cmd)
if retcode:

View File

@@ -1,5 +1,6 @@
# encoding: utf-8
'''Subclasses FileRepo to do git commits of file changes'''
from __future__ import print_function
import inspect
import os
@@ -88,11 +89,11 @@ class MunkiGit(object):
# generate the log message
log_msg = (
'%s %s \'%s\' via %s' % (username, action, itempath, toolname))
print "Doing git commit: %s" % log_msg
print("Doing git commit: %s" % log_msg)
self.run_git(['commit', '-m', log_msg])
if self.results['returncode'] != 0:
print >> sys.stderr, "Failed to commit changes to %s" % a_path
print >> sys.stderr, self.results['error']
print("Failed to commit changes to %s" % a_path, file=sys.stderr)
print(self.results['error'], file=sys.stderr)
return -1
return 0
@@ -106,9 +107,10 @@ class MunkiGit(object):
if self.results['returncode'] == 0:
self.commit_file_at_path(a_path)
else:
print >> sys.stderr, "Git error: %s" % self.results['error']
print("Git error: %s" % self.results['error'],
file=sys.stderr)
else:
print >> sys.stderr, "%s is not in a git repo." % a_path
print("%s is not in a git repo." % a_path, file=sys.stderr)
def add_file_at_path(self, a_path):
"""Commits a file to the Git repo."""

View File

@@ -1,5 +1,6 @@
# encoding: utf-8
'''Defines MWA2APIRepo plugin. See docstring for MWA2APIRepo class'''
from __future__ import print_function
import base64
import getpass
@@ -38,7 +39,7 @@ class MWA2APIRepo(Repo):
if 'MUNKIREPO_AUTHTOKEN' in os.environ:
self.authtoken = os.environ['MUNKIREPO_AUTHTOKEN']
else:
print 'Please provide credentials for %s:' % self.baseurl
print('Please provide credentials for %s:' % self.baseurl)
username = raw_input('Username: ')
password = getpass.getpass()
user_and_pass = '%s:%s' % (username, password)
@@ -52,23 +53,23 @@ class MWA2APIRepo(Repo):
contentpath = None
fileref, directivepath = tempfile.mkstemp()
fileobj = os.fdopen(fileref, 'w')
print >> fileobj, 'silent' # no progress meter
print >> fileobj, 'show-error' # print error msg to stderr
print >> fileobj, 'fail' # throw error if download fails
print >> fileobj, 'location' # follow redirects
print >> fileobj, 'request = %s' % method
print('silent', file=fileobj) # no progress meter
print('show-error', file=fileobj) # print error msg to stderr
print('fail', file=fileobj) # throw error if download fails
print('location', file=fileobj) # follow redirects
print('request = %s' % method, file=fileobj)
if headers:
for key in headers:
print >> fileobj, 'header = "%s: %s"' % (key, headers[key])
print >> fileobj, 'header = "Authorization: %s"' % self.authtoken
print('header = "%s: %s"' % (key, headers[key]), file=fileobj)
print('header = "Authorization: %s"' % self.authtoken, file=fileobj)
if formdata:
for line in formdata:
print >> fileobj, 'form = "%s"' % line
print('form = "%s"' % line, file=fileobj)
url = os.path.join(self.baseurl, relative_url)
print >> fileobj, 'url = "%s"' % url
print('url = "%s"' % url, file=fileobj)
fileobj.close()
cmd = [CURL_CMD, '-q', '--config', directivepath]

View File

@@ -1,3 +1,5 @@
from __future__ import print_function
import imp
import os
import sys
@@ -21,8 +23,8 @@ def plugin_named(name):
module = globals()[name]
return getattr(module, name)
except (KeyError, AttributeError):
print >> sys.stderr, (
"ERROR: %s repo plugin not found." % name)
print((
"ERROR: %s repo plugin not found." % name), file=sys.stderr)
return None

View File

@@ -21,6 +21,7 @@ Created by Greg Neagle on 2009-09-24.
Utility functions for using MunkiStatus.app
to display status and progress.
"""
from __future__ import print_function
import os
import time
@@ -157,4 +158,4 @@ def restartAlert():
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2017-03-29.
Support for using startosinstall to install macOS.
"""
from __future__ import print_function
# stdlib imports
import os
@@ -519,4 +520,4 @@ def run(finishing_tasks=None):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2016-12-13.
Common functions and classes used by the munki tools.
"""
from __future__ import print_function
import platform
import os
@@ -172,10 +173,11 @@ def osascript(osastring):
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(out, err) = proc.communicate()
if proc.returncode != 0:
print >> sys.stderr, 'Error: ', err
print('Error: ', err, file=sys.stderr)
if out:
return str(out).decode('UTF-8').rstrip('\n')
return u''
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2016-12-14.
Common pkg/receipt functions and classes used by the munki tools.
"""
from __future__ import print_function
import os
import re
@@ -871,4 +872,4 @@ def isApplication(pathname):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -17,6 +17,7 @@
powermgr.py
Munki module to handle Power Manager tasks
"""
from __future__ import print_function
from . import display
@@ -120,4 +121,4 @@ class Caffeinator(object):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2016-12-13.
Preferences functions and classes used by the munki tools.
"""
from __future__ import print_function
# PyLint cannot properly find names inside Cocoa libraries, so issues bogus
# No name 'Foo' in module 'Bar' warnings. Disable them.
# pylint: disable=E0611
@@ -269,7 +270,7 @@ def get_config_level(domain, pref_name, value):
def print_config():
'''Prints the current Munki configuration'''
print 'Current Munki configuration:'
print('Current Munki configuration:')
max_pref_name_len = max(
[len(pref_name) for pref_name in DEFAULT_PREFS.keys()])
for pref_name in sorted(DEFAULT_PREFS.keys()):
@@ -281,12 +282,12 @@ def print_config():
repr_value = value
if isinstance(value, basestring):
repr_value = repr(value)
print ('%' + str(max_pref_name_len) + 's: %5s %s ') % (
pref_name, repr_value, where)
print(('%' + str(max_pref_name_len) + 's: %5s %s ') % (
pref_name, repr_value, where))
# also print com.apple.SoftwareUpdate CatalogURL config if
# Munki is configured to install Apple updates
if pref('InstallAppleSoftwareUpdates'):
print 'Current Apple softwareupdate configuration:'
print('Current Apple softwareupdate configuration:')
domain = 'com.apple.SoftwareUpdate'
pref_name = 'CatalogURL'
value = CFPreferencesCopyAppValue(pref_name, domain)
@@ -294,9 +295,9 @@ def print_config():
repr_value = value
if isinstance(value, basestring):
repr_value = repr(value)
print ('%' + str(max_pref_name_len) + 's: %5s %s ') % (
pref_name, repr_value, where)
print(('%' + str(max_pref_name_len) + 's: %5s %s ') % (
pref_name, repr_value, where))
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -21,6 +21,7 @@ Created by Greg Neagle on 2016-12-14.
Functions for finding, listing, etc processes
"""
from __future__ import print_function
import os
import signal
@@ -219,4 +220,4 @@ def stop_requested():
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -17,6 +17,7 @@
profiles.py
Munki module for working with configuration profiles.
"""
from __future__ import print_function
import os
import subprocess
@@ -288,4 +289,4 @@ def profile_is_installed(identifier):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -21,6 +21,7 @@ Created by Greg Neagle on 2016-12-14.
Reporting functions
"""
from __future__ import print_function
import os
import subprocess
@@ -52,21 +53,21 @@ def printreportitem(label, value, indent=0):
"""Prints a report item in an 'attractive' way"""
indentspace = ' '
if type(value) == type(None):
print indentspace*indent, '%s: !NONE!' % label
print(indentspace*indent, '%s: !NONE!' % label)
elif type(value) == list or type(value).__name__ == 'NSCFArray':
if label:
print indentspace*indent, '%s:' % label
print(indentspace*indent, '%s:' % label)
index = 0
for item in value:
index += 1
printreportitem(index, item, indent+1)
elif type(value) == dict or type(value).__name__ == 'NSCFDictionary':
if label:
print indentspace*indent, '%s:' % label
print(indentspace*indent, '%s:' % label)
for subkey in value.keys():
printreportitem(subkey, value[subkey], indent+1)
else:
print indentspace*indent, '%s: %s' % (label, value)
print(indentspace*indent, '%s: %s' % (label, value))
def printreport(reportdict):
@@ -97,7 +98,7 @@ def _warn(msg):
"""We can't use display module functions here because that would require
circular imports. So a partial reimplementation."""
warning = 'WARNING: %s' % msg
print >> sys.stderr, warning.encode('UTF-8')
print(warning.encode('UTF-8'), file=sys.stderr)
munkilog.log(warning)
# append this warning to our warnings log
munkilog.log(warning, 'warnings.log')
@@ -148,4 +149,4 @@ report = {}
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -21,6 +21,7 @@ Created by Greg Neagle on 2016-12-14.
Functions to run scripts inside Munki
"""
from __future__ import print_function
import os
import subprocess
@@ -38,7 +39,7 @@ def _writefile(stringdata, path):
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')
print(line.encode('UTF-8'), file=fileobject)
fileobject.close()
return path
except (OSError, IOError):
@@ -131,4 +132,4 @@ def run_script(itemname, path, scriptname, suppress_error=False):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -19,6 +19,7 @@ updatecheck.analyze
Created by Greg Neagle on 2017-01-10.
"""
from __future__ import print_function
import datetime
import os
@@ -1018,4 +1019,4 @@ def process_removal(manifestitem, cataloglist, installinfo):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2018-04-17.
Functions for automatically discovering and configuring some Munki settings.
"""
from __future__ import print_function
# Apple frameworks via PyObjC
# PyLint cannot properly find names inside Cocoa libraries, so issues bogus
# No name 'Foo' in module 'Bar' warnings. Disable them.
@@ -103,4 +104,4 @@ def autodetect_repo_url_if_needed():
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2017-01-01.
Functions for working with Munki catalogs
"""
from __future__ import print_function
import os
@@ -561,7 +562,7 @@ def get_item_detail(name, cataloglist, vers='',
if skip_min_os_check:
display.display_debug1(
'Looking for detail for: %s, version %s, '
'ignoring minimum_os_version...', name, vers),
'ignoring minimum_os_version...', name, vers)
else:
display.display_debug1(
'Looking for detail for: %s, version %s...', name, vers)
@@ -649,4 +650,4 @@ def catalogs():
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2016-12-13.
Comparison/checking functions used by updatecheck
"""
from __future__ import print_function
import os
from operator import itemgetter
@@ -305,7 +306,7 @@ def compare_item_version(item):
return compare_plist_version(item)
if itemtype == 'file':
return filesystem_item_exists(item)
raise utils.Error('Unknown installs item type: %s', itemtype)
raise utils.Error('Unknown installs item type: %s' % itemtype)
def compare_receipt_version(item):
@@ -431,4 +432,4 @@ def get_installed_version(item_plist):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -19,6 +19,7 @@ updatecheck.core
Created by Greg Neagle on 2008-11-13.
"""
from __future__ import print_function
# standard libs
import os
@@ -534,4 +535,4 @@ def get_primary_manifest_catalogs(client_id='', force_refresh=False):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -21,6 +21,7 @@ Created by Greg Neagle on 2016-12-31.
Functions for downloading resources from the Munki server
"""
from __future__ import print_function
import os
import urllib2
@@ -500,4 +501,4 @@ def stop_precaching_agent():
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2017-01-01.
Utilities for determining installation status for Munki items.
"""
from __future__ import print_function
import os
@@ -293,4 +294,4 @@ def evidence_this_is_installed(item_pl):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -19,6 +19,7 @@ updatecheck.licensing
Created by Greg Neagle on 2017-01-01.
"""
from __future__ import print_function
from urllib import quote_plus
@@ -102,4 +103,4 @@ def update_available_license_seats(installinfo):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -21,6 +21,7 @@ Created by Greg Neagle on 2016-12-16.
Functions for working with manifest files
"""
from __future__ import print_function
import os
import urllib2
@@ -319,4 +320,4 @@ def remove_from_selfserve_uninstalls(itemname):
_MANIFESTS = {}
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -20,6 +20,7 @@ Created by Greg Neagle on 2017-02-18.
Functions for removing unused optional install items
"""
from __future__ import print_function
# Apple frameworks via PyObjC
# PyLint cannot properly find names inside Cocoa libraries, so issues bogus
@@ -139,4 +140,4 @@ def should_be_removed(item_pl):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -22,6 +22,7 @@ Common utility functions used throughout Munki.
Note: this module should be 100% free of ObjC-dependent Python imports.
"""
from __future__ import print_function
import grp
@@ -204,4 +205,4 @@ def getFirstPlist(textString):
if __name__ == '__main__':
print 'This is a library of support tools for the Munki Suite.'
print('This is a library of support tools for the Munki Suite.')

View File

@@ -25,6 +25,7 @@ This will have the effect of unbuffering output I/O from the subprocess.
stdin of the subprocess is not connected to the stdin of this parent
process.
"""
from __future__ import print_function
import fcntl
import os
@@ -67,7 +68,7 @@ def SigHandler(signum, frame):
def Usage(arg0):
"""Print usage."""
print >>sys.stderr, 'Usage: %s [command to run] [arguments...]' % arg0
print('Usage: %s [command to run] [arguments...]' % arg0, file=sys.stderr)
return 0
@@ -88,7 +89,7 @@ def PtyExec(argv):
try:
os.execv(argv[0], argv)
except OSError as e:
print >>sys.stderr, str(e)
print(str(e), file=sys.stderr)
sys.exit(1)
elif pid > 0: # parent
f = os.fdopen(fd, 'r+', 0)
@@ -109,7 +110,7 @@ def PtyExec(argv):
f.close()
elif pid == -1: # error, never forked.
print >>sys.stderr, 'fork() error'
print('fork() error', file=sys.stderr)
return 1
return child_exited.get(pid, 1)

View File

@@ -26,6 +26,7 @@ is made to revert to older versions of a file when uninstalling;
only file removals are done.
"""
from __future__ import print_function
import optparse
import os
@@ -66,7 +67,7 @@ def main():
# check to see if we're root
if os.geteuid() != 0:
print >> sys.stderr, "You must run this as root!"
print("You must run this as root!", file=sys.stderr)
exit(-1)
# set the display globals

View File

@@ -22,6 +22,7 @@ Created by Greg Neagle on 2016-06-22.
A tool to remove older, unused software items from a Munki repo.
"""
from __future__ import print_function
import plistlib
import subprocess
@@ -261,10 +262,10 @@ class RepoCleaner(object):
item_name = self.pkginfodb[key][
self.pkginfodb[key].keys()[0]][0]['name']
if print_this:
print key
print(key)
if item_name not in self.manifest_items:
print "[not in any manifests]"
print "versions:"
print("[not in any manifests]")
print("versions:")
index = 0
for version in sorted(self.pkginfodb[key].keys(), compare_versions):
line_info = ''
@@ -303,13 +304,13 @@ class RepoCleaner(object):
line_info = "(%s) %s" % (item['resource_identifier'],
line_info)
if print_this:
print " ", version, line_info
print(" ", version, line_info)
if len(item_list) > 1:
for item in item_list:
print " ", " " * len(version),
print "(%s)" % item['resource_identifier']
print(" ", " " * len(version), end=' ')
print("(%s)" % item['resource_identifier'])
if print_this:
print
print()
print_utf8("Total pkginfo items: %s" % self.pkginfo_count)
print_utf8("Item variants: %s" % len(self.pkginfodb.keys()))
@@ -364,7 +365,7 @@ class RepoCleaner(object):
if not os.path.exists(makecatalogs_path):
# didn't find it; assume the default install path
makecatalogs_path = '/usr/local/munki/makecatalogs'
print 'Rebuilding catalogs at %s...' % self.options.repo_url
print('Rebuilding catalogs at %s...' % self.options.repo_url)
cmd = [makecatalogs_path]
cmd.append('--repo-url')
cmd.append(self.options.repo_url)
@@ -381,8 +382,8 @@ class RepoCleaner(object):
errors = proc.stderr.read()
if errors:
print '\nThe following issues occurred while building catalogs:\n'
print errors
print('\nThe following issues occurred while building catalogs:\n')
print(errors)
def clean(self):
@@ -391,7 +392,7 @@ class RepoCleaner(object):
self.analyze_pkgsinfo()
self.find_cleanup_items()
if len(self.items_to_delete):
print
print()
answer = raw_input(
'Delete pkginfo and pkg items marked as [to be DELETED]? '
'WARNING: This action cannot be undone. [y/n] ')
@@ -427,7 +428,7 @@ def main():
options, arguments = parser.parse_args()
if options.version:
print get_version()
print(get_version())
exit(0)
if not options.repo_url:
@@ -458,8 +459,8 @@ def main():
try:
repo = munkirepo.connect(options.repo_url, options.plugin)
except munkirepo.RepoError as err:
print >> sys.stderr, (u'Could not connect to munki repo: %s'
% unicode(err))
print(u'Could not connect to munki repo: %s'
% unicode(err), file=sys.stderr)
exit(-1)
# clean up the repo

View File

@@ -16,6 +16,7 @@
# limitations under the License.
"""Tool to supervise launch other binaries."""
from __future__ import print_function
import errno
@@ -100,17 +101,16 @@ class Supervisor(object):
self.continue_sleeping = True
if 'delayrandom' in self.options and self.options['delayrandom']:
max_secs = self.options['delayrandom']
random_secs = random.randrange(0, max_secs)
logging.debug(
'Applying random delay up to %s seconds: %s',
max_secs, random_secs)
time.sleep(random_secs)
max_secs = self.options['delayrandom']
random_secs = random.randrange(0, max_secs)
logging.debug('Applying random delay up to %s seconds: %s',
max_secs, random_secs)
time.sleep(random_secs)
if self.delayrandom_abort:
if not self.continue_sleeping:
logging.debug('Awoken from random delay by signal')
signal.signal(signal.SIGUSR1, signal.SIG_DFL)
if not self.continue_sleeping:
logging.debug('Awoken from random delay by signal')
signal.signal(signal.SIGUSR1, signal.SIG_DFL)
if self.options['error-exec']:
self.stdout = tempfile.NamedTemporaryFile()
@@ -259,7 +259,7 @@ def parseOpts(argv):
def Usage():
"""Print usage."""
print """supervisor [options] [--] [path to executable] [arguments]
print("""supervisor [options] [--] [path to executable] [arguments]
options:
--timeout n
@@ -297,7 +297,7 @@ def Usage():
--
use the -- to separate supervisor options from arguments to the
executable which will appear as options.
"""
""")
def processOpts(options, args):

View File

@@ -6,6 +6,7 @@ test_isapprunning.py
Unit tests for processes.isAppRunning.
"""
from __future__ import print_function
# Copyright 2016-present Nate Walck.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,7 +31,7 @@ try:
from mock import patch
except ImportError:
import sys
print >>sys.stderr, "mock module is required. run: easy_install mock"
print("mock module is required. run: easy_install mock", file=sys.stderr)
raise

View File

@@ -1,5 +1,6 @@
#!/usr/bin/python env
from __future__ import print_function
import subprocess
import sys