Esempio n. 1
0
def local_display_percent_done(current, maximum):
    '''Bump up verboseness so we get download percentage done feedback.'''
    oldverbose = munkicommon.verbose
    munkicommon.verbose = oldverbose + 1
    
    munkicommon.display_percent_done(current, maximum)
    
    # set verboseness back.
    munkicommon.verbose = oldverbose
Esempio n. 2
0
def local_display_percent_done(current, maximum):
    '''Bump up verboseness so we get download percentage done feedback.'''
    oldverbose = munkicommon.verbose
    munkicommon.verbose = oldverbose + 1

    munkicommon.display_percent_done(current, maximum)

    # set verboseness back.
    munkicommon.verbose = oldverbose
Esempio n. 3
0
def removeFilesystemItems(removalpaths, forcedeletebundles):
    """
    Attempts to remove all the paths in the array removalpaths
    """
    # we sort in reverse because we can delete from the bottom up,
    # clearing a directory before we try to remove the directory itself
    removalpaths.sort(reverse=True)
    removalerrors = ""
    removalcount = len(removalpaths)
    munkicommon.display_status_minor('Removing %s filesystem items' %
                                     removalcount)

    itemcount = len(removalpaths)
    itemindex = 0
    munkicommon.display_percent_done(itemindex, itemcount)

    for item in removalpaths:
        itemindex += 1
        pathtoremove = "/" + item
        # use os.path.lexists so broken links return true
        # so we can remove them
        if os.path.lexists(pathtoremove):
            munkicommon.display_detail("Removing: " + pathtoremove)
            if (os.path.isdir(pathtoremove)
                    and not os.path.islink(pathtoremove)):
                diritems = munkicommon.listdir(pathtoremove)
                if diritems == ['.DS_Store']:
                    # If there's only a .DS_Store file
                    # we'll consider it empty
                    ds_storepath = pathtoremove + "/.DS_Store"
                    try:
                        os.remove(ds_storepath)
                    except (OSError, IOError):
                        pass
                    diritems = munkicommon.listdir(pathtoremove)
                if diritems == []:
                    # directory is empty
                    try:
                        os.rmdir(pathtoremove)
                    except (OSError, IOError), err:
                        msg = "Couldn't remove directory %s - %s" % (
                            pathtoremove, err)
                        munkicommon.display_error(msg)
                        removalerrors = removalerrors + "\n" + msg
                else:
                    # the directory is marked for deletion but isn't empty.
                    # if so directed, if it's a bundle (like .app), we should
                    # remove it anyway - no use having a broken bundle hanging
                    # around
                    if forcedeletebundles and isBundle(pathtoremove):
                        munkicommon.display_warning(
                            "Removing non-empty bundle: %s", pathtoremove)
                        retcode = subprocess.call(
                            ['/bin/rm', '-r', pathtoremove])
                        if retcode:
                            msg = "Couldn't remove bundle %s" % pathtoremove
                            munkicommon.display_error(msg)
                            removalerrors = removalerrors + "\n" + msg
                    else:
                        # if this path is inside a bundle, and we've been
                        # directed to force remove bundles,
                        # we don't need to warn because it's going to be
                        # removed with the bundle.
                        # Otherwise, we should warn about non-empty
                        # directories.
                        if not insideBundle(pathtoremove) or \
                           not forcedeletebundles:
                            msg = \
                              "Did not remove %s because it is not empty." % \
                               pathtoremove
                            munkicommon.display_error(msg)
                            removalerrors = removalerrors + "\n" + msg

            else:
                # not a directory, just unlink it
                # I was using rm instead of Python because I don't trust
                # handling of resource forks with Python
                #retcode = subprocess.call(['/bin/rm', pathtoremove])
                # but man that's slow.
                # I think there's a lot of overhead with the
                # subprocess call. I'm going to use os.remove.
                # I hope I don't regret it.
                retcode = ''
                try:
                    os.remove(pathtoremove)
                except (OSError, IOError), err:
                    msg = "Couldn't remove item %s: %s" % (pathtoremove, err)
                    munkicommon.display_error(msg)
                    removalerrors = removalerrors + "\n" + msg
