Developers documentation

Limitations

  • It’s not possible to use collective.recipe.patch recipe. First of all it doesn’t use zc.recipe.egg recipe for installing eggs, and doesn’t support buildout:shared-eggs-directory. Second if package already exist in shared directory, collective.recipe.patch won’t able to patch it because of system permissions.
  • Any recipe that doesn’t use zc.recipe.egg for installing additional eggs won’t work with deb/rpm building process.

Requirenments

  • init.d rc script for each service (i.e. zeo, instances, etc):

    [zeo-rc]
    recipe = zc.recipe.rhrc
    parts = zeo
    chkconfig = 345 90 10
    chkconfigcommand = echo
    user = plone
    dest = ${buildout:directory}/bin
    
    [instance-rc]
    recipe = zc.recipe.rhrc
    parts = instance
    chkconfig = 345 90 10
    chkconfigcommand = echo
    user = plone
    dest = ${buildout:directory}/bin
  • logrotate configuration for application. buildbout config:

    [logrotate]
    recipe = collective.recipe.template
    input = logrotate.conf.tmpl
    output = parts/logrotate.conf
    

    logrotate.conf.tmpl template example:

    rotate 4
    weekly
    create
    compress
    delaycompress
    
    ${buildout:directory}/var/log/zeo.log
    ${buildout:directory}/var/log/instance.log ${buildout:directory}/var/log/instance-Z2.log
    ${buildout:directory}/var/log/instance2.log ${buildout:directory}/var/log/instance2-Z2.log
    {
        sharedscripts
        postrotate
        /bin/kill -USR2 $(cat ${buildout:directory}/var/zeo.pid)
        /bin/kill -USR2 $(cat ${buildout:directory}/var/instance.pid)
        /bin/kill -USR2 $(cat ${buildout:directory}/var/instance2.pid)
        endscript
     }
  • Buildout should not use development packages

  • Use eggs for eggs-directory:

    buildout:eggs-directory=eggs
  • “PIL” should be placed in dependencies:

    buildout:eggs += PIL
  • zc.buildout and zc.recipe.egg should be pinned:

    [versions]
    zc.buildout = 1.4.4
    zc.recipe.egg = 1.2.2
  • Use zope as effective user for zope/zeo instances.

    For zope isntance recipe:

    [instance]
    recipe = plone.recipe.zope2instance
    effective-user = zope
    

    For zeo instance recipe:

    [zeo]
    recipe = plone.recipe.zeoserver
    effective-user = zope
    

Building

In general case customer configuration should extend /usr/lib/plone40/versions.cfg. This file contains versions for plone4.0.1 and zope2.12.12 (depends on plone40-base package). Also there is no need to use bootstrap.py, use buildout script from plone40-base deb/rpm. For example if production configuration located in production.cfg file, building command will look like this:

>> /usr/lib/plone40/buildout -c production.cfg

This command uses patched zc.buildout and supports additional buildout setting buildout:shared-eggs-directory, so it looks like this:

>> /usr/lib/plone40/buildout -c production.cfg buildout:shared-eggs-directory=/usr/lib/plone40/eggs

Project has to be build with /usr/lib/plone40/buildout, because this command is used for building deb/rpm.

Developer has to select directory where customer application will be located on production server. And build should be able to build in this directory. For example developer can select directory /opt/customer-intranet for customer application. So building script should look like this:

