aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2015-08-04 15:22:29 -0400
committerAnthony G. Basile <blueness@gentoo.org>2015-08-04 15:22:29 -0400
commit31cbb5f345039e61d47f8e7d31adb4d523dd3acd (patch)
treec2751c678d89f3a0fbd8d66cf0dbec66ae0b05f6 /bin
parentgrs/Kernel.py: rsync was clobbering lib -> lib64, not tar. (diff)
downloadgrss-31cbb5f345039e61d47f8e7d31adb4d523dd3acd.tar.gz
grss-31cbb5f345039e61d47f8e7d31adb4d523dd3acd.tar.bz2
grss-31cbb5f345039e61d47f8e7d31adb4d523dd3acd.zip
Better organize directory structure.
Diffstat (limited to 'bin')
-rwxr-xr-xbin/clean-worldconf14
-rwxr-xr-xbin/grsrun77
-rwxr-xr-xbin/grsup204
-rwxr-xr-xbin/install-worldconf11
-rwxr-xr-xbin/make-worldconf147
5 files changed, 453 insertions, 0 deletions
diff --git a/bin/clean-worldconf b/bin/clean-worldconf
new file mode 100755
index 0000000..2e76f57
--- /dev/null
+++ b/bin/clean-worldconf
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+
+import os
+
+from grs import CONST
+from grs import WorldConf
+
+def main():
+ WorldConf.clean()
+ if os.path.isfile(CONST.PORTAGE_DIRTYFILE):
+ os.remove(CONST.PORTAGE_DIRTYFILE)
+
+if __name__ == "__main__":
+ main()
diff --git a/bin/grsrun b/bin/grsrun
new file mode 100755
index 0000000..c5e5240
--- /dev/null
+++ b/bin/grsrun
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+
+import os
+import re
+import signal
+import sys
+import time
+
+from grs import CONST
+from grs import Execute
+from grs import Interpret
+
+from getopt import getopt, GetoptError
+
+
+def usage(rc=1):
+ usage = """
+usage: grsrun [-m|-u|-h|-s <name>]
+
+flags: Release run. Do every step in build script.
+ : -u Update run. Do only '+' steps.
+ : -m Mock run. Log what would be done.
+ : -s <name>. Only run for GRS system <name>.
+ : -h Print this help file.
+"""
+ print(usage)
+ sys.exit(rc)
+
+
+
+def main():
+ try:
+ opts, x = getopt(sys.argv[1:], 'mus:h')
+ except GetoptError as e:
+ usage()
+
+ mock_run = False
+ update_run = False
+ grsname = None
+ for o, a in opts:
+ if o == '-h':
+ usage(0)
+ elif o == '-m':
+ mock_run = True
+ elif o == '-u':
+ update_run = True
+ elif o == '-s':
+ grsname = a
+
+ os.makedirs(CONST.GRS_CGROUPDIR, mode=0o555, exist_ok=True)
+ if not os.path.ismount(CONST.GRS_CGROUPDIR):
+ cmd = 'mount -t cgroup -o none,name=grs grs %s' % CONST.GRS_CGROUPDIR
+ Execute(cmd)
+
+ count = 0
+ for name in CONST.names:
+ if grsname:
+ if name != grsname:
+ count = count + 1
+ continue
+ if not os.fork():
+ subcgroup = 'run-%s' % name
+ subcgroupdir = os.path.join(CONST.GRS_CGROUPDIR, subcgroup)
+ os.makedirs(subcgroupdir, exist_ok=True)
+
+ cmd = 'cgclassify -g name=%s:/%s %d' % (CONST.GRS_CGROUP, subcgroup, os.getpid())
+ Execute(cmd)
+
+ mr = Interpret(CONST.pidfiles[count], run_number=count, subcgroupdir=subcgroupdir, \
+ mock_run=mock_run, update_run=update_run)
+ mr.start()
+ sys.exit(0)
+ count = count + 1
+
+
+if __name__ == '__main__':
+ main()
diff --git a/bin/grsup b/bin/grsup
new file mode 100755
index 0000000..2e726f0
--- /dev/null
+++ b/bin/grsup
@@ -0,0 +1,204 @@
+#!/usr/bin/env python
+
+import copy
+import os
+import re
+import shutil
+import signal
+import sys
+import urllib.request
+
+from getopt import getopt, GetoptError
+from html.parser import HTMLParser
+
+from grs import CONST
+from grs import Execute
+from grs import Log
+from grs import Synchronize
+from grs import WorldConf
+
+from _emerge.main import emerge_main, parse_opts
+from portage.exception import IsADirectory, ParseError, PermissionDenied
+from portage import settings
+
+
+def install_kernel(version = 'latest', logfile = CONST.LOGFILE):
+ """ doc here
+ more doc
+ """
+ class MyHTMLParser(HTMLParser):
+ def __init__(self, **kwargs):
+ HTMLParser.__init__(self, **kwargs)
+ self.kernels = []
+ def handle_starttag(self, tag, attrs):
+ if tag != 'a':
+ return
+ for attr in attrs:
+ if attr[0] == 'href' and re.match('linux-image-', attr[1]):
+ self.kernels.append(attr[1])
+ def get_kernels(self):
+ return self.kernels
+
+ baseurl = settings['PORTAGE_BINHOST']
+ if baseurl == '':
+ print('PORTAGE_BINHOST is not set. Install kernel manually.')
+ return
+
+ try:
+ request = urllib.request.urlopen('%s/%s' % (baseurl,'linux-images'))
+ dload = request.read().decode('utf-8')
+ except urllib.error.HTTPError:
+ print('Cannot open %s' % baseurl)
+ return
+
+ parser = MyHTMLParser()
+ parser.feed(dload)
+ kernels = parser.get_kernels()
+ kernels.sort()
+
+ if version == 'latest':
+ try:
+ kernel = kernels[-1]
+ except IndexError:
+ print('No linux-image available')
+ return
+ else:
+ for k in kernels:
+ m = re.search('linux-image-(.+).tar.xz', k)
+ if m.group(1) == version:
+ kernel = k
+ break
+ else:
+ print('No linux-image %s available' % version)
+ return
+
+ # Download the linux-image tarball to packages/linux-image
+ request = urllib.request.urlopen('%s/%s/%s' % (baseurl, 'linux-images', kernel))
+ package = '/usr/portage/packages/linux-images'
+ os.makedirs(package, mode=0o755, exist_ok=True)
+ kpath = os.path.join(package, kernel)
+ with open(kpath, 'wb') as f:
+ shutil.copyfileobj(request, f)
+
+ # Try to mount /boot. Fail silently since it may not be mountable.
+ if not os.path.ismount('/boot'):
+ cmd = 'mount /boot'
+ Execute(cmd, timeout=60, failok=True, logfile=logfile)
+
+ # Untar it at '/'. tar will not clobber files.
+ cwd = os.getcwd()
+ os.chdir('/')
+ cmd = 'tar --overwrite -Jxf %s' % kpath
+ Execute(cmd, timeout=600, logfile=logfile)
+ os.chdir(cwd)
+
+
+def usage(rc=1):
+ usage = """
+usage: grsup [pkg(s)] : update @world or pkg(s) if given
+ grsup [-r|-d] pkg(s) : re-install or delete pkg(s)
+ grsup -D : download all @world pkgs, don't install
+ grsup -k <version> : install kernel <version> or 'latest'
+ grsup -h : print this help
+"""
+ print(usage)
+ sys.exit(rc)
+
+
+def main():
+ myaction, myopts, myfiles = parse_opts(sys.argv[1:])
+
+ try:
+ opts, x = getopt(sys.argv[1:], 'Ck:rdh')
+ except GetoptError:
+ usage()
+
+ do_install_kernel = False
+ if len(opts) == 0:
+ args = ['-1', '-g', '-K', '-u', '-D', '-q']
+ if len(myfiles) == 0:
+ myfiles = ['@world']
+ args.extend(myfiles)
+ else:
+ exclude = 0
+ for o, a in opts:
+ if o == '-h':
+ usage(rc=0)
+ elif o == '-r':
+ if len(myfiles) == 0 or exclude > 1:
+ usage()
+ args = ['-1', '-g', '-K', '-D', '-q']
+ args.extend(myfiles)
+ exclude += 1
+ elif o == '-d':
+ if len(myfiles) == 0 or exclude > 1:
+ usage()
+ args = ['-C', '-q']
+ args.extend(myfiles)
+ exclude += 1
+ elif o == '-D':
+ if len(myfiles) > 0:
+ usage()
+ args = ['-g', '-e', '-f', '-q', '@world']
+ elif o == '-k':
+ if len(sys.argv[1:]) != 2:
+ usage()
+ version = a
+ do_install_kernel = True
+
+ if len(CONST.names) > 1:
+ sys.stderr.write('More than one GRS specified in systems.conf. Using the first one.\n')
+
+ name = CONST.names[0]
+ repo_uri = CONST.repo_uris[0]
+ stage_uri = CONST.stage_uris[0]
+ libdir = CONST.libdirs[0]
+ logfile = CONST.logfiles[0]
+
+ # Change the log name for the client.
+ basename = os.path.basename(logfile)
+ dirname = os.path.dirname(logfile)
+ logfile = os.path.join(dirname, 'grsup-%s' % basename)
+
+ Log(logfile).rotate_logs()
+ Synchronize(repo_uri, name, libdir, logfile).sync()
+
+ # Copy the new world.conf to CONST.WORLD_CONFIG
+ newconf = '%s/core%s' % (libdir, CONST.WORLD_CONFIG)
+ shutil.copy(newconf, CONST.WORLD_CONFIG)
+
+ if os.path.isfile(CONST.PORTAGE_DIRTYFILE):
+ WorldConf.clean()
+ open(CONST.PORTAGE_DIRTYFILE, 'a').close()
+ WorldConf.install()
+
+ if do_install_kernel:
+ install_kernel(version=version)
+ else:
+ try:
+ emerge_main(args)
+ except PermissionDenied as e:
+ sys.stderr.write("Permission denied: '%s'\n" % str(e))
+ sys.stderr.flush()
+ sys.exit(e.errno)
+ except IsADirectory as e:
+ sys.stderr.write("'%s' is a directory, but should be a file!\n" % sys.exit(e.errno))
+ sys.stderr.flush()
+ except ParseError as e:
+ sys.stderr.write("%s\n" % str(e))
+ sys.stderr.flush()
+ sys.exit(1)
+
+ WorldConf.clean()
+ if os.path.exists(CONST.PORTAGE_DIRTYFILE):
+ os.remove(CONST.PORTAGE_DIRTYFILE)
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ sys.stderr.write("Cleaning up /etc/portage. This make take some time.\n")
+ WorldConf.clean()
+ if os.path.exists(CONST.PORTAGE_DIRTYFILE):
+ os.remove(CONST.PORTAGE_DIRTYFILE)
diff --git a/bin/install-worldconf b/bin/install-worldconf
new file mode 100755
index 0000000..bdcc6b9
--- /dev/null
+++ b/bin/install-worldconf
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+
+from grs import CONST
+from grs import WorldConf
+
+def main():
+ open(CONST.PORTAGE_DIRTYFILE, 'a').close()
+ WorldConf.install()
+
+if __name__ == "__main__":
+ main()
diff --git a/bin/make-worldconf b/bin/make-worldconf
new file mode 100755
index 0000000..c991817
--- /dev/null
+++ b/bin/make-worldconf
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+
+import configparser
+import copy
+import os
+import re
+import sys
+
+from grs import CONST
+
+from _emerge.main import parse_opts
+from _emerge.actions import load_emerge_config, create_depgraph_params
+from _emerge.depgraph import backtrack_depgraph
+
+
+def useflags(config, p):
+ # Get all IUSE, enabled USE and EXPAND_HIDDEN flags.
+ try:
+ iuse = list(p.iuse.all)
+ use = list(p.use.enabled)
+ # expand = list(p.use.expand)
+ expand_hidden = list(p.use.expand_hidden)
+ except AttributeError:
+ return
+ except TypeError:
+ return
+
+ # We only include select USE_EXPAND flags. Note becaue of how we match 'abi_',
+ # for example, will match abi_ppc, abi_mips etc. Hopefully this will not lead
+ # to any false hits.
+ expand = [ 'kernel_', 'elibc_', 'userland_', 'abi_', 'linguas_', 'python_' ]
+
+ # Remove any selected USE_EXPAND and any EXPAND_HIDDEN flags from IUSE flags
+ my_iuse = copy.deepcopy(iuse)
+ for u in iuse:
+ for e in expand + expand_hidden:
+ while re.match(e, u):
+ try:
+ my_iuse.remove(u)
+ except ValueError:
+ break
+
+ # Remove the same flags from the enabled USE flags
+ my_use = copy.deepcopy(use)
+ for u in use:
+ for e in expand + expand_hidden:
+ while re.match(e, u):
+ try:
+ my_use.remove(u)
+ except ValueError:
+ break
+
+ # Remove the arch flag.
+ # TODO: this needs to be generalized.
+ my_use.remove('amd64')
+
+ # Go through all the IUSE flags and put a - in front
+ # of all the disabled USE flags.
+ flags = []
+ for i in my_iuse:
+ if i in my_use:
+ flags.append(i)
+ else:
+ flags.append('-%s' % i)
+
+ # Insert nicely sorted flags.
+ if len(flags) > 0:
+ flags.sort()
+ config[p.slot_atom]['package.use'] = p.slot_atom + ' ' + ' '.join(flags)
+
+
+def keywords(config, p):
+ # Stable means there is no keyword is needed.
+ keyword = None
+ try:
+ if not p.stable:
+ keyword = "??" # Something went wrong!
+ if p.get_keyword_mask() == 'missing':
+ keyword = '**'
+ if p.get_keyword_mask() == 'unstable':
+ # This needs to be generalized
+ keyword = '~amd64'
+ except AttributeError:
+ pass
+ if keyword:
+ config[p.slot_atom]['package.accept_keywords'] = '=%s %s' % (p.cpv, keyword)
+
+
+def from_etc_portage(config, p, subdir):
+ # We could add better matching intelligence here so as to match
+ # these subdirs+files for /etc/portage not maintained by GRS.
+ fpath = os.path.join(CONST.PORTAGE_CONFIGDIR, '%s/%s' % \
+ (subdir, re.sub('[/:]', '_', p.slot_atom)))
+ if os.path.isfile(fpath):
+ with open(fpath, 'r') as g:
+ config[p.slot_atom][subdir] = g.read().strip()
+
+
+def main():
+ args = sys.argv[1:]
+ if len(args) == 0:
+ args = [ '-e', '@world' ]
+
+ myaction, myopts, myfiles = parse_opts(args, silent=True)
+ emerge_config = load_emerge_config(action=myaction, args=myfiles, opts=myopts)
+ mysettings, mytrees = emerge_config.target_config.settings, emerge_config.trees
+ myparams = create_depgraph_params(myopts, myaction)
+ success, mydepgraph, favorites = backtrack_depgraph(mysettings, mytrees, myopts, \
+ myparams, myaction, myfiles, spinner=None)
+
+ config = configparser.RawConfigParser(delimiters=':', allow_no_value=True, comment_prefixes=None)
+
+ for p in mydepgraph.altlist():
+ # Prepare an empty section for this atom
+ try:
+ config[p.slot_atom] = {}
+ except AttributeError:
+ continue
+
+ # Populate package.use - these are read out of p
+ useflags(config, p)
+
+ # Populate package.accept_keywords - these are read out of p
+ keywords(config, p)
+
+ # Others - these are read out of /etc/portage
+ from_etc_portage(config, p, 'package.mask')
+ from_etc_portage(config, p, 'package.unmask')
+ from_etc_portage(config, p, 'package.env')
+ from_etc_portage(config, p, 'env')
+
+ # Remove any empty sections
+ if config[p.slot_atom] == {}:
+ config.remove_section(p.slot_atom)
+
+ # Recontruct a RawConfigParser from the above which has sorted sections.
+ all_slot_atoms = config.sections()
+ all_slot_atoms.sort()
+ sorted_config = configparser.RawConfigParser(delimiters=':', allow_no_value=True, comment_prefixes=None)
+ for s in all_slot_atoms:
+ sorted_config[s] = config[s]
+
+ with open('world.conf', 'w') as configfile:
+ sorted_config.write(configfile)
+
+if __name__ == "__main__":
+ main()