#!/usr/bin/env python # -*- coding: utf-8 -*- import ConfigParser import logging import paramiko import optparse import sys import os LOG = logging.getLogger('rpmbuild-remote') LOG.addHandler(logging.StreamHandler()) EXTENSIONS = ( 'patch', 'bz2', 'gz', 'tgz', 'lzma', 'xz', ) def get_parser(): """Return a commandline parser""" parser = optparse.OptionParser(usage="%prog [options]... ...") home = os.path.expanduser("~") parser.set_conflict_handler("resolve") parser.add_option("-c", "--config", action="store", type="string", dest="config", default=os.path.join(home, ".rpmbuild-remote"), help="Configuration file to use for the build. " "[Default: ~/.rpmbuild-remote") parser.add_option("-s", "--system", action="store", type="string", dest="system", help="The remote machine to use (defined in config file)") parser.add_option("-k", "--ssh-key", action="store", type="string", dest="ssh_key", help="The private SSH key to use to login.") parser.add_option("-u", "--user", action="store", type="string", dest="user", default=os.getlogin(), help="The username on the remote system [Default: current user]") parser.add_option("-h", "--host", action="store", type="string", dest="host", help="The hostname/IP of the remote system") parser.add_option("-p", "--port", action="store", type="int", dest="port", default=21, help="The port to use on the remote system [Default: 21]") parser.add_option("-d", "--dest", action="store", type="string", dest="dest", default=os.path.join(home, "rpmbuild-remote"), help="Directory to place resulting files " "[Default: ~/rpmbuild-remote/]") parser.add_option("-m", "--mock", action="store", type="string", dest="mock", help="Mock configuration to use (only applies to SRPM files) " "[Default: Use rpmbuild --rebuild)]") return parser def read_section(config, section, values): if not config.has_section(section): return ret = {} for value, typ in values: if config.has_option(section, value): if typ == 'int': method = config.getint elif typ == 'float': method = config.getfloat elif typ == 'boolean': method = config.getboolean elif typ == 'str': method = config.get else: method = config.get LOG.warning("Unknown type %s, assuming string" % typ) ret[value] = method(section, value) return ret def read_preferences(opts): values = ( ('user', 'str'), ('ssh_key', 'str'), ('host', 'str'), ('port', 'int'), ) config = ConfigParser.SafeConfigParser() config.read(opts.config) system = read_section(config, opts.system, values) if system == {}: system = read_section(config, 'default', values) if 'user' not in system: system['user'] = opts.user if 'ssh_key' not in system: system['ssh_key'] = opts.ssh_key if 'host' not in system: if opts.host is None: LOG.error("Host not set") sys.exit(1) system['host'] = opts.host if 'port' not in system: system['port'] = opts.port return system def execute_jobs(opts, system, jobs): session = paramiko.SSHClient() session.connect(system['host'], port=system['port'], username=system['user'], key_filename=system['ssh_key']) for job in jobs: # We have an SRPM if type(job) == type(''): # Send the file to the server dest = "$HOME/rpmbuild/SRPMS/" send_files([job], dest) # Build the SRPM # TODO else: # Send the spec file to the server dest = "$HOME/rpmbuild/SPECS" send_files([jobs[0]], dest) dest = "$HOME/rpmbuild/SOURCES" send_files(jobs[1:], dest) # Build the RPMs def main(): parser = get_parser() opts, args = parser.parse_args() jobs = [] for arg in args: ext = os.path.splitext(arg)[1] if ext == '.srpm': jobs.append(arg) elif ext == '.spec': jobs.append([arg]) else: if ext not in EXTENSIONS: LOG.warning("Uncommon source extension %s for file %s. " "Please double check files." % (ext, arg)) if not len(jobs) or not type(jobs[-1]) == type([]): LOG.error("Source file given without spec file.") sys.exit(1) jobs[-1].append(arg) # Read the preferences file system = read_preferences(opts) execute_jobs(opts, system, jobs) if __name__ == '__main__': main()