mirror of
https://github.com/munki/munki.git
synced 2026-04-23 04:59:17 -05:00
Removed code/tools/makeChoices.py; this functionality is better met with /usr/sbin/installer (10.6.6+)
This commit is contained in:
@@ -1,271 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
#
|
||||
# Copyright 2009-2010 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
|
||||
#
|
||||
# http://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.
|
||||
|
||||
"""
|
||||
makeChoices.py
|
||||
|
||||
Created by Greg Neagle on 2008-11-10.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import plistlib
|
||||
import subprocess
|
||||
import tempfile
|
||||
import optparse
|
||||
|
||||
def getchoicestatus(p,choiceID):
|
||||
(enabled, selected) = (False, -2)
|
||||
for plitem in p:
|
||||
if choiceID == plitem['choiceIdentifier']:
|
||||
return (plitem['choiceIsEnabled'], plitem['choiceIsSelected'])
|
||||
else:
|
||||
(enabled, selected) = getchoicestatus(plitem['childItems'],
|
||||
choiceID)
|
||||
if selected <> -2:
|
||||
return (enabled, selected)
|
||||
return (enabled, selected)
|
||||
|
||||
|
||||
def choiceItemHasChildren(p, choice):
|
||||
for item in p:
|
||||
if item['choiceIdentifier'] == choice:
|
||||
if len(item['childItems']):
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
childreturn = choiceItemHasChildren(item['childItems'], choice)
|
||||
if childreturn != -1:
|
||||
return childreturn
|
||||
return -1
|
||||
|
||||
|
||||
def getChoicesXML(pkgpath, target):
|
||||
cmd = ['/usr/sbin/installer', '-showChoicesXML', '-pkg', pkgpath, "-target", target]
|
||||
p = subprocess.Popen(cmd, shell=False, bufsize=1, stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
(plist, err) = p.communicate()
|
||||
if p.returncode == 0:
|
||||
if plist:
|
||||
return plistlib.readPlistFromString(plist)
|
||||
|
||||
return ''
|
||||
|
||||
|
||||
def OLDmakeChoiceForID(choicesxml, choiceID, desiredState, choiceArray):
|
||||
if choicesxml:
|
||||
(choiceEnabled, choiceSelected) = getchoicestatus(choicesxml,
|
||||
choiceID)
|
||||
#print choiceID, choiceEnabled, choiceSelected
|
||||
if choiceSelected == -2:
|
||||
print >>sys.stderr, "%s is not a valid choice." % choiceID
|
||||
exit(1)
|
||||
# if choice is not enabled, we can't change it
|
||||
if choiceEnabled:
|
||||
if choiceSelected == desiredState:
|
||||
# no clicks needed
|
||||
return
|
||||
if not choiceSelected == -1:
|
||||
# current state is not mixed, so one click
|
||||
# to invert
|
||||
choiceArray.append(choiceID)
|
||||
return
|
||||
# current state is mixed
|
||||
if desiredState == 1:
|
||||
# one click to go from mixed to on
|
||||
choiceArray.append(choiceID)
|
||||
return
|
||||
else:
|
||||
# two clicks to go from mixed to off
|
||||
choiceArray.append(choiceID)
|
||||
choiceArray.append(choiceID)
|
||||
return
|
||||
|
||||
else:
|
||||
if choiceSelected != desiredState:
|
||||
print >>sys.stderr, "Warning: Choice '%s' is not enabled; you cannot modify its selection state. Ignoring." % choiceID
|
||||
|
||||
|
||||
def makeChoiceForID(choicesxml, choiceID, desiredState, choiceArray):
|
||||
choice = {}
|
||||
choice['attributeSetting'] = (desiredState!=0)
|
||||
choice['choiceAttribute'] = "selected"
|
||||
choice['choiceIdentifier'] = choiceID
|
||||
choiceArray.append(choice)
|
||||
return
|
||||
|
||||
|
||||
def selectionInfo(enabled, selected, identifier, description):
|
||||
selChar = ' '
|
||||
required = ' '
|
||||
requiredText = ''
|
||||
if selected == 0:
|
||||
selChar = "O"
|
||||
if selected == 1:
|
||||
selChar = "X"
|
||||
if selected == -1:
|
||||
selChar = "-"
|
||||
if selected and not enabled:
|
||||
required = '!'
|
||||
requiredText = "REQUIRED"
|
||||
if not selected and not enabled:
|
||||
required = '!'
|
||||
requiredText = "NOT APPLICABLE"
|
||||
return "%s%s %s\t%s\t%s" % (required, selChar, identifier, requiredText, description)
|
||||
|
||||
|
||||
#def getPkgInfo(path):
|
||||
# if path.startswith("file://localhost") and path.endswith('.pkg'):
|
||||
# p = path[16:]
|
||||
# if os.path.exists(p):
|
||||
# if os.path.isfile(p): # new flat package
|
||||
# info = getPackageInfo.getFlatPackageInfo(p)
|
||||
# if os.path.isdir(p): # bundle-style package
|
||||
# info = getPackageInfo.getBundlePackageInfo(p)
|
||||
# if len(info):
|
||||
# return info[0]
|
||||
#
|
||||
# return {}
|
||||
|
||||
|
||||
def printchoices(p,indent,hideunselected=False,verbose=False):
|
||||
indentspace = " "
|
||||
for plitem in p:
|
||||
choice = {}
|
||||
choice['Identifier'] = plitem['choiceIdentifier']
|
||||
choice['IsEnabled'] = plitem.get('choiceIsEnabled', False)
|
||||
choice['IsSelected'] = plitem.get('choiceIsSelected', False)
|
||||
choice['IsVisible'] = plitem.get('choiceIsVisible', False)
|
||||
choice['pkgPaths'] = plitem.get('pathsOfActivePackagesInChoice')
|
||||
if 'choiceDescription' in plitem:
|
||||
choice['Description'] = plitem['choiceDescription']
|
||||
else:
|
||||
choice['Description'] = ''
|
||||
|
||||
if (not choice['IsSelected'] and hideunselected) or not choice['IsVisible']:
|
||||
pass
|
||||
else:
|
||||
print indentspace*indent, selectionInfo(choice['IsEnabled'],
|
||||
choice['IsSelected'], choice['Identifier'].encode('UTF-8'), choice['Description'].encode('UTF-8'))
|
||||
if verbose:
|
||||
for item in choice['pkgPaths']:
|
||||
print indentspace*(indent+1), item.encode('UTF-8')
|
||||
#pkginfo = getPkgInfo(item)
|
||||
#if pkginfo:
|
||||
#print indentspace*(indent+1), "pkgid: %s\tversion: %s" % (pkginfo['id'], pkginfo['version'])
|
||||
|
||||
if 'childItems' in plitem:
|
||||
printchoices(plitem['childItems'],indent+1,hideunselected)
|
||||
|
||||
|
||||
def getTopLevelEnabledSelectedChoices(p):
|
||||
choicelist = []
|
||||
for plitem in p:
|
||||
if plitem['choiceIsEnabled'] and plitem['choiceIsSelected'] and plitem['choiceIsVisible'] and plitem['choiceIdentifier'] != '__ROOT_CHOICE_IDENT__':
|
||||
choicelist.append(plitem['choiceIdentifier'])
|
||||
if plitem['choiceIdentifier'] == '__ROOT_CHOICE_IDENT__':
|
||||
for item in plitem['childItems']:
|
||||
if item['choiceIsEnabled'] and item['choiceIsSelected'] and item['choiceIsVisible']:
|
||||
choicelist.append(item['choiceIdentifier'])
|
||||
|
||||
return choicelist
|
||||
|
||||
|
||||
def main():
|
||||
p = optparse.OptionParser()
|
||||
p.set_usage("""Usage: %prog [options]
|
||||
Examples:
|
||||
%prog --pkg /path/to/some.pkg --listchoices
|
||||
%prog --pkg /path/to/some.pkg --doinstall CHOICEID
|
||||
%prog --pkg /path/to/some.pkg --doinstall CHOICEID1 --dontinstall CHOICEID2""")
|
||||
|
||||
p.add_option("--pkg", help="Path to package.")
|
||||
p.add_option('--target', default='/',
|
||||
help="Installer target. Defaults to /")
|
||||
p.add_option("--doinstall", action="append",
|
||||
help="Optional choices to install.")
|
||||
p.add_option("--dontinstall", action="append",
|
||||
help="Optional choices not to install.")
|
||||
p.add_option('--onlyinstall',
|
||||
help="Deselects all available choices except this one, selects this choice.")
|
||||
p.add_option("--listchoices", action='store_true',
|
||||
help="List the available choices.")
|
||||
p.add_option("--listselectedchoices", action='store_true',
|
||||
help="List only the selected choices.")
|
||||
p.add_option('--verbose', action='store_true', help='More output.')
|
||||
|
||||
# Get our options and our package path
|
||||
options, arguments = p.parse_args()
|
||||
if not options.pkg:
|
||||
print >>sys.stderr, "Must specify a package!"
|
||||
exit(1)
|
||||
|
||||
choicesxml = getChoicesXML(options.pkg, options.target)
|
||||
if choicesxml == '':
|
||||
print >>sys.stderr, "Error getting choicesxml."
|
||||
exit(1)
|
||||
|
||||
if options.listchoices:
|
||||
printchoices(choicesxml,0,False,options.verbose)
|
||||
exit(0)
|
||||
|
||||
if options.listselectedchoices:
|
||||
printchoices(choicesxml,0,True,options.verbose)
|
||||
exit(0)
|
||||
|
||||
choiceArray = []
|
||||
|
||||
if options.onlyinstall:
|
||||
selectedChoices = getTopLevelEnabledSelectedChoices(choicesxml)
|
||||
for item in selectedChoices:
|
||||
if not item == options.onlyinstall:
|
||||
makeChoiceForID(choicesxml, item, 0, choiceArray)
|
||||
|
||||
makeChoiceForID(choicesxml, options.onlyinstall, 1, choiceArray)
|
||||
|
||||
else:
|
||||
if options.doinstall:
|
||||
for item in options.doinstall:
|
||||
makeChoiceForID(choicesxml, item, 1, choiceArray)
|
||||
if options.dontinstall:
|
||||
for item in options.dontinstall:
|
||||
makeChoiceForID(choicesxml, item, 0, choiceArray)
|
||||
|
||||
mytmpdir = tempfile.mkdtemp()
|
||||
choicesxmlfile = os.path.join(mytmpdir, "choices.xml")
|
||||
plistlib.writePlist(choiceArray, choicesxmlfile)
|
||||
|
||||
print "Current choices:"
|
||||
cmd = ['/usr/sbin/installer', '-showChoicesAfterApplyingChangesXML',
|
||||
choicesxmlfile, '-pkg', options.pkg, "-target", options.target]
|
||||
p = subprocess.Popen(cmd, shell=False, bufsize=1, stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
(plist, err) = p.communicate()
|
||||
if p.returncode == 0:
|
||||
if plist:
|
||||
pl = plistlib.readPlistFromString(plist)
|
||||
printchoices(pl,0,False,options.verbose)
|
||||
else:
|
||||
print >>sys.stderr, err
|
||||
|
||||
print "choicesxmlfile at:", choicesxmlfile
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user