>> mkdir -p /opt/customer-intranet
>> cp -ap ./*.cfg /opt/customer-intranet
>> cp -ap ./logrotate.conf.tmpl /opt/customer-intranet
>> cd /opt/customer-intranet
>> /usr/lib/plone40/buildout -c production.cfg

Main idea is, all generated scripts and configuration file have to contain right paths. And all deleloper has to do is just copy /opt/customer-intranet directory to customer production server and it should work out of box.

Building Debian package

debian-simple contains sample debian configuration for project with one instance. Copy to this directory to customer buildout directory as debian directory.

Files descriptions:

  • README.Debian - just general description, can be skipped

  • README.source - original source of code description, can be skipped

  • changelog - this is way to control debian package version, cannot be skipped:

    customer-intranet (1.0-2) stable; urgency=low
    • customer-intranet - package name
    • 1.0-2 - package version * 1.0 - application version, change this if application is changed * 2 - package version, change this if debian configuration is changed
    • stable; urgency=low - there is no reason to change this part of line, just leave it same.
  • compat - debian internal compatibility, do not change this file.

  • control - control file, contains package name, os level dependencies (dependencies to other debian packages)

    Developer can change Source and Package to customer specific name, other fields in most cases do not require any changes.

    • Source - package name for source package
    • Build-Depends - os level dependencies, should always contains plone core dependecy (plone40-base or plone33-base)
    • Package - binary package name
    • Depends - os level dependencies, should always depends on plone core package.
  • copyright - put here customer copyright

  • postinst - script executes by dpkg manager after pacakge instalation. check script comments for details

  • prerm - script executes by dpkg manager before removing check script comments for details

  • rules - Make file for building deb package

    PACKAGE - customer specific name, usually it is same as package name, also this name is used as directory name for instalation.

    Most importand parts:

    • build:

      • Developer should create destination directory, i.e. /opt/customer-intranet
      • Copy all configuration files that are required by buildout
      • Run buildout to build customer application

      Example:

      build:
          mkdir -p /opt/customer-intranet
          cp -ap ./*.cfg /opt/customer-intranet
          cp -ap ./logrotate.conf.tmpl /opt/customer-intranet
          cd /opt/customer-intranet && /usr/lib/plone40/buildout -c production.cfg
    • install:

      Develper has to create destination directory and copy all required files from building directory to debian temporary directory so debian package builder can pack all files into deb file

      Example:

      install:
           # this spets are required, do not change
           rm -rdf $(DEBIAN)
           dh_testdir
           dh_testroot
           dh_clean -k -s
           dh_installdirs -s
      
           # create destination directory in debian location
           mkdir -p $(DEBIAN)/opt/$(PACKAGE)
      
           # copy generated scripts, config files and custom eggs to deb
           cp -ap $(BUILDDIR)/bin $(DEBIAN)/opt/$(PACKAGE)/
           cp -ap $(BUILDDIR)/eggs $(DEBIAN)/opt/$(PACKAGE)/
           cp -ap $(BUILDDIR)/parts $(DEBIAN)/opt/$(PACKAGE)/
      
           # remove build directory, optional
           rm -rf $(BUILDDIR)/

Debian configuration samples

This documentation contains example debian configuration.

  • debian-simple.tar.gz contains sample debian configuration for project with one zope instances. Check postinst and prerm scripts comments for more details.
  • debian-multi.tar.gz contains sample debian configuration for project with one zeo instance and 2 zope instances. Check postinst and prerm scripts comments for more details.

Building RPM package

rpm.tar.gz file contains sample spec file for plone4 instance with one instance. It is very similar to debian-simple but all files packed to one spec file.

Name: customer-intranet
package name, developer has to change this to customer specific name
Version: 1.0
application version number, it is used as package major version
Revision: 1
spec file revision, it is used as package minor version
BuildRequires: plone40-base
os level dependencies, package has to depend on plone core package
Requires: plone40-base >= 4.0.0
os level dependencies, package has to depend on plone core package

%build - build section, same as build: section in debian rules file

%install - install section, same as install: section in debian rules file

%post - post install script, same as postinst script in debian directory

%preun - before removing script, same as prerm script in debian directory

Signing

All rpm’s have to be signed. rpm singing is manual process.:

>> rpm --addsign clients/customer/staging/i386/name-1.0-1.i386.rpm
>> createrepo clients/customer/staging/i386/

Plone core package utils

Plone core package contains two utilities for creating site and upgrading packages in existing plone sites.

  • /usr/lib/plone40/utils/createsite.py

    To run this script use instance script, example:

    >> /opt/customer/bin/instance run /usr/lib/plone40/utils/createsite.py Plone username package1:default,package2:default
    • Plone - plone object name

    • username - username for plone object owner, developer should use instance:user for username.

    • package1:default,package2:default - comma separated list of generic setup profiles to install on new plone site, for example:

      plonetheme.classic:default,plonetheme.sunburst:default
  • /usr/lib/plone40/utils/upgradeapp.py

    Use this script to upgrade generic setup profiles in existing pline site. To run this script use instance script, example:

    >> /opt/customer/bin/instance run /usr/lib/plone40/utils/upgradeapp.py Plone username package1:default,package2:default
    • Plone - plone object name
    • username - existing username
    • package1:default,package2:default - comma separated list of generic setup profiles to upgrade

Plone3 core package contains same scripts they are located in /usr/lib/plone3/utils directory.



blog comments powered by Disqus