repacked is a command line tool bourne out of the lack of good tools to build cross-distro Linux packages from binaries. It was made free software by 736, the company behind Gameolith (http://www.gameolith.com) in October 2011.
With repacked, you just write a package spec, create a directory with the files structured exactly where they’ll be placed on the system, and run repacked on the package spec file. It’ll spit out all the packages you want.
repacked isn’t designed for creating packages out of Python modules or Ruby gems. Use FPM for that. https://github.com/jordansissel/fpm
repacked isn’t designed to convert one type of package to another. Use alien for that.
Package specifications are written in YAML. You can actually name the file whatever you want, but for the sake of clarity we’ll name this one "packagespec".
name: hello-world version: 1.0 maintainer: Joe Bloggs <[email protected]> summary: Warmly welcoming the world description: > Hello World is an application to say hello to the world. scripts: postinst: SCRIPTS/postinst packagetree: BUILD/ packages: - package: debian architecture: 32-bit requires: libc6, libstdc++6 conflicts: foo - package: rpm architecture: 64-bit requires: libc.so.6, libstdc++.so.6 pkgbuild: preserve-symlinks: true preserve-permissions: true dist-directory: DIST/ pkg-update-dist: PKG/update_hooks pkg-release-hooks: PKG/release_hooks pkg-release-hooks-tag: TAGNAME pkg-build-package: PKG/build_hooks pkg-build-package-args: BUILD_PACKAGE_ARGS
Available architecture types are 1) 32bit, 32-bit 2) 64bit, 64-bit 3) system [ System arch uses architecture used on host/build system as result package arch. ]
Hopefully the above example should be fairly self-explanatory. Just for reference, the file tree that the above spec file would expect is as follows:
┌── BUILD [directory] │ [ repacked automatically picks up all the files under │ this directory. ] | ├── DIST [directory] | [ original upstream sources can be put here, repacked will run pkg_release_hooks script to | put copy them to BUILD directory.] | ├── PKG [directory] | [ Scripts used during package build stages ] │ ├── SCRIPTS [directory] │ └── postinst │ └── packagespec
The scripts supported by repacked are preinst, postinst, prerm, postrm
You would then start repacked as follows, assuming you’re in the file tree above:
repacked.py packagespec
1) pkg-update-dist: PKG/update_hooks → Update upstream sources in DIST directory 2) pkg-release-hooks: PKG/release_hooks → Tag new release in DIST directory 3) pkg-build-package: PKG/build_hooks → Build newly tagged build from DIST and copy it to BUILD
Order of running Package scripts is this:
-
pkg-update-dist
-
pkg-release-hooks
-
pkg-build-package
1) pkg-update-dist script doesn’t receive any arguments
#!/bin/bash
GIT_SERVER="gitserver"
GIT_USER="gituser"
GIT_REPO="excample-git-repo.git"
#
# This script updates Sources in DIST directory to current version on git server
#
save_cd() {
pushd $(pwd) 1>/dev/null 2>&1
cd ${1} 1>/dev/null
}
save_popd() {
popd 1>/dev/null
}
reset_repo() {
git reset --hard
}
update_repo() {
if [ -d DIST/.git ]; then
save_cd DIST
git reset --hard
git pull --all
save_popd
else
git clone ${GIT_USER}@${GIT_SERVER}:${GIT_REPO} DIST/
fi
}
update_repo
2) pkg-release-hooks Has two arguments: * Package version number specified in version field of packagespec file * Optional tagname/branch name specified in pkg-release-hooks-tag field of packagespec file
#!/bin/sh
echo "$1" > BUILD/path-to-sources/version
# we just sync source files here no fancy release management here
rsync -avc --delete DIST/* BUILD/path-to-sources
3) pkg-build-package Has one argument: * Non specified optional arguments passed to a build script defined at pkg-build-package-args
There are two way which can be use to define a generated package version.
1) version tag in packagespec 2) define_env_version tag in packagespec pkgbuil section and package_name_version environmental variable
This makes package version much more dynamic. We need a way yo specify requirements for each package version. Value in pkg-version is matched against current package version and if they match we use that section data.
packages: - package: debian architecture: all pkg-version: 1.6 requires: ruby1.9 | ruby, webafis-ds-app, remote-admin, apt-show-versions, ansi-iso-sdk-linux, webafis-expressid-afis3, idkit-pro-sdk, iseglib-sdk, webafis-nginx-conf, webafis-ds-activemq, inn-oracle-jdk, inn-usb-mount, webafis-ds-graphics - package: debian architecture: all pkg-version: 1.5 requires: ruby1.9 | ruby, webafis-ds-app, remote-admin, apt-show-versions, ansi-iso-sdk-linux, expressid-afis-enterprise, idkit-pro-sdk, iseglib-sdk, webafis-nginx-conf, webafis-ds-activemq, webafis-ds-afismq, inn-oracle-jdk, inn-usb-mount, webafis-ds-graphics
For some situations we need to define dynamic version dependency for a package. E.g. if package requires another package with exact same version every time. Requires text is going to be used as template where package_version is replaced for current package version.
requires: webafis-es-gems (=${package_version}), inn-postgresql, inn-oracle-instaclient-client, cups, ttf-liberation, curl
Package formats are actually plugins. repacked comes with two plugins to start you off: - debian: creates deb packages - rpm: creates rpm packages
We’ll accept plugins for other packaging systems too, and we may even use them on Gameolith.
If you want to create a new plugin, we recommend copying the source of an existing plugin and using that as your starting point. Here’s a few things you should know: - To create control or spec files, you should use Mako templates. - The plugin system checks for a .plugin file in the plugins/ directory, it’s an ini file containing basic information about the plugin. module is the Python module that contains your plugin. - The first method of a plugin that repacked calls is tree(). That acts as a surrogate init(). tree() creates all the files necessary to build the package in a temporary directory. - The second method called is build(), which calls the build application (e.g. dpkg-deb or rpmbuild) and creates the package.
Troubleshooting -------------
If you have REPACKED_DEBUG environmental variable defined during build. Then repacked.py will print debug messages to stdout.