Skip to content

Instantly share code, notes, and snippets.

@benedicteb
Last active January 31, 2017 09:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benedicteb/f9afa2ce7326e280e451c9ca5b0c456d to your computer and use it in GitHub Desktop.
Save benedicteb/f9afa2ce7326e280e451c9ca5b0c456d to your computer and use it in GitHub Desktop.
Script for finding pkg or dmg-files in a munki-repo that's not used in any pkginfo files.
#!/usr/bin/env python
"""
Usage:
./find_orphaned_pkgs.py
./find_orphaned_pkgs.py | grep -ie libreoffice | xargs rm # Remove all orphaned libreoffice pkgs
./find_orphaned_pkgs.py --munki-repo path/to/munki/repo
./find_orphaned_pkgs.py --count
"""
import argparse
import os.path as op
import os
import re
import plistlib
def munki_path(full_path):
return re.search(r'^.+pkgs\/(.+)$', full_path).group(1)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-m', '--munki-repo', type=str, default='./',
help='Path to munki repo. Defaults to current working dir.')
parser.add_argument('-c', '--count', action='store_true',
help='Print total number of orphans.')
args = parser.parse_args()
installer_item_location = 'installer_item_location'
if not op.exists(args.munki_repo):
raise Exception('No such path')
dirs = os.listdir(args.munki_repo)
if not 'pkgs' in dirs and not 'pkgsinfo' in dirs:
raise Exception('This does not look like a munki repo')
pkgs = []
for root, dirs, files in os.walk(op.join(args.munki_repo, 'pkgs/')):
for _dir in dirs:
if _dir.endswith('.pkg'):
pkgs.append(munki_path(op.join(root, _dir)))
for _file in files:
if _file.startswith('._') or _file.startswith('.DS_Store'):
continue
path = munki_path(op.join(root, _file))
# Don't react on pkgs where the script is able to traverse sub-files
if '.pkg' in path and (not path.endswith('.pkg') or path.count('.pkg') != 1):
continue
pkgs.append(path)
installer_items = []
for root, dirs, files in os.walk(op.join(args.munki_repo, 'pkgsinfo')):
for pkginfo in files:
plist = plistlib.readPlist(op.join(root, pkginfo))
if not installer_item_location in plist.keys():
continue
installer_items.append(plist[installer_item_location])
counter = 0
for pkg in pkgs:
if pkg not in installer_items:
counter += 1
print op.join(args.munki_repo, 'pkgs', pkg)
if args.count:
print 'Found %d orphaned files.' % counter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment