From 682da9e3da45278d6298e31808613a4a01963d5e Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Wed, 29 May 2013 14:38:27 +0000 Subject: Task engine is finally being used properly --- ipsutils/tasks.py | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ipsutils/version.py | 1 - 2 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 ipsutils/tasks.py delete mode 100644 ipsutils/version.py (limited to 'ipsutils') diff --git a/ipsutils/tasks.py b/ipsutils/tasks.py new file mode 100644 index 0000000..a48dea0 --- /dev/null +++ b/ipsutils/tasks.py @@ -0,0 +1,266 @@ +from . import task +from . import tpl +import os +import string +import shutil +import subprocess +import sys +import tempfile + +class Resolve_Dependencies(task.Task): + def __init__(self, *args, **kwargs): + super(Resolve_Dependencies, self).__init__(self, *args, **kwargs) + self.name = "Dependency resolution" + + def task(self): + command_pkg = [self.cls.tool['pkgdepend'], + 'resolve', + '-m', + self.cls.env_meta['STAGE3']] + proc_pkg = subprocess.Popen(command_pkg, stderr=subprocess.STDOUT) + err = proc_pkg.wait() + return err + + +class Dependencies(task.Task): + def __init__(self, *args, **kwargs): + super(Dependencies, self).__init__(self, *args, **kwargs) + self.name = "Automatic dependencies" + + def task(self): + command_pkg = [self.cls.tool['pkgdepend'], + 'generate', + '-md', + self.cls.env_pkg['BUILDPROTO'], + self.cls.env_meta['STAGE1_PASS2']] + command_pkgfmt = [self.cls.tool['pkgfmt']] + fp = file(self.cls.env_meta['STAGE3'], 'w+') + proc_pkg = subprocess.Popen(command_pkg, + stdout=subprocess.PIPE) + proc_pkgfmt = subprocess.Popen(command_pkgfmt, + stdin=proc_pkg.stdout, + stdout=fp) + output, err = proc_pkgfmt.communicate() + fp.close() + if self.cls.options.verbose: + if output: + for line in output: + print(">>> {0:s}".format(line)) + return err + + +class Transmogrify(task.Task): + def __init__(self, *args, **kwargs): + super(Transmogrify, self).__init__(self, *args, **kwargs) + self.name = "Transmogrifying file manifest" + + def task(self): + command_pkg = [self.cls.tool['pkgmogrify'], + '-DARCH={0:s}'.format(self.cls.key_dict['arch']), + self.cls.env_meta['STAGE1'], + self.cls.env_meta['STAGE2']] + command_pkgfmt = [self.cls.tool['pkgfmt']] + fp = file(self.cls.env_meta['STAGE2'], 'w+') + # Write %transforms block into transmogrification file + # Proper syntax required. + for line in self.cls.script_dict['transforms']: + fp.writelines(string.join(line)) + fp.close() + + fp = file(self.cls.env_meta['STAGE1_PASS2'], 'w+') + proc_pkg = subprocess.Popen(command_pkg, + stdout=subprocess.PIPE) + proc_pkgfmt = subprocess.Popen(command_pkgfmt, + stdin=proc_pkg.stdout, + stdout=fp) + output, err = proc_pkgfmt.communicate() + fp.close() + + if self.cls.options.verbose: + if output: + for line in output: + print(">>> {0:s}".format(line)) + return err + + +class Manifest(task.Task): + def __init__(self, *args, **kwargs): + super(Manifest, self).__init__(self, *args, **kwargs) + self.name = "Generate file manifest" + + def task(self): + command_pkg = [self.cls.tool['pkgsend'], + 'generate', + self.cls.env_pkg['BUILDPROTO']] + command_pkgfmt = [self.cls.tool['pkgfmt']] + fp = file(self.cls.env_meta['STAGE1'], 'a') + proc_pkg = subprocess.Popen(command_pkg, + stdout=subprocess.PIPE) + proc_pkgfmt = subprocess.Popen(command_pkgfmt, + stdin=proc_pkg.stdout, + stdout=fp) + output, err = proc_pkgfmt.communicate() + fp.close() + if self.cls.options.verbose: + if output: + for line in output: + print(">>> {0:s}".format(line)) + return err + + +class Unpack(task.Task): + def __init__(self, *args, **kwargs): + super(Unpack, self).__init__(self, *args, **kwargs) + self.name = "Unpack source" + + def task(self): + path = os.path.abspath(self.cls.env_pkg['SOURCES']) + if not os.path.exists(path): + print("{0:s}: does not exist".format(path)) + return False + if os.path.exists(self.cls.env_pkg['BUILD']): + shutil.rmtree(self.cls.env_pkg['BUILD']) + + ext = { + '.tar': '{0:s} xf {1:s} -C {2:s}'.format(self.cls.tool['tar'], path, self.cls.env['BUILD']), + '.tar.gz': '{0:s} xfz {1:s} -C {2:s}'.format(self.cls.tool['tar'], path, self.cls.env['BUILD']), + '.tar.bz2': '{0:s} xfj {1:s} -C {2:s}'.format(self.cls.tool['tar'], path, self.cls.env['BUILD']), + '.tar.xz': '{0:s} xfJ {1:s} -C {2:s}'.format(self.cls.tool['tar'], path, self.cls.env['BUILD']), + '.gz': self.cls.tool['gunzip'], # not implemented + '.bz2': self.cls.tool['bunzip'], # not implemented + '.zip': self.cls.tool['unzip'] # not implemented + } + + err = None + for k, v in ext.items(): + if k in path: + cmd = v.split() + if self.cls.options.verbose: + print(string.join(cmd)) + proc = subprocess.Popen(cmd) + err = proc.wait() + break + return err + + +class Buildroot(task.Task): + def __init__(self, *args, **kwargs): + super(Buildroot, self).__init__(self, *args, **kwargs) + self.name = "Create build root" + + def task(self): + """Destroy/Create BUILDROOT per execution to keep the environment stable + + p: tuple of function arguments + """ + path = self.cls.env_pkg['BUILDROOT'] + if os.path.exists(path): + shutil.rmtree(path) + os.makedirs(path, 0755) + return True + + +class Metadata(task.Task): + def __init__(self, *args, **kwargs): + super(Metadata, self).__init__(self, *args, **kwargs) + self.name = "Generate meta data" + + def task(self): + # A common problem that needs solving. What if you need to name your + # package something else? "repackage" + if self.cls.key_dict['repackage']: + repackas = 'repackage' + else: + repackas = 'name' + + output = [] + meta_map = { + 'pkg.fmri': self.cls.key_dict['group'] + "/" + + self.cls.key_dict[repackas] + "@" + + self.cls.key_dict['version'] + "," + + self.cls.key_dict['release'], + 'pkg.description': self.cls.key_dict['description'], + 'pkg.summary': self.cls.key_dict['summary'], + 'variant.arch': self.cls.key_dict['arch'], + 'info.upstream_url': self.cls.key_dict['upstream_url'], + 'info.source_url': self.cls.key_dict['source_url'], + 'info.classification': self.cls.key_dict['classification'] + } + + # Perform metadata template mapping and expansion + template = file(tpl.metadata, 'r') + for line in template.readlines(): + for k, v in meta_map.items(): + if k in line: + output.append(line.replace('{}', v)) + template.close() + + # Generate intial IPS metadata file in buildroot + metadata = file(os.path.join(self.cls.env_meta['STAGE1']), 'w+') + for line in output: + if self.cls.options.verbose: + print(">>> {0:s}".format(line)) + metadata.writelines(line) + metadata.close() + return True + + +class Script(task.Task): + def __init__(self, script, *args, **kwargs): + super(Script, self).__init__(self, *args, **kwargs) + self.script = script + + def task(self): + shebang = "#!/bin/bash\n" + fp_tempfile = tempfile.NamedTemporaryFile('w+', prefix='ipsutils_', suffix='.sh', delete=True) + os.chdir(self.cls.env_pkg['BUILD']) + fp_tempfile.write(shebang) + for line in self.script: + if not line: + continue + # Variable expansion occurs here. Unfortunately, env_pkg is NOT available + # from within the configuration class + t = string.Template(string.join(line)) + line = t.safe_substitute(self.cls.env_pkg) + fp_tempfile.writelines(line) + if self.cls.options.verbose: + print(">>> {0:s}".format(line)) + fp_tempfile.flush() + os.chmod(fp_tempfile.name, 0755) + script = [fp_tempfile.name] + proc = subprocess.Popen(script, stdout=sys.stdout) + err = proc.wait() + fp_tempfile.close() + + os.chdir(self.cls.env['IPSBUILD']) + return err + + +class Package(task.Task): + def __init__(self, *args, **kwargs): + super(Package, self).__init__(self, *args, **kwargs) + self.name = "Generate package" + self.spkg = False + self.source = self.cls.env_pkg['BUILDROOT'] + self.destination = self.cls.env_pkg['PKGS'] + if 'spkg' in kwargs: + self.spkg = True + self.name = "Generate source package" + self.destination = self.cls.env_pkg['SPKGS'] + + def task(self): + if os.path.exists(self.destination): + shutil.rmtree(self.destination) + + if self.spkg: + os.mkdir(self.destination) + shutil.copy2(self.cls.ipsfile, self.destination) + shutil.copy2(self.cls.env_pkg['SOURCES'], self.destination) + else: + shutil.copytree(self.cls.env_pkg['BUILDPROTO'], \ + os.path.join(self.destination, \ + os.path.basename(self.cls.env_pkg['BUILDPROTO']))) + shutil.copy2(self.cls.env_meta['STAGE4'], self.destination) + + return 0 + diff --git a/ipsutils/version.py b/ipsutils/version.py deleted file mode 100644 index e1424ed..0000000 --- a/ipsutils/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = '0.3.1' -- cgit