def removeReceipts(pkgkeylist, noupdateapplepkgdb): """ Removes receipt data from /Library/Receipts, /Library/Receipts/boms, our internal package database, and optionally Apple's package database. """ munkicommon.display_status_minor('Removing receipt info') munkicommon.display_percent_done(0, 4) conn = sqlite3.connect(packagedb) curs = conn.cursor() os_version = munkicommon.getOsVersion(as_tuple=True) applepkgdb = '/Library/Receipts/db/a.receiptdb' if not noupdateapplepkgdb and os_version <= (10, 5): aconn = sqlite3.connect(applepkgdb) acurs = aconn.cursor() munkicommon.display_percent_done(1, 4) for pkgkey in pkgkeylist: pkgid = '' pkgkey_t = (pkgkey, ) row = curs.execute('SELECT pkgname, pkgid from pkgs where pkg_key = ?', pkgkey_t).fetchone() if row: pkgname = row[0] pkgid = row[1] receiptpath = None if os_version <= (10, 5): if pkgname.endswith('.pkg'): receiptpath = os.path.join('/Library/Receipts', pkgname) if pkgname.endswith('.bom'): receiptpath = os.path.join('/Library/Receipts/boms', pkgname) else: # clean up /Library/Receipts in case there's stuff left there receiptpath = findBundleReceiptFromID(pkgid) if receiptpath and os.path.exists(receiptpath): munkicommon.display_detail("Removing %s...", receiptpath) dummy_retcode = subprocess.call( ["/bin/rm", "-rf", receiptpath]) # remove pkg info from our database munkicommon.display_detail( "Removing package data from internal database...") curs.execute('DELETE FROM pkgs_paths where pkg_key = ?', pkgkey_t) curs.execute('DELETE FROM pkgs where pkg_key = ?', pkgkey_t) # then remove pkg info from Apple's database unless option is passed if not noupdateapplepkgdb and pkgid: if os_version <= (10, 5): # Leopard pkgid_t = (pkgid, ) row = acurs.execute('SELECT pkg_key FROM pkgs where pkgid = ?', pkgid_t).fetchone() if row: munkicommon.display_detail( "Removing package data from Apple package " + "database...") apple_pkg_key = row[0] pkgkey_t = (apple_pkg_key, ) acurs.execute('DELETE FROM pkgs where pkg_key = ?', pkgkey_t) acurs.execute('DELETE FROM pkgs_paths where pkg_key = ?', pkgkey_t) acurs.execute('DELETE FROM pkgs_groups where pkg_key = ?', pkgkey_t) acurs.execute('DELETE FROM acls where pkg_key = ?', pkgkey_t) acurs.execute('DELETE FROM taints where pkg_key = ?', pkgkey_t) acurs.execute('DELETE FROM sha1s where pkg_key = ?', pkgkey_t) acurs.execute('DELETE FROM oldpkgs where pkg_key = ?', pkgkey_t) else: # Snow Leopard or higher, must use pkgutil cmd = ['/usr/sbin/pkgutil', '--forget', pkgid] proc = subprocess.Popen(cmd, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (output, dummy_err) = proc.communicate() if output: munkicommon.display_detail( str(output).decode('UTF-8').rstrip('\n')) munkicommon.display_percent_done(2, 4) # now remove orphaned paths from paths table # first, Apple's database if option is passed if not noupdateapplepkgdb: if os_version <= (10, 5): munkicommon.display_detail( "Removing unused paths from Apple package database...") acurs.execute('''DELETE FROM paths where path_key not in (select distinct path_key from pkgs_paths)''') aconn.commit() acurs.close() aconn.close() munkicommon.display_percent_done(3, 4) # we do our database last so its modtime is later than the modtime for the # Apple DB... munkicommon.display_detail("Removing unused paths from internal package " "database...") curs.execute('''DELETE FROM paths where path_key not in (select distinct path_key from pkgs_paths)''') conn.commit() curs.close() conn.close() munkicommon.display_percent_done(4, 4)
def initDatabase(forcerebuild=False): """ Builds or rebuilds our internal package database. """ if not shouldRebuildDB(packagedb) and not forcerebuild: return True munkicommon.display_status_minor( 'Gathering information on installed packages') if os.path.exists(packagedb): try: os.remove(packagedb) except (OSError, IOError): munkicommon.display_error( "Could not remove out-of-date receipt database.") return False os_version = munkicommon.getOsVersion(as_tuple=True) pkgcount = 0 receiptsdir = "/Library/Receipts" bomsdir = "/Library/Receipts/boms" if os.path.exists(receiptsdir): receiptlist = munkicommon.listdir(receiptsdir) for item in receiptlist: if item.endswith(".pkg"): pkgcount += 1 if os.path.exists(bomsdir): bomslist = munkicommon.listdir(bomsdir) for item in bomslist: if item.endswith(".bom"): pkgcount += 1 if os_version >= (10, 6): # Snow Leopard or later pkglist = [] cmd = ['/usr/sbin/pkgutil', '--pkgs'] proc = subprocess.Popen(cmd, shell=False, bufsize=1, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) while True: line = proc.stdout.readline() if not line and (proc.poll() != None): break pkglist.append(line.rstrip('\n')) pkgcount += 1 conn = sqlite3.connect(packagedb) conn.text_factory = str curs = conn.cursor() CreateTables(curs) currentpkgindex = 0 munkicommon.display_percent_done(0, pkgcount) if os.path.exists(receiptsdir): receiptlist = munkicommon.listdir(receiptsdir) for item in receiptlist: if munkicommon.stopRequested(): curs.close() conn.close() #our package db isn't valid, so we should delete it os.remove(packagedb) return False if item.endswith(".pkg"): receiptpath = os.path.join(receiptsdir, item) munkicommon.display_detail("Importing %s...", receiptpath) ImportPackage(receiptpath, curs) currentpkgindex += 1 munkicommon.display_percent_done(currentpkgindex, pkgcount) if os.path.exists(bomsdir): bomslist = munkicommon.listdir(bomsdir) for item in bomslist: if munkicommon.stopRequested(): curs.close() conn.close() #our package db isn't valid, so we should delete it os.remove(packagedb) return False if item.endswith(".bom"): bompath = os.path.join(bomsdir, item) munkicommon.display_detail("Importing %s...", bompath) ImportBom(bompath, curs) currentpkgindex += 1 munkicommon.display_percent_done(currentpkgindex, pkgcount) if os_version >= (10, 6): # Snow Leopard or later for pkg in pkglist: if munkicommon.stopRequested(): curs.close() conn.close() #our package db isn't valid, so we should delete it os.remove(packagedb) return False munkicommon.display_detail("Importing %s...", pkg) ImportFromPkgutil(pkg, curs) currentpkgindex += 1 munkicommon.display_percent_done(currentpkgindex, pkgcount) # in case we didn't quite get to 100% for some reason if currentpkgindex < pkgcount: munkicommon.display_percent_done(pkgcount, pkgcount) # commit and close the db when we're done. conn.commit() curs.close() conn.close() return True
def removeReceipts(pkgkeylist, noupdateapplepkgdb): """ Removes receipt data from /Library/Receipts, /Library/Receipts/boms, our internal package database, and optionally Apple's package database. """ munkicommon.display_status_minor('Removing receipt info') munkicommon.display_percent_done(0, 4) conn = sqlite3.connect(packagedb) curs = conn.cursor() os_version = munkicommon.getOsVersion(as_tuple=True) applepkgdb = '/Library/Receipts/db/a.receiptdb' if not noupdateapplepkgdb and os_version <= (10, 5): aconn = sqlite3.connect(applepkgdb) acurs = aconn.cursor() munkicommon.display_percent_done(1, 4) for pkgkey in pkgkeylist: pkgid = '' pkgkey_t = (pkgkey, ) row = curs.execute( 'SELECT pkgname, pkgid from pkgs where pkg_key = ?', pkgkey_t).fetchone() if row: pkgname = row[0] pkgid = row[1] receiptpath = None if os_version <= (10, 5): if pkgname.endswith('.pkg'): receiptpath = os.path.join('/Library/Receipts', pkgname) if pkgname.endswith('.bom'): receiptpath = os.path.join('/Library/Receipts/boms', pkgname) else: # clean up /Library/Receipts in case there's stuff left there receiptpath = findBundleReceiptFromID(pkgid) if receiptpath and os.path.exists(receiptpath): munkicommon.display_detail("Removing %s...", receiptpath) unused_retcode = subprocess.call( ["/bin/rm", "-rf", receiptpath]) # remove pkg info from our database munkicommon.display_detail( "Removing package data from internal database...") curs.execute('DELETE FROM pkgs_paths where pkg_key = ?', pkgkey_t) curs.execute('DELETE FROM pkgs where pkg_key = ?', pkgkey_t) # then remove pkg info from Apple's database unless option is passed if not noupdateapplepkgdb and pkgid: if os_version <= (10, 5): # Leopard pkgid_t = (pkgid, ) row = acurs.execute( 'SELECT pkg_key FROM pkgs where pkgid = ?', pkgid_t).fetchone() if row: munkicommon.display_detail( "Removing package data from Apple package "+ "database...") apple_pkg_key = row[0] pkgkey_t = (apple_pkg_key, ) acurs.execute( 'DELETE FROM pkgs where pkg_key = ?', pkgkey_t) acurs.execute( 'DELETE FROM pkgs_paths where pkg_key = ?', pkgkey_t) acurs.execute( 'DELETE FROM pkgs_groups where pkg_key = ?', pkgkey_t) acurs.execute( 'DELETE FROM acls where pkg_key = ?', pkgkey_t) acurs.execute( 'DELETE FROM taints where pkg_key = ?', pkgkey_t) acurs.execute( 'DELETE FROM sha1s where pkg_key = ?', pkgkey_t) acurs.execute( 'DELETE FROM oldpkgs where pkg_key = ?', pkgkey_t) else: # Snow Leopard or higher, must use pkgutil cmd = ['/usr/sbin/pkgutil', '--forget', pkgid] proc = subprocess.Popen(cmd, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (output, unused_err) = proc.communicate() if output: munkicommon.display_detail( str(output).decode('UTF-8').rstrip('\n')) munkicommon.display_percent_done(2, 4) # now remove orphaned paths from paths table # first, Apple's database if option is passed if not noupdateapplepkgdb: if os_version <= (10, 5): munkicommon.display_detail( "Removing unused paths from Apple package database...") acurs.execute( '''DELETE FROM paths where path_key not in (select distinct path_key from pkgs_paths)''') aconn.commit() acurs.close() aconn.close() munkicommon.display_percent_done(3, 4) # we do our database last so its modtime is later than the modtime for the # Apple DB... munkicommon.display_detail("Removing unused paths from internal package " "database...") curs.execute( '''DELETE FROM paths where path_key not in (select distinct path_key from pkgs_paths)''') conn.commit() curs.close() conn.close() munkicommon.display_percent_done(4, 4)
custom_header = custom_header.strip().encode('utf-8') if re.search(r'^[\w-]+:.+', custom_header): print >> fileobj, ('header = "%s"' % custom_header) else: munkicommon.display_warning( 'Skipping invalid HTTP header: %s' % custom_header) fileobj.close() except Exception, e: raise CurlError(-5, 'Error writing curl directive: %s' % str(e)) # In Mavericks we need to wrap our call to curl with a utility # that makes curl think it is connected to a tty-like # device so its output is unbuffered so we can get progress info cmd = [] minor_os_version = munkicommon.getOsVersion(as_tuple=True)[1] if minor_os_version > 8: # Try to find our ptyexec tool # first look in the parent directory of this file's directory # (../) parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) ptyexec_path = os.path.join(parent_dir, 'ptyexec') if not os.path.exists(ptyexec_path): # try absolute path in munki's normal install dir ptyexec_path = '/usr/local/munki/ptyexec' if os.path.exists(ptyexec_path): cmd = [ptyexec_path] # Workaround for current issue in OS X 10.9's included curl # Allows for alternate curl binary path as Apple's included curl currently # broken for client-side certificate usage