summaryrefslogtreecommitdiff
path: root/src/backend/libsisyphus.py
diff options
context:
space:
mode:
authorV3n3RiX <venerix@redcorelinux.org>2018-04-08 23:10:31 +0100
committerV3n3RiX <venerix@redcorelinux.org>2018-04-08 23:10:31 +0100
commit2b13470421825e151851b5d91b0c72b3054fc27f (patch)
tree5287c811726b2bb239909f11688055d9f7266f09 /src/backend/libsisyphus.py
parentf730fe0a876965ec656232ef838d7077bf00d89a (diff)
rewrite history
Diffstat (limited to 'src/backend/libsisyphus.py')
-rwxr-xr-xsrc/backend/libsisyphus.py259
1 files changed, 259 insertions, 0 deletions
diff --git a/src/backend/libsisyphus.py b/src/backend/libsisyphus.py
new file mode 100755
index 0000000..36a2dce
--- /dev/null
+++ b/src/backend/libsisyphus.py
@@ -0,0 +1,259 @@
+#!/usr/bin/python3
+
+import animation
+import csv
+import os
+import shutil
+import sqlite3
+import subprocess
+import sys
+import urllib3
+import io
+from datetime import datetime
+
+redcore_portage_config_path = '/opt/redcore-build'
+
+rmtPkgCsv = '/var/lib/sisyphus/csv/remotePackagesPre.csv'
+rmtDscCsv = '/var/lib/sisyphus/csv/remoteDescriptionsPre.csv'
+lclPkgCsv = '/var/lib/sisyphus/csv/localPackagesPre.csv'
+sisyphusDB = '/var/lib/sisyphus/db/sisyphus.db'
+mirrorCfg = '/etc/sisyphus/mirrors.conf'
+
+def checkRoot():
+ if not os.getuid() == 0:
+ sys.exit("\nYou need root permissions to do this, exiting!\n")
+
+def checkSystemMode():
+ portage_binmode_make_conf = '/opt/redcore-build/conf/intel/portage/make.conf.amd64-binmode'
+ portage_mixedmode_make_conf = '/opt/redcore-build/conf/intel/portage/make.conf.amd64-mixedmode'
+ portage_make_conf_symlink = '/etc/portage/make.conf'
+
+ if not os.path.islink(portage_make_conf_symlink):
+ print("\nmake.conf is not a symlink, refusing to run!\n")
+ sys.exit(1)
+ else:
+ if os.path.realpath(portage_make_conf_symlink) == portage_binmode_make_conf:
+ pass
+ elif os.path.realpath(portage_make_conf_symlink) == portage_mixedmode_make_conf:
+ pass
+ else:
+ print("\nThe system is not set to binmode or mixedmode, refusing to run!\n")
+ sys.exit(1)
+
+def fetchRemoteDatabaseCSV():
+ portageExec = subprocess.Popen(['emerge', '--info', '--verbose'], stdout=subprocess.PIPE)
+ for portageOutput in io.TextIOWrapper(portageExec.stdout, encoding="utf-8"):
+ if "PORTAGE_BINHOST" in portageOutput.rstrip():
+ rmtCsvUrl = str(portageOutput.rstrip().split("=")[1].strip('\"').replace('packages', 'csv') + 'remotePackagesPre.csv')
+ rmtDscUrl = str(portageOutput.rstrip().split("=")[1].strip('\"').replace('packages', 'csv') + 'remoteDescriptionsPre.csv')
+
+ http = urllib3.PoolManager()
+
+ with http.request('GET', rmtCsvUrl, preload_content=False) as tmp_buffer, open(rmtPkgCsv, 'wb') as output_file:
+ shutil.copyfileobj(tmp_buffer, output_file)
+
+ with http.request('GET', rmtDscUrl, preload_content=False) as tmp_buffer, open(rmtDscCsv, 'wb') as output_file:
+ shutil.copyfileobj(tmp_buffer, output_file)
+
+def syncGitRepos():
+ subprocess.check_call(['emerge', '--sync', '--quiet'])
+
+def syncPortageCfg():
+ os.chdir(redcore_portage_config_path)
+ subprocess.call(['git', 'pull', '--quiet'])
+
+def syncRemoteDatabaseCSV():
+ sisyphusdb = sqlite3.connect(sisyphusDB)
+ sisyphusdb.cursor().execute('''drop table if exists remote_packages''')
+ sisyphusdb.cursor().execute('''create table remote_packages (category TEXT,name TEXT,version TEXT,slot TEXT)''')
+ with open(rmtPkgCsv) as rmtCsv:
+ for row in csv.reader(rmtCsv):
+ sisyphusdb.cursor().execute("insert into remote_packages (category, name, version, slot) values (?, ?, ?, ?);", row)
+ sisyphusdb.commit()
+ sisyphusdb.close()
+
+ sisyphusdb = sqlite3.connect(sisyphusDB)
+ sisyphusdb.cursor().execute('''drop table if exists remote_descriptions''')
+ sisyphusdb.cursor().execute('''create table remote_descriptions (category TEXT,name TEXT,description TEXT)''')
+ with open(rmtDscCsv) as rmtCsv:
+ for row in csv.reader(rmtCsv):
+ sisyphusdb.cursor().execute("insert into remote_descriptions (category, name, description) values (?, ?, ?);", row)
+ sisyphusdb.commit()
+ sisyphusdb.close()
+
+def syncRemoteDatabaseTable():
+ fetchRemoteDatabaseCSV()
+ syncRemoteDatabaseCSV()
+
+@animation.wait('syncing remote database tables')
+def syncAll():
+ checkRoot()
+
+ portageExec = subprocess.Popen(['emerge', '--info', '--verbose'], stdout=subprocess.PIPE)
+ for portageOutput in io.TextIOWrapper(portageExec.stdout, encoding="utf-8"):
+ if "PORTAGE_BINHOST" in portageOutput.rstrip():
+ rmtCsvUrl = str(portageOutput.rstrip().split("=")[1].strip('\"').replace('packages', 'csv') + 'remotePackagesPre.csv')
+ rmtDscUrl = str(portageOutput.rstrip().split("=")[1].strip('\"').replace('packages', 'csv') + 'remoteDescriptionsPre.csv')
+
+ http = urllib3.PoolManager()
+
+ reqRmtPkgTs = http.request('HEAD',rmtCsvUrl)
+ rmtPkgTs = int(datetime.strptime(reqRmtPkgTs.headers['last-modified'], '%a, %d %b %Y %H:%M:%S %Z').strftime("%s"))
+ lclPkgTs = int(datetime.utcnow().strftime("%s"))
+
+ reqRmtDscTs = http.request('HEAD',rmtDscUrl)
+ rmtDscTs = int(datetime.strptime(reqRmtDscTs.headers['last-modified'], '%a, %d %b %Y %H:%M:%S %Z').strftime("%s"))
+ lclDscTs = int(datetime.utcnow().strftime("%s"))
+
+ if rmtPkgTs > lclPkgTs or rmtDscTs > lclDscTs:
+ fetchRemoteDatabaseCSV()
+ syncGitRepos()
+ syncPortageCfg()
+ syncRemoteDatabaseTable()
+
+def makeLocalDatabaseCSV():
+ subprocess.check_call(['/usr/share/sisyphus/helpers/make_local_csv']) # this is really hard to do in python, so we cheat with a bash helper script
+
+def syncLocalDatabaseTable():
+ sisyphusdb = sqlite3.connect(sisyphusDB)
+ sisyphusdb.cursor().execute('''drop table if exists local_packages''')
+ sisyphusdb.cursor().execute('''create table local_packages (category TEXT,name TEXT,version TEXT,slot TEXT)''')
+ with open(lclPkgCsv) as lclCsv:
+ for row in csv.reader(lclCsv):
+ sisyphusdb.cursor().execute("insert into local_packages (category, name, version, slot) values (?, ?, ?, ?);", row)
+ sisyphusdb.commit()
+ sisyphusdb.close()
+
+@animation.wait('syncing local database tables')
+def startSyncSPM():
+ makeLocalDatabaseCSV()
+ syncLocalDatabaseTable()
+
+def startInstall(pkgList):
+ syncAll()
+ portageExec = subprocess.Popen(['emerge', '-aq'] + pkgList)
+ portageExec.communicate()
+ makeLocalDatabaseCSV()
+ syncLocalDatabaseTable()
+
+def startUninstall(pkgList):
+ portageExec = subprocess.Popen(['emerge', '--depclean', '-aq'] + pkgList)
+ portageExec.communicate()
+ makeLocalDatabaseCSV()
+ syncLocalDatabaseTable()
+
+def startUninstallForce(pkgList):
+ portageExec = subprocess.Popen(['emerge', '--unmerge', '-aq'] + pkgList)
+ portageExec.communicate()
+ makeLocalDatabaseCSV()
+ syncLocalDatabaseTable()
+
+def removeOrphans():
+ portageExec = subprocess.Popen(['emerge', '--depclean', '-aq'])
+ portageExec.communicate()
+ makeLocalDatabaseCSV()
+ syncLocalDatabaseTable()
+
+def startUpgrade():
+ syncAll()
+ portageExec = subprocess.Popen(['emerge', '-uDaNq', '--backtrack=100', '--with-bdeps=y', '@world'])
+ portageExec.communicate()
+ makeLocalDatabaseCSV()
+ syncLocalDatabaseTable()
+
+def startSearch(pkgList):
+ subprocess.check_call(['emerge', '--search'] + pkgList)
+
+def startUpdate():
+ syncAll()
+
+def sysInfo():
+ subprocess.check_call(['emerge', '--info'])
+
+@animation.wait('resurrecting database tables')
+def rescueDB():
+ if os.path.exists(rmtPkgCsv):
+ os.remove(rmtPkgCsv)
+ if os.path.exists(rmtDscCsv):
+ os.remove(rmtDscCsv)
+ if os.path.exists(lclPkgCsv):
+ os.remove(lclPkgCsv)
+ if os.path.exists(sisyphusDB):
+ os.remove(sisyphusDB)
+
+ fetchRemoteDatabaseCSV()
+ syncRemoteDatabaseCSV()
+
+ makeLocalDatabaseCSV()
+ syncLocalDatabaseTable()
+
+def portageKill(portageCmd):
+ portageCmd.terminate()
+
+def getMirrors():
+ mirrorList = []
+ with open(mirrorCfg) as mirrorFile:
+ for line in mirrorFile.readlines():
+ if 'PORTAGE_BINHOST=' in line:
+ url = line.split("=")[1].replace('"', '').rstrip()
+ mirror = {'isActive':True,'Url':url}
+ if line.startswith('#'):
+ mirror['isActive'] = False
+ mirrorList.append(mirror)
+ mirrorFile.close()
+ return mirrorList
+
+def setActiveMirror(mirrorList):
+ with open(mirrorCfg, 'w+') as mirrorFile:
+ mirrorFile.write("#######################################################\n")
+ mirrorFile.write("# Support for multiple mirrors is somewhat incomplete #\n")
+ mirrorFile.write("# Uncomment only one mirror from the list bellow #\n")
+ mirrorFile.write("#######################################################\n")
+ mirrorFile.write("\n")
+ for line in mirrorList :
+ mirror = 'PORTAGE_BINHOST=' + '"' + line['Url'] + '"'
+ if not line['isActive']:
+ mirror = '# ' + mirror
+ mirrorFile.write(mirror + "\n")
+ mirrorFile.write("\n")
+
+def listRepo():
+ mirrorList = getMirrors()
+ for i, line in enumerate(mirrorList):
+ if line['isActive']:
+ print(i+1,'*',line['Url'])
+ else:
+ print(i+1,' ',line['Url'])
+
+def setRepo(mirror):
+ mirror = int(mirror[0])
+ mirrorList = getMirrors()
+ if mirror not in range(1,len(mirrorList)+1):
+ print('mirror index is wrong, please check with "sisyphus mirror list"')
+ else:
+ for i in range(0,len(mirrorList)):
+ indx = i+1
+ if indx == mirror :
+ mirrorList[i]['isActive'] = True
+ else:
+ mirrorList[i]['isActive'] = False
+ setActiveMirror(mirrorList)
+
+def showHelp():
+ print("\nUsage : sisyphus command [package(s)] || [file(s)]\n")
+ print("Sisyphus is a simple python wrapper around portage, gentoolkit, and portage-utils that provides")
+ print("an apt-get/yum-alike interface to these commands, to assist newcomer people transitioning from")
+ print("Debian/RedHat-based systems to Gentoo.\n")
+ print("Commands :\n")
+ print("install - Install new packages")
+ print("uninstall - Uninstall packages *safely* (INFO : If reverse deps are found, package(s) will NOT be uninstalled)")
+ print("force-uninstall - Uninstall packages *unsafely* (WARNING : This option will ignore reverse deps, which may break your system)")
+ print("remove-orphans - Uninstall packages that are no longer needed")
+ print("update - Update the Portage tree, Overlay(s), Portage config files && Sisyphus database remote_packages table")
+ print("upgrade - Upgrade the system")
+ print("search - Search for packages")
+ print("spmsync - Sync Sisyphus database with Portage database (if you install something with Portage, not Sisyphus)")
+ print("rescue - Rescue Sisyphus database if lost or corrupted")
+ print("mirror list - List available mirrors (the active one is marked with *)")
+ print("mirror set INDEX - Switch the repository to the selected mirror")
+ print("sysinfo - Display information about installed core packages and portage configuration")