pax_global_header00006660000000000000000000000064123506131500014506gustar00rootroot0000000000000052 comment=3a3ade7491372865b284e92bacdf93431dd69f25 ricky-0.1/000077500000000000000000000000001235061315000124675ustar00rootroot00000000000000ricky-0.1/.gitignore000066400000000000000000000000261235061315000144550ustar00rootroot00000000000000*swp *pyc *ricky*egg* ricky-0.1/PACKAGING000066400000000000000000000041331235061315000136770ustar00rootroot00000000000000What is required to install/use ricky. So that may become some hints to create the package. System : sid, up to date on 04 Jul 2013 python 2.7.5+ and virtualenvwrapper (me) * Create your env cd ~ git clone https://github.com/paultag/ricky.git mkvirtualenv -p /usr/bin/python2.7 ricky workon ricky (me) virtualenv=ricky * Install ricky dependancies pip install python-debian pip install chardet pip install clint (me) virtualenv=ricky * Install ricky cd ~/ricky python setup.py develop (me/root) * Create the config file required for ricky : SAMPLE /etc/ricky.ini: ############################################################### [config] # Preferably a GPG auto key of yours to avoid repeatedly typing your passphrase signing-key=B11A9FEC01B2B1F6C1C31DD4896AE222CC16515C # Should be setup in your dput configuration dput-target=debuildme ############################################################### (me) * Set up a .dput.cf so that you can upload to lucy SAMPLE ~/.dput.cf: ############################################################### [debuildme] fqdn=debian-manager.via.ecp.fr login=lucy incoming=/srv/local-mirror/incoming method=scp ssh_config_options=IdentityFile ~/.ssh/autokey_id_ecdsa ############################################################### * Your gpg key should be available for lucy, go there and import it gpg --armor --export yourkey gpg --import # FIXME : not so good workaround # dput is not happy when it cannot verify the GPG sig of the original # signing developer (in the debian keyring) # Either use -u or do something else.... * Verify that the debian-keyring is installed on your computer * Add to your ~/.gnupg/gpg.conf SAMPLE : ~/.gnupg/gpg.conf ############################################################### keyring /usr/share/keyrings/debian-keyring.pgp keyring /usr/share/keyrings/debian-keyring.gpg ############################################################### (me) virtualenv=ricky * Use ricky ! ricky-upload --dist=unstable --source=awesome --version=3.4.15-1 --group=test-packages Should work, cross fingers and go look the UI or lucy logs ricky-0.1/bin/000077500000000000000000000000001235061315000132375ustar00rootroot00000000000000ricky-0.1/bin/rebuild000077500000000000000000000006261235061315000146170ustar00rootroot00000000000000#!/bin/bash GROUP=$2 SOURCE=$1 if [ "x${SOURCE}" = "x" ]; then echo "Need a source package" exit 1 fi if [ "x${GROUP}" = "x" ]; then echo "Need a group ID" exit 1 fi VERSION=$(apt-cache showsrc ${SOURCE} | grep '^Version:' | awk '{print $2}') echo "uploading ${SOURCE}/${VERSION} for unstable" ricky-upload --dist=unstable --source=${SOURCE} --version=${VERSION} \ --group=${GROUP} ricky-0.1/requirements.txt000066400000000000000000000000341235061315000157500ustar00rootroot00000000000000python-debian chardet clint ricky-0.1/ricky/000077500000000000000000000000001235061315000136105ustar00rootroot00000000000000ricky-0.1/ricky/__init__.py000066400000000000000000000002121235061315000157140ustar00rootroot00000000000000 __appname__ = "ricky" __version__ = "0.1" # FIXME : This should be easier to change DEFAULT_MIRROR = "debian.lcs.mit.edu" # HTTP Only ricky-0.1/ricky/cli.py000066400000000000000000000021351235061315000147320ustar00rootroot00000000000000from ricky.utils import write_changes, fetch_and_upload from clint import args def forge_changes(): dist = None for flag in args.flags: if flag is None: break k, v = (x.strip() for x in flag.split("=", 1)) if k == '--dist': dist = v if dist is None: raise Exception("No dist given with --dist=unstable") for what in args.files: changes = write_changes(what, dist) def upload_package(): opts = { "dist": "unstable", "source": None, "version": None, "group": None } for flag in args.flags: if flag is None: break k, v = (x.strip() for x in flag.split("=", 1)) if k.startswith('--'): k = k[2:] opts[k] = v for k, v in opts.items(): if v is None: raise KeyError( "give me --dist=unstable --source=fluxbox --version=1.3.5-1 --group=test" ) if opts['group']: opts['X-Debile-Group'] = opts.pop('group') else: opts.pop('group') fetch_and_upload(**opts) ricky-0.1/ricky/utils.py000066400000000000000000000122771235061315000153330ustar00rootroot00000000000000# This isn't perfect, but it'll do. from debian import deb822 import tempfile import subprocess import shutil from contextlib import contextmanager import os import shlex try: import configparser except ImportError: import ConfigParser as configparser import datetime as dt import email.utils import tarfile import hashlib import time import os @contextmanager def tdir(): fp = tempfile.mkdtemp() try: yield fp finally: shutil.rmtree(fp) @contextmanager def cd(where): ncwd = os.getcwd() try: yield os.chdir(where) finally: os.chdir(ncwd) def run_command(command, stdin=None): if not isinstance(command, list): command = shlex.split(command) try: pipe = subprocess.Popen(command, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError: return (None, None, -1) kwargs = {} if stdin: kwargs['input'] = stdin.read() (output, stderr) = pipe.communicate(**kwargs) output, stderr = (c.decode('utf-8', errors='ignore') for c in (output, stderr)) return (output, stderr, pipe.returncode) def pool_path(source): pfix = '' if source.startswith('lib'): pfix += source[:4] else: pfix += source[0] pfix += "/" + source return pfix def run(cmd): out, err, ret = run_command(cmd) if ret != 0: print(out, err) raise Exception("Command " + cmd + " failed") return out, err def fetch_and_upload(dist, source, version, **kwargs): from ricky import DEFAULT_MIRROR confFile = "/etc/ricky.ini" config = configparser.ConfigParser() if not os.path.isfile(confFile): raise Exception("Could not find " + confFile) config.read([confFile]) gpg = config.get('config', 'signing-key') target = config.get('config', 'dput-target') eversion = version if ":" in eversion: epoch, eversion = version.rsplit(":", 1) if "incoming.debian.org" == DEFAULT_MIRROR: DSC_URL = ( "http://{mirror}/{source}_{version}.dsc".format( source=source, version=eversion, mirror=DEFAULT_MIRROR, )) else: path = pool_path(source) DSC_URL = ( "http://{mirror}/debian/pool/main/" "{path}/{source}_{version}.dsc".format( path=path, source=source, version=eversion, mirror=DEFAULT_MIRROR, )) with tdir() as pth: with cd(pth): out, err = run(['dget', '-u', DSC_URL]) dsc = os.path.basename(DSC_URL) changes = write_changes(dsc, dist, **kwargs) out, err = run(['debsign', '-k%s' % (gpg), changes]) out, err = run(['dput', target, changes]) def file_info(path): for algo, name in [ ('md5', 'Files'), ('sha1', 'Checksums-Sha1'), ('sha256', 'Checksums-Sha256') ]: m = getattr(hashlib, algo)() buf = open(path, 'rb').read() m.update(buf) hhash = m.hexdigest() fsize = len(buf) yield (algo, name, hhash, fsize, path) def write_changes(fname, dist, **kwargs): changes = forge_changes_file(fname, dist, **kwargs) version = changes['Version'] eversion = version if ":" in eversion: epoch, eversion = version.rsplit(":", 1) path = '{source}_{version}_source.changes'.format( source=changes['Source'], version=eversion, ) changes.dump(fd=open(path, 'wb')) return path def forge_changes_file(fname, dist, **kwargs): dsc = deb822.Dsc(open(fname, 'r')) changes = deb822.Changes() changes['Format'] = '1.8' changes['Date'] = email.utils.formatdate( time.mktime(dt.datetime.utcnow().timetuple()), usegmt=True ) for key in [ 'Source', 'Version', 'Maintainer', 'Checksums-Sha1', 'Checksums-Sha256', 'Files' ]: changes[key] = dsc[key] for algo, key, h, s, f in file_info(fname): if algo == 'md5': algo = 'md5sum' entry = deb822.Deb822Dict() entry[algo] = h entry['size'] = s entry['name'] = f changes[key].append(entry) for entry in changes['Files']: entry['section'] = 'not-implemented' entry['priority'] = 'not-implemented' changes['Distribution'] = dist changes['Urgency'] = 'low' changes['Changed-By'] = 'Archive Rebuilder ' changes['Architecture'] = 'source' changes['Binary'] = 'not implemented either' changes['Description'] = """This feature is not implemented. This is a pretty damn hard to deal with right now. I might write this later.""" changes['Changes'] = """ {source} ({version}) {dist}; urgency={urgency} . * This is a fake ChangeLog entry used by ricky to force a rebuild on debuild.me.""".format( source=changes['Source'], version=changes['Version'], urgency=changes['Urgency'], dist=dist, ) for k, v in kwargs.items(): changes[k] = v return changes ricky-0.1/setup.py000077500000000000000000000014711235061315000142070ustar00rootroot00000000000000from ricky import __appname__, __version__ from setuptools import setup long_description = "" with open('requirements.txt') as f: install_requires = [l for l in f.read().splitlines() if not l.startswith('#')] setup( name=__appname__, version=__version__, scripts=[], packages=[ 'ricky', ], install_requires=install_requires, author="Paul Tagliamonte", author_email="tag@pault.ag", long_description=long_description, description='tool for rebuilding packages using the Debile infrastructure', license="Expat", url="http://deb.io/", platforms=['any'], entry_points={ 'console_scripts': [ 'ricky-forge-changes = ricky.cli:forge_changes', 'ricky-upload = ricky.cli:upload_package', ], } )