Esempio n. 4
0
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)
Esempio n. 5
0
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
Esempio n. 6
0
                # I was using rm instead of Python because I don't trust
                # handling of resource forks with Python
                #retcode = subprocess.call(['/bin/rm', pathtoremove])
                # but man that's slow.
                # I think there's a lot of overhead with the
                # subprocess call. I'm going to use os.remove.
                # I hope I don't regret it.
                retcode = ''
                try:
                    os.remove(pathtoremove)
                except (OSError, IOError), err:
                    msg = "Couldn't remove item %s: %s" % (pathtoremove, err)
                    munkicommon.display_error(msg)
                    removalerrors = removalerrors + "\n" + msg

        munkicommon.display_percent_done(itemindex, itemcount)

    if removalerrors:
        munkicommon.display_info(
            "---------------------------------------------------")
        munkicommon.display_info(
            "There were problems removing some filesystem items.")
        munkicommon.display_info(
            "---------------------------------------------------")
        munkicommon.display_info(removalerrors)


def removepackages(pkgnames,
                   forcedeletebundles=False,
                   listfiles=False,
                   rebuildpkgdb=False,
Esempio n. 7
0
def removeFilesystemItems(removalpaths, forcedeletebundles):
    """
    Attempts to remove all the paths in the array removalpaths
    """
    # we sort in reverse because we can delete from the bottom up,
    # clearing a directory before we try to remove the directory itself
    removalpaths.sort(reverse=True)
    removalerrors = ""
    removalcount = len(removalpaths)
    munkicommon.display_status_minor(
        'Removing %s filesystem items' % removalcount)

    itemcount = len(removalpaths)
    itemindex = 0
    munkicommon.display_percent_done(itemindex, itemcount)

    for item in removalpaths:
        itemindex += 1
        pathtoremove = "/" + item
        # use os.path.lexists so broken links return true
        # so we can remove them
        if os.path.lexists(pathtoremove):
            munkicommon.display_detail("Removing: " + pathtoremove)
            if (os.path.isdir(pathtoremove) and \
               not os.path.islink(pathtoremove)):
                diritems = munkicommon.listdir(pathtoremove)
                if diritems == ['.DS_Store']:
                    # If there's only a .DS_Store file
                    # we'll consider it empty
                    ds_storepath = pathtoremove + "/.DS_Store"
                    try:
                        os.remove(ds_storepath)
                    except (OSError, IOError):
                        pass
                    diritems = munkicommon.listdir(pathtoremove)
                if diritems == []:
                    # directory is empty
                    try:
                        os.rmdir(pathtoremove)
                    except (OSError, IOError), err:
                        msg = "Couldn't remove directory %s - %s" % (
                            pathtoremove, err)
                        munkicommon.display_error(msg)
                        removalerrors = removalerrors + "\n" + msg
                else:
                    # the directory is marked for deletion but isn't empty.
                    # if so directed, if it's a bundle (like .app), we should
                    # remove it anyway - no use having a broken bundle hanging
                    # around
                    if (forcedeletebundles and isBundle(pathtoremove)):
                        munkicommon.display_warning(
                            "Removing non-empty bundle: %s", pathtoremove)
                        retcode = subprocess.call(['/bin/rm', '-r',
                                                   pathtoremove])
                        if retcode:
                            msg = "Couldn't remove bundle %s" % pathtoremove
                            munkicommon.display_error(msg)
                            removalerrors = removalerrors + "\n" + msg
                    else:
                        # if this path is inside a bundle, and we've been
                        # directed to force remove bundles,
                        # we don't need to warn because it's going to be
                        # removed with the bundle.
                        # Otherwise, we should warn about non-empty
                        # directories.
                        if not insideBundle(pathtoremove) or \
                           not forcedeletebundles:
                            msg = \
                              "Did not remove %s because it is not empty." % \
                               pathtoremove
                            munkicommon.display_error(msg)
                            removalerrors = removalerrors + "\n" + msg

            else:
                # not a directory, just unlink it
                # I was using rm instead of Python because I don't trust
                # handling of resource forks with Python
                #retcode = subprocess.call(['/bin/rm', pathtoremove])
                # but man that's slow.
                # I think there's a lot of overhead with the
                # subprocess call. I'm going to use os.remove.
                # I hope I don't regret it.
                retcode = ''
                try:
                    os.remove(pathtoremove)
                except (OSError, IOError), err:
                    msg = "Couldn't remove item %s: %s" % (pathtoremove, err)
                    munkicommon.display_error(msg)
                    removalerrors = removalerrors + "\n" + msg
Esempio n. 8
0
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)
Esempio n. 9
0
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
Esempio n. 10
0
                # I was using rm instead of Python because I don't trust
                # handling of resource forks with Python
                #retcode = subprocess.call(['/bin/rm', pathtoremove])
                # but man that's slow.
                # I think there's a lot of overhead with the
                # subprocess call. I'm going to use os.remove.
                # I hope I don't regret it.
                retcode = ''
                try:
                    os.remove(pathtoremove)
                except (OSError, IOError), err:
                    msg = "Couldn't remove item %s: %s" % (pathtoremove, err)
                    munkicommon.display_error(msg)
                    removalerrors = removalerrors + "\n" + msg

        munkicommon.display_percent_done(itemindex, itemcount)

    if removalerrors:
        munkicommon.display_info(
                        "---------------------------------------------------")
        munkicommon.display_info(
                        "There were problems removing some filesystem items.")
        munkicommon.display_info(
                        "---------------------------------------------------")
        munkicommon.display_info(removalerrors)


