Skip to content

Instantly share code, notes, and snippets.

@tomjnixon
Created October 7, 2017 17:32
Show Gist options
  • Save tomjnixon/5b4a2132eb12e52e9aaf56d9d8aa6d97 to your computer and use it in GitHub Desktop.
Save tomjnixon/5b4a2132eb12e52e9aaf56d9d8aa6d97 to your computer and use it in GitHub Desktop.
get a list of user-installed packages given an OPKG status file/output from an OpenWRT/LEDE device

This is not intended to be run on-device, but it might be usefull as part of a backup/upgrade process.

Packages are listed that:

  • are not depended on by any other package
  • were not installed within 5 minutes of the kernel (which can't be upgraded without building a new image)

Obviously this is a quick hack, YMMV.

Usage

$ ssh [email protected] opkg status | python installed.py -
hostapd-utils iperf3 ...

$ python installed.py backup/usr/lib/opkg/status
hostapd-utils iperf3 ...
def parse_status_file(f):
packages = {}
data = {}
for line in f:
# deal with Conffiles values
if line.startswith(" "):
continue
line = line.strip()
if not line:
if data:
packages[data["Package"]] = data
data = {}
else:
key, value = line.split(":", 1)
data[key] = value.lstrip(" ")
if data:
packages[data["Package"]] = data
return packages
def get_dependant_packages(all_packages):
dependant = set(all_packages)
for name, data in all_packages.items():
for depend in data.get("Depends", "").split(", "):
depend = depend.split(" ")[0] # remove version number
if depend in dependant:
dependant.remove(depend)
return dependant
def remove_early(packages, selected):
creation_time = int(packages["kernel"]["Installed-Time"])
for name, data in packages.items():
if name in selected:
if int(data["Installed-Time"]) < creation_time + 300:
selected.remove(name)
def parse_args():
import argparse
parser = argparse.ArgumentParser(description="list user-installed opkg packages")
parser.add_argument("status_file", type=argparse.FileType('r'),
help="opkg status file, from /usr/lib/opkg/status or opkg status")
return parser.parse_args()
if __name__ == "__main__":
args = parse_args()
packages = parse_status_file(args.status_file)
selected = get_dependant_packages(packages)
remove_early(packages, selected)
print(' '.join(sorted(selected)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment