def make_package(distro, build_os, arch, spec, srcdir): """Construct the package for (arch, distro, spec). Get the packaging files from srcdir and any user-specified suffix from suffixes. """ sdir = setupdir(distro, build_os, arch, spec) packager.ensure_dir(sdir) # Note that the RPM packages get their man pages from the debian # directory, so the debian directory is needed in all cases (and # innocuous in the debianoids' sdirs). for pkgdir in ["debian", "rpm"]: print("Copying packaging files from %s to %s" % ("%s/%s" % (srcdir, pkgdir), sdir)) # FIXME: sh-dash-cee is bad. See if tarfile can do this. packager.sysassert([ "sh", "-c", "(cd \"%s\" && git archive %s %s/ ) | (cd \"%s\" && tar xvf -)" % (srcdir, spec.metadata_gitspec(), pkgdir, sdir) ]) # Splat the binaries and snmp files under sdir. The "build" stages of the # packaging infrastructure will move the files to wherever they # need to go. unpack_binaries_into(build_os, arch, spec, sdir) # Remove the mongoreplay binary due to libpcap dynamic # linkage. if os.path.exists(sdir + "bin/mongoreplay"): os.unlink(sdir + "bin/mongoreplay") return distro.make_pkg(build_os, arch, spec, srcdir)
def make_deb(distro, build_os, arch, spec, srcdir): # I can't remember the details anymore, but the initscript/upstart # job files' names must match the package name in some way; and # see also the --name flag to dh_installinit in the generated # debian/rules file. suffix = spec.suffix() sdir = setupdir(distro, build_os, arch, spec) if re.search("debian", distro.name()): os.link( sdir + "debian/init.d", sdir + "debian/%s%s-server.mongod.init" % (distro.pkgbase(), suffix)) os.unlink(sdir + "debian/mongod.upstart") elif re.search("ubuntu", distro.name()): os.link( sdir + "debian/mongod.upstart", sdir + "debian/%s%s-server.mongod.upstart" % (distro.pkgbase(), suffix)) os.unlink(sdir + "debian/init.d") else: raise Exception("unknown debianoid flavor: not debian or ubuntu?") # Rewrite the control and rules files write_debian_changelog(sdir + "debian/changelog", spec, srcdir) distro_arch = distro.archname(arch) sysassert([ "cp", "-v", srcdir + "debian/%s%s.control" % (distro.pkgbase(), suffix), sdir + "debian/control" ]) sysassert([ "cp", "-v", srcdir + "debian/%s%s.rules" % (distro.pkgbase(), suffix), sdir + "debian/rules" ]) # old non-server-package postinst will be hanging around for old versions # if os.path.exists(sdir + "debian/postinst"): os.unlink(sdir + "debian/postinst") # copy our postinst files # sysassert([ "sh", "-c", "cp -v \"%sdebian/\"*.postinst \"%sdebian/\"" % (srcdir, sdir) ]) # Do the packaging. oldcwd = os.getcwd() try: os.chdir(sdir) sysassert([ "dpkg-buildpackage", "-a" + distro_arch, "-k Richard Kreuter <*****@*****.**>" ]) finally: os.chdir(oldcwd) r = distro.repodir(arch, build_os, spec) ensure_dir(r) # FIXME: see if shutil.copyfile or something can do this without # much pain. sysassert(["sh", "-c", "cp -v \"%s/../\"*.deb \"%s\"" % (sdir, r)]) return r
def make_package(distro, build_os, arch, spec, srcdir): """Construct the package for (arch, distro, spec), getting packaging files from srcdir and any user-specified suffix from suffixes""" sdir = setupdir(distro, build_os, arch, spec) packager.ensure_dir(sdir) # Note that the RPM packages get their man pages from the debian # directory, so the debian directory is needed in all cases (and # innocuous in the debianoids' sdirs). for pkgdir in ["debian", "rpm"]: print "Copying packaging files from %s to %s" % ("%s/%s" % (srcdir, pkgdir), sdir) # FIXME: sh-dash-cee is bad. See if tarfile can do this. packager.sysassert([ "sh", "-c", "(cd \"%s\" && git archive %s %s/ ) | (cd \"%s\" && tar xvf -)" % (srcdir, spec.metadata_gitspec(), pkgdir, sdir) ]) # Splat the binaries and snmp files under sdir. The "build" stages of the # packaging infrastructure will move the files to wherever they # need to go. unpack_binaries_into(build_os, arch, spec, sdir) # Remove the mongoreplay binary due to libpcap dynamic # linkage. if os.path.exists(sdir + "bin/mongoreplay"): os.unlink(sdir + "bin/mongoreplay") return distro.make_pkg(build_os, arch, spec, srcdir)
def main(argv): # --distros must be "build_os" value, not actual distro name ("ubuntu1404" vs. "ubuntu") # distros=[Distro(distro) for distro in DISTROS] DISTRO_CHOICES=[] for distro in distros: DISTRO_CHOICES.extend(distro.build_os()) parser = argparse.ArgumentParser(description='Build MongoDB Packages') parser.add_argument("-s", "--server-version", help="Server version to build (e.g. 2.7.8-rc0)") parser.add_argument("-m", "--metadata-gitspec", help="Gitspec to use for package metadata files", required=False) parser.add_argument("-r", "--release-number", help="RPM release number base", type=int, required=False) parser.add_argument("-d", "--distros", help="Distros to build for", choices=DISTRO_CHOICES, required=False, default=[], action='append') parser.add_argument("-a", "--arches", help="Architecture to build", choices=DEFAULT_ARCHES, default=DEFAULT_ARCHES, required=False, action='append') parser.add_argument("-t", "--tarball", help="Local tarball to package instead of downloading (only valid with one distro/arch combination)", required=False, type=lambda x: is_valid_file(parser, x)) args = parser.parse_args() if len(args.distros) * len(args.arches) > 1 and args.tarball: parser.error("Can only specify local tarball with one distro/arch combination") spec = Spec(args.server_version, args.metadata_gitspec, args.release_number) oldcwd=os.getcwd() srcdir=oldcwd+"/../" # We do all our work in a randomly-created directory. You can set # TEMPDIR to influence where this program will do stuff. prefix=tempfile.mkdtemp() print "Working in directory %s" % prefix os.chdir(prefix) try: # Download the binaries. urlfmt="http://downloads.mongodb.com/linux/mongodb-linux-%s-enterprise-%s-%s.tgz" # Build a package for each distro/spec/arch tuple, and # accumulate the repository-layout directories. for (distro, arch) in crossproduct(distros, args.arches): for build_os in distro.build_os(): if build_os in args.distros or not args.distros: if args.tarball: filename = tarfile(build_os, arch, spec) ensure_dir(filename) shutil.copyfile(args.tarball,filename) else: httpget(urlfmt % (arch, build_os, spec.version()), ensure_dir(tarfile(build_os, arch, spec))) repo = make_package(distro, build_os, arch, spec, srcdir) make_repo(repo, distro, build_os, spec) finally: os.chdir(oldcwd)
def main(argv): distros = [EnterpriseDistro(distro) for distro in DISTROS] args = packager.get_args(distros, ARCH_CHOICES) spec = EnterpriseSpec(args.server_version, args.metadata_gitspec, args.release_number) oldcwd = os.getcwd() srcdir = oldcwd + "/../" # Where to do all of our work. Use a randomly-created directory if one # is not passed in. prefix = args.prefix if prefix is None: prefix = tempfile.mkdtemp() print "Working in directory %s" % prefix os.chdir(prefix) try: # Download the binaries. urlfmt = "http://downloads.mongodb.com/linux/mongodb-linux-%s-enterprise-%s-%s.tgz" made_pkg = False # Build a package for each distro/spec/arch tuple, and # accumulate the repository-layout directories. for (distro, arch) in packager.crossproduct(distros, args.arches): for build_os in distro.build_os(arch): if build_os in args.distros or not args.distros: if args.tarball: filename = tarfile(build_os, arch, spec) packager.ensure_dir(filename) shutil.copyfile(args.tarball, filename) else: packager.httpget( urlfmt % (arch, build_os, spec.version()), packager.ensure_dir(tarfile(build_os, arch, spec))) repo = make_package(distro, build_os, arch, spec, srcdir) make_repo(repo, distro, build_os, spec) made_pkg = True if not made_pkg: raise Exception("No valid combination of distro and arch selected") finally: os.chdir(oldcwd)
def main(argv): distros=[EnterpriseDistro(distro) for distro in DISTROS] args = packager.get_args(distros, ARCH_CHOICES) spec = EnterpriseSpec(args.server_version, args.metadata_gitspec, args.release_number) oldcwd=os.getcwd() srcdir=oldcwd+"/../" # Where to do all of our work. Use a randomly-created directory if one # is not passed in. prefix = args.prefix if prefix is None: prefix=tempfile.mkdtemp() print "Working in directory %s" % prefix os.chdir(prefix) try: # Download the binaries. urlfmt="http://downloads.mongodb.com/linux/mongodb-linux-%s-enterprise-%s-%s.tgz" made_pkg = False # Build a package for each distro/spec/arch tuple, and # accumulate the repository-layout directories. for (distro, arch) in packager.crossproduct(distros, args.arches): for build_os in distro.build_os(arch): if build_os in args.distros or not args.distros: if args.tarball: filename = tarfile(build_os, arch, spec) packager.ensure_dir(filename) shutil.copyfile(args.tarball,filename) else: packager.httpget(urlfmt % (arch, build_os, spec.version()), packager.ensure_dir(tarfile(build_os, arch, spec))) repo = make_package(distro, build_os, arch, spec, srcdir) make_repo(repo, distro, build_os, spec) made_pkg = True if not made_pkg: raise Exception("No valid combination of distro and arch selected") finally: os.chdir(oldcwd)
def main(): """Execute Main program.""" distros = [EnterpriseDistro(distro) for distro in DISTROS] args = packager.get_args(distros, ARCH_CHOICES) spec = EnterpriseSpec(args.server_version, args.metadata_gitspec, args.release_number) oldcwd = os.getcwd() srcdir = oldcwd + "/../" # Where to do all of our work. Use a randomly-created directory if one # is not passed in. prefix = args.prefix if prefix is None: prefix = tempfile.mkdtemp() print("Working in directory %s" % prefix) os.chdir(prefix) try: made_pkg = False # Build a package for each distro/spec/arch tuple, and # accumulate the repository-layout directories. for (distro, arch) in packager.crossproduct(distros, args.arches): for build_os in distro.build_os(arch): if build_os in args.distros or not args.distros: filename = tarfile(build_os, arch, spec) packager.ensure_dir(filename) shutil.copyfile(args.tarball, filename) repo = make_package(distro, build_os, arch, spec, srcdir) make_repo(repo, distro, build_os) made_pkg = True if not made_pkg: raise Exception("No valid combination of distro and arch selected") finally: os.chdir(oldcwd)
def make_deb(distro, build_os, arch, spec, srcdir): # I can't remember the details anymore, but the initscript/upstart # job files' names must match the package name in some way; and # see also the --name flag to dh_installinit in the generated # debian/rules file. suffix=spec.suffix() sdir=setupdir(distro, build_os, arch, spec) if re.search("debian", distro.name()): os.link(sdir+"debian/init.d", sdir+"debian/%s%s-server.mongod.init" % (distro.pkgbase(), suffix)) os.unlink(sdir+"debian/mongod.upstart") elif re.search("ubuntu", distro.name()): os.link(sdir+"debian/mongod.upstart", sdir+"debian/%s%s-server.mongod.upstart" % (distro.pkgbase(), suffix)) os.unlink(sdir+"debian/init.d") else: raise Exception("unknown debianoid flavor: not debian or ubuntu?") # Rewrite the control and rules files write_debian_changelog(sdir+"debian/changelog", spec, srcdir) distro_arch=distro.archname(arch) sysassert(["cp", "-v", srcdir+"debian/%s%s.control" % (distro.pkgbase(), suffix), sdir+"debian/control"]) sysassert(["cp", "-v", srcdir+"debian/%s%s.rules" % (distro.pkgbase(), suffix), sdir+"debian/rules"]) # old non-server-package postinst will be hanging around for old versions # if os.path.exists(sdir+"debian/postinst"): os.unlink(sdir+"debian/postinst") # copy our postinst files # sysassert(["sh", "-c", "cp -v \"%sdebian/\"*.postinst \"%sdebian/\""%(srcdir, sdir)]) # Do the packaging. oldcwd=os.getcwd() try: os.chdir(sdir) sysassert(["dpkg-buildpackage", "-a"+distro_arch, "-k Richard Kreuter <*****@*****.**>"]) finally: os.chdir(oldcwd) r=distro.repodir(arch, build_os, spec) ensure_dir(r) # FIXME: see if shutil.copyfile or something can do this without # much pain. sysassert(["sh", "-c", "cp -v \"%s/../\"*.deb \"%s\""%(sdir, r)]) return r
def unpack_binaries_into(build_os, arch, spec, where): """Unpack the tarfile for (build_os, arch, spec) into directory where.""" rootdir=os.getcwd() packager.ensure_dir(where) # Note: POSIX tar doesn't require support for gtar's "-C" option, # and Python's tarfile module prior to Python 2.7 doesn't have the # features to make this detail easy. So we'll just do the dumb # thing and chdir into where and run tar there. os.chdir(where) try: packager.sysassert(["tar", "xvzf", rootdir+"/"+tarfile(build_os, arch, spec)]) release_dir = glob('mongodb-linux-*')[0] for releasefile in "bin", "snmp", "LICENSE.txt", "README", "THIRD-PARTY-NOTICES", "MPL-2": os.rename("%s/%s" % (release_dir, releasefile), releasefile) os.rmdir(release_dir) except Exception: exc=sys.exc_value os.chdir(rootdir) raise exc os.chdir(rootdir)
def make_rpm(distro, build_os, arch, spec, srcdir): # Create the specfile. suffix=spec.suffix() sdir=setupdir(distro, build_os, arch, spec) # Use special suse init script if we're building for SUSE # if distro.name() == "suse": os.unlink(sdir+"rpm/init.d-mongod") os.link(sdir+"rpm/init.d-mongod.suse", sdir+"rpm/init.d-mongod") specfile=srcdir+"rpm/mongodb%s.spec" % suffix topdir=ensure_dir('%s/rpmbuild/%s/' % (os.getcwd(), build_os)) for subdir in ["BUILD", "RPMS", "SOURCES", "SPECS", "SRPMS"]: ensure_dir("%s/%s/" % (topdir, subdir)) distro_arch=distro.archname(arch) # RPM tools take these macro files that define variables in # RPMland. Unfortunately, there's no way to tell RPM tools to use # a given file *in addition* to the files that it would already # load, so we have to figure out what it would normally load, # augment that list, and tell RPM to use the augmented list. To # figure out what macrofiles ordinarily get loaded, older RPM # versions had a parameter called "macrofiles" that could be # extracted from "rpm --showrc". But newer RPM versions don't # have this. To tell RPM what macros to use, older versions of # RPM have a --macros option that doesn't work; on these versions, # you can put a "macrofiles" parameter into an rpmrc file. But # that "macrofiles" setting doesn't do anything for newer RPM # versions, where you have to use the --macros flag instead. And # all of this is to let us do our work with some guarantee that # we're not clobbering anything that doesn't belong to us. Why is # RPM so braindamaged? macrofiles=[l for l in backtick(["rpm", "--showrc"]).split("\n") if l.startswith("macrofiles")] flags=[] macropath=os.getcwd()+"/macros" write_rpm_macros_file(macropath, topdir, distro.release_dist(build_os)) if len(macrofiles)>0: macrofiles=macrofiles[0]+":"+macropath rcfile=os.getcwd()+"/rpmrc" write_rpmrc_file(rcfile, macrofiles) flags=["--rpmrc", rcfile] else: # This hard-coded hooey came from some box running RPM # 4.4.2.3. It may not work over time, but RPM isn't sanely # configurable. flags=["--macros", "/usr/lib/rpm/macros:/usr/lib/rpm/%s-linux/macros:/etc/rpm/macros.*:/etc/rpm/macros:/etc/rpm/%s-linux/macros:~/.rpmmacros:%s" % (distro_arch, distro_arch, macropath)] # Put the specfile and the tar'd up binaries and stuff in # place. FIXME: see if shutil.copyfile can do this without too # much hassle. sysassert(["cp", "-v", specfile, topdir+"SPECS/"]) oldcwd=os.getcwd() os.chdir(sdir+"/../") try: sysassert(["tar", "-cpzf", topdir+"SOURCES/mongodb%s-%s.tar.gz" % (suffix, spec.pversion(distro)), os.path.basename(os.path.dirname(sdir))]) finally: os.chdir(oldcwd) # Do the build. flags.extend(["-D", "dynamic_version " + spec.pversion(distro), "-D", "dynamic_release " + spec.prelease()]) sysassert(["rpmbuild", "-ba", "--target", distro_arch] + flags + ["%s/SPECS/mongodb%s.spec" % (topdir, suffix)]) r=distro.repodir(arch, build_os, spec) ensure_dir(r) # FIXME: see if some combination of shutil.copy<hoohah> and glob # can do this without shelling out. sysassert(["sh", "-c", "cp -v \"%s/RPMS/%s/\"*.rpm \"%s\""%(topdir, distro_arch, r)]) return r