diff options
-rwxr-xr-x | backend/libsisyphus.py | 229 | ||||
-rwxr-xr-x | frontend/cli/sisyphus-cli.py | 33 | ||||
-rwxr-xr-x | helpers/make_local_csv_post | 21 | ||||
-rwxr-xr-x | helpers/make_local_csv_pre | 21 |
4 files changed, 304 insertions, 0 deletions
diff --git a/backend/libsisyphus.py b/backend/libsisyphus.py new file mode 100755 index 0000000..5dff073 --- /dev/null +++ b/backend/libsisyphus.py @@ -0,0 +1,229 @@ +#!/usr/bin/python3 + +import csv +import filecmp +import os +import shutil +import sqlite3 +import sys +import urllib3 +import subprocess + +redcore_portage_tree_path = '/usr/portage' +redcore_desktop_overlay_path = '/var/lib/layman/redcore-desktop' +redcore_portage_config_path = '/opt/redcore-build' + +sisyphus_remote_csv_url = 'http://mirror.math.princeton.edu/pub/redcorelinux/csv/remote_preinst.csv' +sisyphus_remote_csv_path_pre = '/var/lib/sisyphus/csv/remote_preinst.csv' +sisyphus_remote_csv_path_post = '/var/lib/sisyphus/csv/remote_postinst.csv' +sisyphus_local_csv_path_pre = '/var/lib/sisyphus/csv/local_preinst.csv' +sisyphus_local_csv_path_post = '/var/lib/sisyphus/csv/local_postinst.csv' +sisyphus_database_path = '/var/lib/sisyphus/db/sisyphus.db' +def check_if_root(): + if not os.getuid() == 0: + sys.exit("you need root permissions to do this. exiting!") + +def check_if_srcmode(): + portage_srcmode_make_conf = '/opt/redcore-build/conf/intel/portage/make.conf.amd64-srcmode' + portage_make_conf_symlink = '/etc/portage/make.conf' + + if os.path.islink(portage_make_conf_symlink) and os.path.realpath(portage_make_conf_symlink) == portage_srcmode_make_conf: + print("the system is set to srcmode (full gentoo), refusing to run!") + sys.exit(1) + +def check_redcore_portage_tree(): + os.chdir(redcore_portage_tree_path) + subprocess.call(['git', 'remote', 'update']) + redcore_portage_tree_local_hash = subprocess.check_output(['git', 'rev-parse', '@']) + redcore_portage_tree_remote_hash = subprocess.check_output(['git', 'rev-parse', '@{u}']) + + if not redcore_portage_tree_local_hash == redcore_portage_tree_remote_hash: + print("redcore desktop portage tree is out-of-date. run 'sisyphus update' first!") + sys.exit(1) + +def check_redcore_desktop_overlay(): + os.chdir(redcore_desktop_overlay_path) + subprocess.call(['git', 'remote', 'update']) + redcore_desktop_overlay_local_hash = subprocess.check_output(['git', 'rev-parse', '@']) + redcore_desktop_overlay_remote_hash = subprocess.check_output(['git', 'rev-parse', '@{u}']) + + if not redcore_desktop_overlay_local_hash == redcore_desktop_overlay_remote_hash: + print("redcore desktop overlay is out-of-date. run 'sisyphus update' first!") + sys.exit(1) + +def check_redcore_portage_config(): + os.chdir(redcore_portage_config_path) + subprocess.call(['git', 'remote', 'update']) + redcore_portage_config_local_hash = subprocess.check_output(['git', 'rev-parse', '@']) + redcore_portage_config_remote_hash = subprocess.check_output(['git', 'rev-parse', '@{u}']) + + if not redcore_portage_config_local_hash == redcore_portage_config_remote_hash: + print("redcore desktop portage config is out-of-date. run 'sisyphus update' first!") + sys.exit(1) + +def fetch_sisyphus_remote_packages_table_csv(): + http = urllib3.PoolManager() + + if not os.path.isfile(sisyphus_remote_csv_path_pre): + os.mknod(sisyphus_remote_csv_path_pre) + with http.request('GET', sisyphus_remote_csv_url, preload_content=False) as tmp_buffer, open(sisyphus_remote_csv_path_post, 'wb') as output_file: + shutil.copyfileobj(tmp_buffer, output_file) + else: + with http.request('GET', sisyphus_remote_csv_url, preload_content=False) as tmp_buffer, open(sisyphus_remote_csv_path_post, 'wb') as output_file: + shutil.copyfileobj(tmp_buffer, output_file) + +def check_sisyphus_remote_packages_table_csv(): + if not filecmp.cmp(sisyphus_remote_csv_path_pre, sisyphus_remote_csv_path_post): + print("sisyphus database remote_packages table is out-of-date. run 'sisyphus update' first!") + os.remove(sisyphus_remote_csv_path_post) + sys.exit(1) + else: + os.remove(sisyphus_remote_csv_path_post) + +def check_sisyphus_remote_packages_table(): + fetch_sisyphus_remote_packages_table_csv() + check_sisyphus_remote_packages_table_csv() + +def check_sync(): + check_if_root() + check_redcore_portage_tree() + check_redcore_desktop_overlay() + check_redcore_portage_config() + check_sisyphus_remote_packages_table() + +def sync_redcore_portage_tree_and_desktop_overlay(): + subprocess.call(['emerge', '--sync']) + +def sync_redcore_portage_config(): + os.chdir(redcore_portage_config_path) + print(">>> Syncing 'portage config' into '/etc/portage'...") + print("/usr/bin/git pull") + subprocess.call(['git', 'pull']) + print("=== Sync completed for 'portage config'") + +def sync_sisyphus_remote_packages_table_csv(): + if not filecmp.cmp(sisyphus_remote_csv_path_pre, sisyphus_remote_csv_path_post): + print(">>> Syncing 'sisyphus database remote_packages table' into '/var/lib/sisyphus/db/sisyphus.db'") + print("/usr/bin/sqlite3 /var/lib/sisyphus/db/sisyphus.db") + sisyphusdb = sqlite3.connect(sisyphus_database_path) + sisyphusdb.cursor().execute('''drop table if exists remote_packages''') + sisyphusdb.cursor().execute('''create table remote_packages (category TEXT,name TEXT,version TEXT,slot TEXT,description TEXT)''') + with open(sisyphus_remote_csv_path_post) as sisyphus_remote_csv: + for row in csv.reader(sisyphus_remote_csv): + sisyphusdb.cursor().execute("insert into remote_packages (category, name, version, slot, description) values (?, ?, ?, ?, ?);", row) + sisyphusdb.commit() + sisyphusdb.close() + print("=== Sync completed for 'sisyphus database remote_packages table'") + else: + print(">>> Syncing 'sisyphus database remote_packages table' into '/var/lib/sisyphus/db/sisyphus.db'") + print("/usr/bin/sqlite3 /var/lib/sisyphus/db/sisyphus.db") + print("Already up-to-date.") + print("=== Sync completed for 'sisyphus database remote_packages table'") + shutil.move(sisyphus_remote_csv_path_post, sisyphus_remote_csv_path_pre) + +def sync_sisyphus_database_remote_packages_table(): + fetch_sisyphus_remote_packages_table_csv() + sync_sisyphus_remote_packages_table_csv() + +def redcore_sync(): + check_if_root() + sync_redcore_portage_tree_and_desktop_overlay() + sync_redcore_portage_config() + sync_sisyphus_database_remote_packages_table() + +def generate_sisyphus_local_packages_table_csv_pre(): + subprocess.call(['/usr/share/sisyphus-cli/helpers/make_local_csv_pre']) # this is really hard to do in python, so we cheat with a bash helper script + +def generate_sisyphus_local_packages_table_csv_post(): + subprocess.call(['/usr/share/sisyphus-cli/helpers/make_local_csv_post']) # this is really hard to do in python, so we cheat with a bash helper script + +def sync_sisyphus_local_packages_table_csv(): + if filecmp.cmp(sisyphus_local_csv_path_pre, sisyphus_local_csv_path_post): + print("sisyphus database local_packages table is in sync with portage database, nothing to do...") + else: + print("sisyphus database local_packages table is not in sync with portage database, syncing now...") + sisyphusdb = sqlite3.connect(sisyphus_database_path) + sisyphusdb.cursor().execute('''drop table if exists local_packages''') + sisyphusdb.cursor().execute('''create table local_packages (category TEXT,name TEXT,version TEXT,slot TEXT,description TEXT)''') + with open(sisyphus_local_csv_path_post) as sisyphus_local_csv: + for row in csv.reader(sisyphus_local_csv): + sisyphusdb.cursor().execute("insert into local_packages (category, name, version, slot, description) values (?, ?, ?, ?, ?);", row) + sisyphusdb.commit() + sisyphusdb.close() + shutil.move(sisyphus_local_csv_path_post, sisyphus_local_csv_path_pre) + +def sisyphus_pkg_install(): + check_sync() + generate_sisyphus_local_packages_table_csv_pre() + subprocess.call(['emerge', '-a'] + sys.argv[2:]) + generate_sisyphus_local_packages_table_csv_post() + sync_sisyphus_local_packages_table_csv() + +def sisyphus_pkg_uninstall(): + check_sync() + generate_sisyphus_local_packages_table_csv_pre() + subprocess.call(['emerge', '--depclean', '-a'] + sys.argv[2:]) + generate_sisyphus_local_packages_table_csv_post() + sync_sisyphus_local_packages_table_csv() + +def sisyphus_pkg_force_uninstall(): + check_sync() + generate_sisyphus_local_packages_table_csv_pre() + subprocess.call(['emerge', '--unmerge', '-a'] + sys.argv[2:]) + generate_sisyphus_local_packages_table_csv_post() + sync_sisyphus_local_packages_table_csv() + +def sisyphus_pkg_remove_orphans(): + check_sync() + generate_sisyphus_local_packages_table_csv_pre() + subprocess.call(['emerge', '--depclean', '-a']) + generate_sisyphus_local_packages_table_csv_post() + sync_sisyphus_local_packages_table_csv() + +def sisyphus_pkg_system_upgrade(): + check_sync() + generate_sisyphus_local_packages_table_csv_pre() + subprocess.call(['emerge', '-uDaN', '--with-bdeps=y', '@world']) + generate_sisyphus_local_packages_table_csv_post() + sync_sisyphus_local_packages_table_csv() + +def sisyphus_pkg_auto_install(): + redcore_sync() + generate_sisyphus_local_packages_table_csv_pre() + subprocess.call(['emerge'] + sys.argv[2:]) + generate_sisyphus_local_packages_table_csv_post() + sync_sisyphus_local_packages_table_csv() + +def sisyphus_pkg_auto_uninstall(): + redcore_sync() + generate_sisyphus_local_packages_table_csv_pre() + subprocess.call(['emerge', '--depclean'] + sys.argv[2:]) + generate_sisyphus_local_packages_table_csv_post() + sync_sisyphus_local_packages_table_csv() + +def sisyphus_pkg_auto_force_uninstall(): + redcore_sync() + generate_sisyphus_local_packages_table_csv_pre() + subprocess.call(['emerge', '--unmerge'] + sys.argv[2:]) + generate_sisyphus_local_packages_table_csv_post() + sync_sisyphus_local_packages_table_csv() + +def sisyphus_pkg_auto_remove_orphans(): + redcore_sync() + generate_sisyphus_local_packages_table_csv_pre() + subprocess.call(['emerge', '--depclean', '-q']) + generate_sisyphus_local_packages_table_csv_post() + sync_sisyphus_local_packages_table_csv() + +def sisyphus_pkg_auto_system_upgrade(): + redcore_sync() + generate_sisyphus_local_packages_table_csv_pre() + subprocess.call(['emerge', '-uDN', '--with-bdeps=y', '@world']) + generate_sisyphus_local_packages_table_csv_post() + sync_sisyphus_local_packages_table_csv() + +def sisyphus_pkg_search(): + subprocess.call(['emerge', '--search'] + sys.argv[2:]) + +def sisyphus_pkg_system_update(): + redcore_sync() diff --git a/frontend/cli/sisyphus-cli.py b/frontend/cli/sisyphus-cli.py new file mode 100755 index 0000000..3d4fb3a --- /dev/null +++ b/frontend/cli/sisyphus-cli.py @@ -0,0 +1,33 @@ +#!/usr/bin/python3 + +import sys +import subprocess +from libsisyphus import * + +check_if_srcmode() + +if "__main__" == __name__: + if "install" in sys.argv[1:]: + sisyphus_pkg_install() + elif "uninstall" in sys.argv[1:]: + sisyphus_pkg_uninstall() + elif "force-uninstall" in sys.argv[1:]: + sisyphus_pkg_force_uninstall() + elif "remove-orphans" in sys.argv[1:]: + sisyphus_pkg_remove_orphans() + elif "upgrade" in sys.argv[1:]: + sisyphus_pkg_system_upgrade() + elif "auto-install" in sys.argv[1:]: + sisyphus_pkg_auto_install() + elif "auto-uninstall" in sys.argv[1:]: + sisyphus_pkg_auto_uninstall() + elif "auto-force-uninstall" in sys.argv[1:]: + sisyphus_pkg_auto_force_uninstall() + elif "auto-remove-orphans" in sys.argv[1:]: + sisyphus_pkg_auto_remove_orphans() + elif "auto-upgrade" in sys.argv[1:]: + sisyphus_pkg_auto_system_upgrade() + elif "search" in sys.argv[1:]: + sisyphus_pkg_search() + elif "update" in sys.argv[1:]: + sisyphus_pkg_system_update() diff --git a/helpers/make_local_csv_post b/helpers/make_local_csv_post new file mode 100755 index 0000000..cd38974 --- /dev/null +++ b/helpers/make_local_csv_post @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +collect_local_portage_database() { + for i in $(qlist -ICv); do + pushd /var/db/pkg/$i > /dev/null 2>&1 + echo "$(<CATEGORY),$(sed -re "s/-([0-9])/,\1/" <PF),$(<SLOT),$(sed -e "s/\"//g" -e "s/\'//g" -e "s/\,//g" <DESCRIPTION)" >> /tmp/local_postinst.csv + popd > /dev/null 2>&1 + done + mv /tmp/local_postinst.csv /var/lib/sisyphus/csv/ +} + +clean_temporary_files() { + rm -rf /tmp/local_postinst.csv +} + +main() { + collect_local_portage_database + clean_temporary_files +} + +main diff --git a/helpers/make_local_csv_pre b/helpers/make_local_csv_pre new file mode 100755 index 0000000..068331e --- /dev/null +++ b/helpers/make_local_csv_pre @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +collect_local_portage_database() { + for i in $(qlist -ICv); do + pushd /var/db/pkg/$i > /dev/null 2>&1 + echo "$(<CATEGORY),$(sed -re "s/-([0-9])/,\1/" <PF),$(<SLOT),$(sed -e "s/\"//g" -e "s/\'//g" -e "s/\,//g" <DESCRIPTION)" >> /tmp/local_preinst.csv + popd > /dev/null 2>&1 + done + mv /tmp/local_preinst.csv /var/lib/sisyphus/csv/ +} + +clean_temporary_files() { + rm -rf /tmp/local_preinst.csv +} + +main() { + collect_local_portage_database + clean_temporary_files +} + +main |