def removepackages(pkgnames, forcedeletebundles=False, listfiles=False,
                    rebuildpkgdb=False, noremovereceipts=False,
                    noupdateapplepkgdb=False):
    """
Esempio n. 11
0
def get_url(url,
            destinationpath,
            custom_headers=None,
            message=None,
            onlyifnewer=False,
            resume=False,
            follow_redirects=False):
    """Gets an HTTP or HTTPS URL and stores it in
    destination path. Returns a dictionary of headers, which includes
    http_result_code and http_result_description.
    Will raise CurlError if Gurl returns an error.
    Will raise HTTPError if HTTP Result code is not 2xx or 304.
    If destinationpath already exists, you can set 'onlyifnewer' to true to
    indicate you only want to download the file only if it's newer on the
    server.
    If you set resume to True, Gurl will attempt to resume an
    interrupted download."""

    tempdownloadpath = destinationpath + '.download'
    if os.path.exists(tempdownloadpath) and not resume:
        if resume and not os.path.exists(destinationpath):
            os.remove(tempdownloadpath)

    cache_data = None
    if onlyifnewer and os.path.exists(destinationpath):
        # create a temporary Gurl object so we can extract the
        # stored caching data so we can download only if the
        # file has changed on the server
        gurl_obj = Gurl.alloc().initWithOptions_({'file': destinationpath})
        cache_data = gurl_obj.get_stored_headers()
        del gurl_obj

    options = {
        'url': url,
        'file': tempdownloadpath,
        'follow_redirects': follow_redirects,
        'can_resume': resume,
        'additional_headers': header_dict_from_list(custom_headers),
        'download_only_if_changed': onlyifnewer,
        'cache_data': cache_data,
        'logging_function': munkicommon.display_debug2
    }
    munkicommon.display_debug2('Options: %s' % options)

    connection = Gurl.alloc().initWithOptions_(options)
    stored_percent_complete = -1
    stored_bytes_received = 0
    connection.start()
    try:
        while True:
            # if we did `while not connection.isDone()` we'd miss printing
            # messages and displaying percentages if we exit the loop first
            connection_done = connection.isDone()
            if message and connection.status and connection.status != 304:
                # log always, display if verbose is 1 or more
                # also display in MunkiStatus detail field
                munkicommon.display_status_minor(message)
                # now clear message so we don't display it again
                message = None
            if (str(connection.status).startswith('2')
                    and connection.percentComplete != -1):
                if connection.percentComplete != stored_percent_complete:
                    # display percent done if it has changed
                    stored_percent_complete = connection.percentComplete
                    munkicommon.display_percent_done(stored_percent_complete,
                                                     100)
            elif connection.bytesReceived != stored_bytes_received:
                # if we don't have percent done info, log bytes received
                stored_bytes_received = connection.bytesReceived
                munkicommon.display_detail('Bytes received: %s',
                                           stored_bytes_received)
            if connection_done:
                break

    except (KeyboardInterrupt, SystemExit):
        # safely kill the connection then re-raise
        connection.cancel()
        raise
    except Exception, err:  # too general, I know
        # Let us out! ... Safely! Unexpectedly quit dialogs are annoying...
        connection.cancel()
        # Re-raise the error as a GurlError
        raise GurlError(-1, str(err))
Esempio n. 12
0
                    if message and header.get('http_result_code') != '304':
                        if message:
                            # log always, display if verbose is 1 or more
                            # also display in MunkiStatus detail field
                            munkicommon.display_status_minor(message)

        elif targetsize and header.get('http_result_code').startswith('2'):
            # display progress if we get a 2xx result code
            if os.path.exists(tempdownloadpath):
                downloadedsize = os.path.getsize(tempdownloadpath)
                percent = int(float(downloadedsize)
                                    /float(targetsize)*100)
                if percent != downloadedpercent:
                    # percent changed; update display
                    downloadedpercent = percent
                    munkicommon.display_percent_done(downloadedpercent, 100)
            time.sleep(0.1)
        else:
            # Headers have finished, but not targetsize or HTTP2xx.
            # It's possible that Content-Length was not in the headers.
            # so just sleep and loop again. We can't show progress.
            time.sleep(0.1)

        if (proc.poll() != None):
            # For small download files curl may exit before all headers
            # have been parsed, don't immediately exit.
            maxheaders -= 1
            if donewithheaders or maxheaders <= 0:
                break

    retcode = proc.poll()
Esempio n. 13
0
                    if message and header.get('http_result_code') != '304':
                        if message:
                            # log always, display if verbose is 1 or more
                            # also display in MunkiStatus detail field
                            munkicommon.display_status_minor(message)

        elif targetsize and header.get('http_result_code').startswith('2'):
            # display progress if we get a 2xx result code
            if os.path.exists(tempdownloadpath):
                downloadedsize = os.path.getsize(tempdownloadpath)
                percent = int(float(downloadedsize)
                                    /float(targetsize)*100)
                if percent != downloadedpercent:
                    # percent changed; update display
                    downloadedpercent = percent
                    munkicommon.display_percent_done(downloadedpercent, 100)
            time.sleep(0.1)
        else:
            # Headers have finished, but not targetsize or HTTP2xx.
            # It's possible that Content-Length was not in the headers.
            # so just sleep and loop again. We can't show progress.
            time.sleep(0.1)

        if (proc.poll() != None):
            # For small download files curl may exit before all headers
            # have been parsed, don't immediately exit.
            maxheaders -= 1
            if donewithheaders or maxheaders <= 0:
                break

    retcode = proc.poll()
Esempio n. 14
0
                break
            else:
                # no data, but we're still running
                # sleep a bit before checking for more output
                time.sleep(1)
                continue

        output = output.decode('UTF-8').strip()
        # send the output to STDOUT or MunkiStatus as applicable
        if output.startswith('Progress: '):
            # Snow Leopard/Lion progress info with '-v' flag
            try:
                percent = int(output[10:].rstrip('%'))
            except ValueError:
                percent = -1
            munkicommon.display_percent_done(percent, 100)
        elif output.startswith('Software Update Tool'):
            # don't display this
            pass
        elif output.startswith('Copyright 2'):
            # don't display this
            pass
        elif output.startswith('Installing ') and mode == 'install':
            item = output[11:]
            if item:
                if munkicommon.munkistatusoutput:
                    munkistatus.message(output)
                    munkistatus.detail("")
                    munkistatus.percent(-1)
                    munkicommon.log(output)
                else:
Esempio n. 15
0
def get_url(url, destinationpath,
            custom_headers=None, message=None, onlyifnewer=False,
            resume=False, follow_redirects=False):
    """Gets an HTTP or HTTPS URL and stores it in
    destination path. Returns a dictionary of headers, which includes
    http_result_code and http_result_description.
    Will raise CurlError if Gurl returns an error.
    Will raise HTTPError if HTTP Result code is not 2xx or 304.
    If destinationpath already exists, you can set 'onlyifnewer' to true to
    indicate you only want to download the file only if it's newer on the
    server.
    If you set resume to True, Gurl will attempt to resume an
    interrupted download."""

    tempdownloadpath = destinationpath + '.download'
    if os.path.exists(tempdownloadpath) and not resume:
        if resume and not os.path.exists(destinationpath):
            os.remove(tempdownloadpath)

    cache_data = None
    if onlyifnewer and os.path.exists(destinationpath):
        # create a temporary Gurl object so we can extract the
        # stored caching data so we can download only if the
        # file has changed on the server
        gurl_obj = Gurl.alloc().initWithOptions_({'file': destinationpath})
        cache_data = gurl_obj.get_stored_headers()
        del gurl_obj

    options = {'url': url,
               'file': tempdownloadpath,
               'follow_redirects': follow_redirects,
               'can_resume': resume,
               'additional_headers': header_dict_from_list(custom_headers),
               'download_only_if_changed': onlyifnewer,
               'cache_data': cache_data,
               'logging_function': munkicommon.display_debug2}
    munkicommon.display_debug2('Options: %s' % options)

    connection = Gurl.alloc().initWithOptions_(options)
    stored_percent_complete = -1
    stored_bytes_received = 0
    connection.start()
    try:
        while True:
            # if we did `while not connection.isDone()` we'd miss printing
            # messages and displaying percentages if we exit the loop first
            connection_done = connection.isDone()
            if message and connection.status and connection.status != 304:
                # log always, display if verbose is 1 or more
                # also display in MunkiStatus detail field
                munkicommon.display_status_minor(message)
                # now clear message so we don't display it again
                message = None
            if (str(connection.status).startswith('2')
                and connection.percentComplete != -1):
                if connection.percentComplete != stored_percent_complete:
                    # display percent done if it has changed
                    stored_percent_complete = connection.percentComplete
                    munkicommon.display_percent_done(
                                                stored_percent_complete, 100)
            elif connection.bytesReceived != stored_bytes_received:
                # if we don't have percent done info, log bytes received
                stored_bytes_received = connection.bytesReceived
                munkicommon.display_detail(
                    'Bytes received: %s', stored_bytes_received)
            if connection_done:
                break

    except (KeyboardInterrupt, SystemExit):
        # safely kill the connection then re-raise
        connection.cancel()
        raise
    except Exception, err: # too general, I know
        # Let us out! ... Safely! Unexpectedly quit dialogs are annoying...
        connection.cancel()
        # Re-raise the error as a GurlError
        raise GurlError(-1, str(err))
Esempio n. 16
0
                break
            else:
                # no data, but we're still running
                # sleep a bit before checking for more output
                time.sleep(1)
                continue

        output = output.decode('UTF-8').strip()
        # send the output to STDOUT or MunkiStatus as applicable
        if output.startswith('Progress: '):
            # Snow Leopard/Lion progress info with '-v' flag
            try:
                percent = int(output[10:].rstrip('%'))
            except ValueError:
                percent = -1
            munkicommon.display_percent_done(percent, 100)
        elif output.startswith('Software Update Tool'):
            # don't display this
            pass
        elif output.startswith('Copyright 2'):
            # don't display this
            pass
        elif output.startswith('Installing ') and mode == 'install':
            item = output[11:]
            if item:
                if munkicommon.munkistatusoutput:
                    munkistatus.message(output)
                    munkistatus.detail("")
                    munkistatus.percent(-1)
                    munkicommon.log(output)
                else: