diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | doc/development/versioning.txt | 18 | ||||
-rw-r--r-- | doc/getting_started/macosx/notes.txt | 77 | ||||
-rw-r--r-- | osx/Makefile | 16 | ||||
-rw-r--r-- | src/lib/Environment.py | 37 | ||||
-rwxr-xr-x | tools/export.py | 284 |
6 files changed, 349 insertions, 84 deletions
diff --git a/.gitignore b/.gitignore index d449d8bb4..80cc98761 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ src/Bcfg2 +*.pyc diff --git a/doc/development/versioning.txt b/doc/development/versioning.txt new file mode 100644 index 000000000..e32a361a0 --- /dev/null +++ b/doc/development/versioning.txt @@ -0,0 +1,18 @@ +.. -*- mode: rst -*- + +.. _development-tips: + +Versioning Bcfg2 +---------------- + +#. These are the conventions Bcfg2 has adopted for `versioning`_: + + * The version number will be broken down into Major.Minor.MicroBuild. + * Major and Minor are ever increasing integers. + * Micro is a single digit integer. This is because of limits in some +of the package systems (specifically Mac OS X). + * Build is either missing or refers to release candidates: e.g. +"pre3". + + +.. _versioning: https://secure.wikimedia.org/wikipedia/en/wiki/Software_versioning diff --git a/doc/getting_started/macosx/notes.txt b/doc/getting_started/macosx/notes.txt new file mode 100644 index 000000000..88178fee9 --- /dev/null +++ b/doc/getting_started/macosx/notes.txt @@ -0,0 +1,77 @@ += Setting up Bcfg2 From Scratch = + +Ala [[http://blog.conpocococo.org/post/6079832974/managing-etc-motd-with-bcfg2-starting-from-an-empty-vm|Managing /etc/motd with Bcfg2 Starting From an Empty VM]], I'll be setting up a fresh OS X 10.6 machine to be managed by [[http://bcfg2.org|Bcfg2]]. + +== Get OS X 10.6 Running == + +Use your favorite provisioning method (e.g. open-box-then-push-power-button, DVD, [[http://www.deploystudio.com/Home.html|DeplyStudio]], etc) to get your operating system running and fully patched. + +For this hands on, I'm running OS X 10.6.8 (Build 10K540) with the +supplied python 2.6.1. I've also turned on Remote Login (i.e. ssh) so I +can use my client to write this document going through the steps; having +ssh on is not a requirement for this howto. + +== Get bcfg2-server Working == + +=== Get bcfg2 package === + +You might be able to get a package already built for you, but it is not hard to build it from the source. You'll need git (via [[https://code.google.com/p/git-osx-installer/|git-osx-installer]] or [[https://github.com/mxcl/homebrew|homebrew]] the former is easier, the later more developer friendly) and Apple's [[http://developer.apple.com/xcode/|xcode]]. + +The first step is to clone the bcfg2 repository into a working directory: + +{{{#!highlight bash +cd ~/Devloper +git clone git://git.mcs.anl.gov/bcfg2.git +cd bcfg2 +}}} + +At this point you will probably want to checkout a release tag (`git tag -l` to +see a list of them). This test is using v1.2.0pre4. Once you've done +that you can build the server. + +{{{#!highlight bash +git checkout v1.2.0pre4 +cd osx +make server +}}} + +The server package contains both the client and the server. The package +is located at ./osx/bcfg2-VERSION.pkg. Copy it to the machine you want +to set up from scratch and install it. + +THIS NEEDS TO VERIFIED +Some of the differences between bcfg2 on Mac OS X and Debian is that the +libraries are stored at +`/Library/Frameworks/Python.framework/Versions/Current/share/bcfg2/` +`/Library/Python/site-packages/Bcfg2/` +instead of `/usr/lib/pymodules/` and `/usr/share/pyshare/Bcfg2. Also, +instead of cron and init.d, +`/Library/LaunchDaemons/gov.anl.mcs.bcfg2-daily.plist` controls peridic +runs and starts and stops. The runtime files are stored in +`/usr/local/bin` under Mac OS X instead of /usr/sbin/ for Debian. +VERIFY + +Error: bcfg2-admin init +""" +10.6_client :~ user$ sudo /usr/local/bin/bcfg2-admin init +Failed to import lxml dependency. Shutting down server. +""" + +Try: sudo easy_install lxml. If you don't have gcc-4.2 installed, you'll +need to install it on a machine that does. Then move +`/Library/Python/2.6/sites-packages/lxml-2.3-py2.6-macosx-10.6-universal.egg` +to the client and add the line +"./lxml-2.3-py2.6-macosx-10.6-universal.egg" to +`/Library/Python/2.6/site-packages/easy-install.pth`. + +getting a new error: + +$ sudo /usr/local/bin/bcfg2-admin init +Interactively initialize a new repository. + +bcfg2-admin init +$ + +So what is lxml easy_install fully installing? Need to make a package +(Lettuce to the rescue!) + diff --git a/osx/Makefile b/osx/Makefile index 075628668..a5920a5eb 100644 --- a/osx/Makefile +++ b/osx/Makefile @@ -1,6 +1,6 @@ -PYVERSION := $(shell /usr/bin/python -c "import sys; print sys.version[0:3]") -PYMAJORVERSION := $(shell /usr/bin/python -c "import sys; print sys.version[0:1]") -PYMINORVERSION := $(shell /usr/bin/python -c "import sys; print sys.version[2:3]") +PYVERSION := $(shell /usr/bin/python -c "import sys; print '%s.%s' % (sys.version_info[0], sys.version_info[1])") +PYMAJORVERSION := $(shell /usr/bin/python -c "import sys; print sys.version_info[0]") +PYMINORVERSION := $(shell /usr/bin/python -c "import sys; print sys.version_info[1]") PREFLIGHT = preflight POSTFLIGHT = postflight PKGROOT = bcfg2pkg @@ -29,13 +29,9 @@ SITELIBDIR = /Library/Python/${PYVERSION}/site-packages # an Info.plist file for packagemaker to look at for package creation # and substitute the version strings. Major/Minor versions can only be # integers (e.g. "1" and "00" for bcfg2 version 1.0.0. -BCFGVER = $(shell /usr/bin/grep version ../setup.py | cut -d\" -f2) -BCFGVER1 = $(shell /bin/echo ${BCFGVER} | /usr/bin/cut -d"." -f1) -BCFGVER2 = $(shell /bin/echo ${BCFGVER} | /usr/bin/cut -d"." -f2) -BCFGVER3 = $(shell /bin/echo ${BCFGVER} | /usr/bin/cut -d"." -f3) -BCFGVER3I = $(shell /usr/bin/python -c "import sys; print sys.argv[1][0:1]" ${BCFGVER3}) -MAJOR = ${BCFGVER1} -MINOR = ${BCFGVER2}${BCFGVER3I} +BCFGVER = 1.2.0pre3 +MAJOR = 1 +MINOR = 20 default: clean client diff --git a/src/lib/Environment.py b/src/lib/Environment.py new file mode 100644 index 000000000..782407ee2 --- /dev/null +++ b/src/lib/Environment.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# encoding: utf-8 +""" +Environment.py + +Classes for easy access to python environment information (e.g. python version). +""" + +import sys +import os + +class Pyversion(): + + def __init__(self): + # This is only helpful for Python 2 and older. Python 3 has sys.version_info.major. + [self.major, self.minor, self.micro, self.releaselevel, self.serial] = sys.version_info + self.version = sys.version + self.hex = sys.hexversion + + +def main(): + # test class Pyversion + pyversion = Pyversion() + print "%s : %s" % ("major", pyversion.major) + print "%s : %s" % ("minor", pyversion.minor) + print "%s : %s" % ("micro", pyversion.micro) + print "%s : %s" % ("releaselevel", pyversion.releaselevel) + print "%s : %s" % ("serial", pyversion.serial) + print "%s : %s" % ("version", pyversion.version) + print "%s : %s" % ("hex", pyversion.hex) + + pass + + +if __name__ == '__main__': + main() + diff --git a/tools/export.py b/tools/export.py index 2885625d5..c690ecd73 100755 --- a/tools/export.py +++ b/tools/export.py @@ -1,12 +1,16 @@ #!/usr/bin/env python +# encoding: utf-8 """ -First attempt to make our export script more portable than export.sh +Second attempt to make our export script more portable than export.sh + """ import fileinput from subprocess import Popen, PIPE import sys +# This will need to be replaced with argsparse when we make a 2.7+/3.2+ version +import optparse # py3k compatibility try: @@ -14,22 +18,28 @@ try: except ImportError: from email.utils import formatdate +# In lieu of a config file +help_message = '''This script creates a tag in the Bcfg2 git repo and exports a tar file of the code +at that tag. + +This script must be run at the top of your git repository. +''' + + pkgname = 'bcfg2' ftphost = 'terra.mcs.anl.gov' ftpdir = '/mcs/ftp/pub/bcfg' -# py3k compatibility -try: - version = raw_input("Please enter the version you are tagging (e.g. 1.0.0): ") -except NameError: - version = input("Please enter the version you are tagging (e.g. 1.0.0): ") -tarname = '/tmp/%s-%s.tar.gz' % (pkgname, version) - def run(command): return Popen(command, shell=True, stdout=PIPE).communicate() -def find_and_replace(f, iftest, rline, startswith=False): - for line in fileinput.input(f, inplace=1): +def find_and_replace(f, iftest, rline, startswith=False, dryrun=False): + if dryrun: + inplace=0 + print "*** dry-run: New '%s' will look like this:" % f + else: + inplace=1 + for line in fileinput.input(f, inplace): if startswith: if line.startswith(iftest): line = line.replace(line, rline) @@ -38,74 +48,200 @@ def find_and_replace(f, iftest, rline, startswith=False): if iftest in line and line != "Version: %{version}\n": line = line.replace(line, rline) sys.stdout.write(line) + if dryrun: + print "*** End '%s'" % f -# update the version -majorver = version[:5] -minorver = version[5:] -# py3k compatibility -try: - name = raw_input("Your name: ") - email = raw_input("Your email: ") -except NameError: - name = input("Your name: ") - email = input("Your email: ") -newchangelog = \ +def main(argv=None): + # This is where the options are set up + p = optparse.OptionParser(description = help_message, + prog = 'export2.py', + version = '0.1', + usage = '%prog [-h|--help] [-v|--version] [-n|--dry-run] [-d|--debug]') + p.add_option('--verbose', '-v', + action = 'store_true', + help = 'turns on verbose mode', + default = False, + dest = 'verbose') + p.add_option('--dry-run', '-n', + action = 'store_true', + help = 'run in dry-run mode; no changes will be made to the system', + default = False, + dest = 'dryrun') + p.add_option('--debug', '-d', + action = 'store_true', + help = 'run in debun mode', + default = False, + dest = 'debug') + p.add_option('--paranoid', '-P', + action = 'store_true', + help = 'run in paranoid mode, make changes but do not commit to repository', + default = False, + dest = 'paranoid') + options, arguments = p.parse_args() + + if options.debug: + print options + print "What should debug mode do?" + + # py3k compatibility + try: + version = raw_input("Please enter the Bcfg2 version you are tagging (e.g. 1.0.0): ") + name = raw_input("Your name: ") + email = raw_input("Your email: ") + except NameError: + version = input("Please enter the Bcfg2 version you are tagging (e.g. 1.0.0): ") + name = input("Your name: ") + email = input("Your email: ") + + # parse version into Major.Minor.MicroBuild and validate + vkeys = ["major", "minor", "microbuild"] + try: + version_info = dict(zip(vkeys,version.split("."))) + version_info["micro"] = version_info["microbuild"][0:1] + version_info["build"] = version_info["microbuild"][1:] + version_release = "%s.%s.%s" % (version_info['major'], version_info['minor'], version_info['micro']) + + if options.debug: + print "version is %s" % version + print "version_info is %s" % version_info + print "version_release is %s" % version_release + + if not version_info["major"].isdigit() or not version_info["minor"].isdigit() or not version_info["micro"]: + raise VersionError('isdigit() test failed') + if len(version_info["micro"]) > 1: + raise VersionError('micro must be single digit because IFMinorVersion restrictions in Mac OS X Packaging') + except: + print """Version must be of the form Major.Minor.MicroBuild, +where Major and Minor are integers and +Micro is a single digit optionally followed by Build (i.e. pre##) +E.G. 1.2.0pre1 is a valid version. +""" + quit() + + + tarname = '/tmp/%s-%s.tar.gz' % (pkgname, version) + + newchangelog = \ """bcfg2 (%s%s-0.0) unstable; urgency=low * New upstream release -- %s <%s> %s -""" % (majorver, minorver, name, email, formatdate(localtime=True)) -# write out the new debian changelog -with open('debian/changelog', 'r+') as f: - old = f.read() - f.seek(0) - f.write(newchangelog + old) -f.close() -# Update redhat directory versions -with open('redhat/VERSION', 'w') as f: - f.write("%s\n" % majorver) -f.close() -with open('redhat/RELEASE', 'w') as f: - f.write("0.0%s\n" % minorver) -f.close() -# update solaris version -find_and_replace('solaris/Makefile', 'VERS=', - 'VERS=%s-1\n' % version, startswith=True) -find_and_replace('solaris/pkginfo.bcfg2', 'VERSION=', - 'VERSION="%s"\n' % version, startswith=True) -find_and_replace('solaris/pkginfo.bcfg2-server', 'VERSION=', - 'VERSION="%s"\n' % version, startswith=True) -# set new version in setup.py -find_and_replace('setup.py', 'version=', ' version="%s",\n' % version) -# replace version in misc/bcfg2.spec -find_and_replace('misc/bcfg2.spec', 'Version:', - 'Version: %s\n' % version) -# update the version in reports -find_and_replace('src/lib/Server/Reports/reports/templates/base.html', - 'Bcfg2 Version', ' <span>Bcfg2 Version %s</span>\n' % version) -# update the version in the docs -find_and_replace('doc/conf.py', 'version =', - 'version = \'%s\'\n' % majorver[0:3], startswith=True) -find_and_replace('doc/conf.py', 'release =', - 'release = \'%s\'\n' % (majorver), startswith=True) - -# tag the release -#FIXME: do this using python-dulwich -cmd = "git commit -asm 'Version bump to %s'" % version -output = run(cmd)[0].strip() -# NOTE: This will use the default email address key. If you want to sign the tag -# using a different key, you will need to set 'signingkey' to the proper -# value in the [user] section of your git configuration. -cmd = "git tag -s v%s -m 'tagged %s release'" % (version, version) -output = run(cmd)[0].strip() -cmd = "git archive --format=tar --prefix=%s-%s/ v%s | gzip > %s" % \ - (pkgname, version, version, tarname) -output = run(cmd)[0].strip() -cmd = "gpg --armor --output %s.gpg --detach-sig %s" % (tarname, tarname) -output = run(cmd)[0].strip() - -# upload release to ftp -cmd = "scp %s* terra.mcs.anl.gov:/mcs/ftp/pub/bcfg/" % tarname -output = run(cmd)[0].strip() +""" % (version_release, version_info['build'], name, email, formatdate(localtime=True)) + + + # write out the new debian changelog + if options.dryrun: + print "*** Add the following to the top of debian/changelog:\n%s" % newchangelog + print "\n" + else: + try: + with open('debian/changelog', 'r+') as f: + old = f.read() + f.seek(0) + f.write(newchangelog + old) + f.close() + except: + print "Problem opening debian/changelog" + print help_message + quit() + + # Update redhat directory versions + if options.dryrun: + print "*** Replace redhat/VERIONS content with '%s'." % version_release + print "*** Replace redhat/RELEASE content with '%s'." % version_info['build'] + else: + with open('redhat/VERSION', 'w') as f: + f.write("%s\n" % version_release) + f.close() + with open('redhat/RELEASE', 'w') as f: + f.write("0.0%s\n" % version_info['build']) + f.close() + + # update solaris version + find_and_replace('solaris/Makefile', 'VERS=', + 'VERS=%s-1\n' % version, + startswith=True, + dryrun=options.dryrun) + find_and_replace('solaris/pkginfo.bcfg2', 'VERSION=', + 'VERSION="%s"\n' % version, + startswith=True, + dryrun=options.dryrun) + find_and_replace('solaris/pkginfo.bcfg2-server', 'VERSION=', + 'VERSION="%s"\n' % version, + startswith=True, + dryrun=options.dryrun) + # set new version in setup.py + find_and_replace('setup.py', 'version=', ' version="%s",\n' % version, + dryrun=options.dryrun) + # replace version in misc/bcfg2.spec + find_and_replace('misc/bcfg2.spec', 'Version:', + 'Version: %s\n' % version, + dryrun=options.dryrun) + # update the version in reports + find_and_replace('src/lib/Server/Reports/reports/templates/base.html', + 'Bcfg2 Version', ' <span>Bcfg2 Version %s</span>\n' % version, + dryrun=options.dryrun) + # update the version in the docs + find_and_replace('doc/conf.py', 'version =', + 'version = \'%s.%s\'\n' % (version_info['major'], version_info['minor']), + startswith=True, + dryrun=options.dryrun) + find_and_replace('doc/conf.py', 'release =', + 'release = \'%s\'\n' % (version_release), + startswith=True, + dryrun=options.dryrun) + # update osx Makefile + find_and_replace('osx/Makefile', 'BCFGVER =', + 'BCFGVER = %s\n' % (version), + startswith=True, + dryrun=options.dryrun) + find_and_replace('osx/Makefile', 'MAJOR =', + 'MAJOR = %s\n' % (version_info['major']), + startswith=True, + dryrun=options.dryrun) + find_and_replace('osx/Makefile', 'MINOR =', + 'MINOR = %s%s\n' % (version_info['minor'], version_info['micro']), + startswith=True, + dryrun=options.dryrun) + + # tag the release + #FIXME: do this using python-dulwich + commando = {} + + commando["vcs_diff"] = "git diff" + + commando["vcs_commit"] = "git commit -asm 'Version bump to %s'" % version + + # NOTE: This will use the default email address key. If you want to sign the tag + # using a different key, you will need to set 'signingkey' to the proper + # value in the [user] section of your git configuration. + commando["vcs_tag"] = "git tag -s v%s -m 'tagged %s release'" % (version, version) + + commando["create_archive"] = "git archive --format=tar --prefix=%s-%s/ v%s | gzip > %s" % \ + (pkgname, version, version, tarname) + + commando["gpg_encrypt"] = "gpg --armor --output %s.gpg --detach-sig %s" % (tarname, tarname) + + # upload release to ftp + commando["scp_archive"] = "scp %s* terra.mcs.anl.gov:/mcs/ftp/pub/bcfg/" % tarname + + # Execute the commands + if options.paranoid: + commando_orders = ["vcs_diff"] + else: + commando_orders = ["vcs_commit","vcs_tag","create_archive","gpg_encrypt","scp_archive"] + + if options.dryrun: + for cmd in commando_orders: + print "*** dry-run: %s" % commando[cmd] + else: + for cmd in commando_orders: + output = run(commando[cmd])[0].strip() + if options.verbose: + print output + print "Ran '%s' with above output." % cmd + +if __name__ == '__main__': + sys.exit(main()) |