#!/usr/bin/python3 # SPDX-License-Identifier: GPL-2.0-only import os import subprocess import cfg debug_opkg_cmds = bool(os.environ.get('DEBUG_OPKG_CMDS') or False) vardir = os.environ['VARDIR'] def opkgcl(opkg_args): cmd = '{} -o {} {}'.format(cfg.opkgcl, cfg.offline_root, opkg_args) if debug_opkg_cmds: print('DEBUG cmd: {}'.format(cmd)) p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) (stdout_data, stderr_data) = p.communicate() if debug_opkg_cmds: print('DEBUG stdout: {}'.format(stdout_data.decode('utf-8') if stdout_data else None)) print('DEBUG stderr: {}'.format(stderr_data.decode('utf-8') if stderr_data else None)) status = p.returncode return (status, stdout_data.decode('utf-8')) def distupgrade(params=None, flags=''): if params: return opkgcl('{} --force-postinstall dist-upgrade {}'.format(flags, params))[0] else: return opkgcl('--force-postinstall dist-upgrade')[0] def download(pkg_name, flags=''): return opkgcl('{} download {}'.format(flags, pkg_name))[0] def files(pkg_name): output = opkgcl('files {}'.format(pkg_name))[1] return output.split('\n')[1:] def flag_hold(pkg_name): out = opkgcl('flag hold {}'.format(pkg_name)) return out == 'Setting hold flag on package {}.'.format(pkg_name) def flag_unpacked(pkg_name): out = opkgcl('flag unpacked {}'.format(pkg_name)) return out == 'Setting flags for package {} to unpacked.'.format(pkg_name) def info(pkg_name, params=None, flags=''): if params: return opkgcl('{} --fields {} info {}'.format(flags, params, pkg_name))[1] else: return opkgcl('{} info {}'.format(flags, pkg_name))[1] def install(pkg_name, flags=''): return opkgcl('{} --force-postinstall install {}'.format(flags, pkg_name))[0] def is_autoinstalled(pkg_name): status_path = ('{}' + vardir + '/lib/opkg/status').format(cfg.offline_root) if not os.path.exists(status_path): return False status_file = open(status_path, 'r') status = status_file.read() status_file.close() index_start = status.find('Package: {}'.format(pkg_name)) if index_start < 0: return False index_end = status.find('\n\n', index_start) return status.find('Auto-Installed: yes', index_start, index_end) >= 0 def is_installed(pkg_name, version=None, flags=''): out = opkgcl('{} list_installed {}'.format(flags, pkg_name))[1] if len(out) == 0 or out.split()[0] != pkg_name: return False if version and out.split()[2] != version: return False if not os.path.exists(('{}' + vardir + '/lib/opkg/info/{}.control')\ .format(cfg.offline_root, pkg_name)): return False return True def is_upgradable(pkg_name, version=None): out = opkgcl('list_upgradable')[1] if len(out) == 0: return False for line in out.splitlines(): pkg, *_, new_v = line.split() if pkg != pkg_name: continue if version and new_v != version: return False return True return False def remove(pkg_name, flags=''): return opkgcl('{} --force-postinstall remove {}'.format(flags, pkg_name))[0] def update(): return opkgcl('update')[0] def search(glob): (status, output) = opkgcl('search {}'.format(glob)) if status == 255: raise FileNotFoundError() elif status != 0: raise OSError(status) else: return output.strip().split('\n') def upgrade(params=None, flags=''): if params: return opkgcl('{} --force-postinstall upgrade {}'.format(flags, params))[0] else: return opkgcl('--force-postinstall upgrade')[0] if __name__ == '__main__': import sys (status, output) = opkgcl(' '.join(sys.argv[1:])) print(output) exit(status)