SlideShare a Scribd company logo
Reaching
Deployment Nirvana
  Using Buildout
        Clayton Parker
    Plone Conference 2008




             nowhere to go but
            open source
       s ix fe e tup . c om / dw 0 8
Here’s to Plone




                  si xf eet up .co m /dw 0 8
To-do List
•   Buildout
    •   Parts
    •   Recipes
    •   Command Line
•   ZopeSkel
    •   Create Buildouts
    •   Custom Recipes


                           si xf eet up .co m /dw 0 8
Why buildout?




                si xf eet up .co m /dw 0 8
Eliminate Confusion




                      si xf eet up .co m /dw 0 8
Tracking Dependencies




                        si xf eet up .co m /dw 0 8
Roll Your Own


•   Installer
•   ZopeSkel




                si xf eet up .co m /dw 0 8
ZopeSkel

 $ easy_install ZopeSkel
 $ paster create --list-templates
 plone3_buildout:    A buildout for Plone 3 projects
 $ paster create -t plone3_buildout mybuildout




                                                  si xf eet up .co m /dw 0 8
Lingo


  si xf eet up .co m /dw 0 8
Syntax
   [buildout]
   parts =
       zope2
       plone
       instance

   [plone]
   recipe = plone.recipe.plone

   [zope2]
   recipe = plone.recipe.zope2install

   [instance]
   recipe = plone.recipe.zope2instance
   user = admin:admin
   eggs = ${plone:eggs}
   products = ${plone:products}
                                         si xf eet up .co m /dw 0 8
Advanced Syntax
  Variable Substitution
     ${part:option}

     ${plone:eggs}
     ${buildout:directory}
     option = ${buildout:directory}/somefolder


  Option Addition and Removal
     options = foo bar

     options += baz
     options -= foo

                                                 si xf eet up .co m /dw 0 8
Reserved Characters


        :$ % { }


                      si xf eet up .co m /dw 0 8
Parts


        si xf eet up .co m /dw 0 8
[buildout]
parts =
    instance

[instance]
recipe = plone.recipe.zope2instance
user = admin:admin
eggs = ${plone:eggs} archetypes.schemaextender
zcml = archetypes.schemaextender
products = ${plone:products}
environment-vars =
    TZ America/Chicago
http-address = 51060
zeo-address = 53060
debug-mode = on
verbose-security = on
event-log-level = debug


                                                 si xf eet up .co m /dw 0 8
Recipes


          si xf eet up .co m /dw 0 8
[buildout]
parts =
    zope2
    plone
    instance

[plone]
recipe = plone.recipe.plone

[zope2]
recipe = plone.recipe.zope2install

[instance]
recipe = plone.recipe.zope2instance
user = admin:admin
eggs = ${plone:eggs}
products = ${plone:products}


                                      si xf eet up .co m /dw 0 8
Buildout Directory
•   bin/
•   bootstrap.py
•   buildout.cfg
•   develop-eggs/
•   downloads/
•   eggs/
•   parts/
•   products/
•   src/             si xf eet up .co m /dw 0 8
Buildout options
•   bin-directory
•   develop-eggs-directory
•   eggs-directory
•   parts
•   parts-directory
•   log-level


                             si xf eet up .co m /dw 0 8
Defaults

 [buildout]
 eggs-directory = /home/clayton/.buildout/eggs
 download-cache = /home/clayton/.buildout/downloads
 zope-directory = /home/clayton/.buildout/zope
 index = http://download.zope.org/ppix

 [instance]
 event-log-level = debug




                                                      si xf eet up .co m /dw 0 8
Recipes


   si xf eet up .co m /dw 0 8
Plone Recipes

•   plone.recipe.plone
•   plone.recipe.zope2install
•   plone.recipe.zope2instance
•   plone.recipe.squid




                                 si xf eet up .co m /dw 0 8
plone.recipe.zope2install

    [zope2]
    recipe = plone.recipe.zope2install
    url = ${plone:zope2-url}
    fake-zope-eggs = true
    additional-fake-eggs = ZODB3
    skip-fake-eggs =
        zope.testing
        zope.component
        zope.i18n




                                         si xf eet up .co m /dw 0 8
In The Wild




              si xf eet up .co m /dw 0 8
Extending Configuration
•   buildout.cfg
•   profiles/
    •   base.cfg
    •   development.cfg
    •   debug.cfg
    •   qa.cfg
    •   prod.cfg
    •   versions.cfg
                          si xf eet up .co m /dw 0 8
buildout.cfg
    [buildout]
    # the profile we want to use
    extends = profiles/development.cfg

    find-links =
        http://dist.plone.org
        http://download.zope.org/distribution/
        http://effbot.org/downloads




                                                 si xf eet up .co m /dw 0 8
base.cfg
 [buildout]
 parts =
     PILwoTK
     plone
     zope2
     instance
     zeoserver
 develop = src/my.package

 [PILwoTK]
 recipe = zc.recipe.egg
 find-links = http://download.zope.org/distribution/

 [zope2]
 recipe = plone.recipe.zope2install
 url = ${plone:zope2-url}
 fake-zope-eggs = true
 additional-fake-eggs = ZODB3
 skip-fake-eggs = zope.testing zope.component zope.i18n


                                                          si xf eet up .co m /dw 0 8
[plone]
recipe = plone.recipe.plone

[instance]
recipe = plone.recipe.zope2instance
zeo-client = True
zope2-location = ${zope2:location}
eggs =
    PILwoTK
    elementtree
    ${plone:eggs}
    my.package
zcml = my.package
products = ${plone:products}
environment-vars =
    TZ America/New_York

[zeoserver]
recipe = plone.recipe.zope2zeoserver
zope2-location = ${instance:zope2-location}
zeo-address = ${instance:zeo-address}


                                              si xf eet up .co m /dw 0 8
development.cfg
   [buildout]
   extends =
       base.cfg
       debug.cfg
   parts += ${debugging:parts} omelette

   [instance]
   user = admin:admin
   http-address = 8080
   zeo-address = 8100
   debug-mode = on
   verbose-security = on
   event-log-level = debug
   products +=
       ${buildout:directory}/products
       ${debugging:debug-products}
   eggs += ${debugging:eggs}
   zcml += ${debugging:zcml}

   [omelette]
   recipe = collective.recipe.omelette
   eggs = ${instance:eggs}
   ignore-develop = True
                                          si xf eet up .co m /dw 0 8
   ignores = setuptools
debug.cfg
 [debugging]
 parts =
     debug-products
     debug-products-svn
     ipzope
     zopepy
 debug-products =
     ${debug-products:location}
 eggs =
     plone.reload
     Products.PDBDebugMode
     Products.DocFinderTab
     Products.Clouseau
     Products.PrintingMailHost
 zcml =
     plone.reload

                                  si xf eet up .co m /dw 0 8
[debug-products]
recipe = plone.recipe.distros
urls =
    ...dcworkflowgraph-0_3.tgz
    ...PTProfiler-1.2.tgz

[ipzope]
recipe = zc.recipe.egg
eggs = ipython ${instance:eggs}
initialization =
    import sys, os
    os.environ[quot;SOFTWARE_HOMEquot;] = quot;${instance:zope2-location}/lib/
pythonquot;
    os.environ[quot;INSTANCE_HOMEquot;] = quot;${instance:location}quot;
    sys.argv[1:1] = quot;-p zopequot;.split()
extra-paths = ${instance:zope2-location}/lib/python
scripts = ipython=ipzope

[zopepy]
recipe = zc.recipe.egg
eggs = ${instance:eggs}
interpreter = zopepy
extra-paths = ${instance:zope2-location}/lib/python    si xf eet up .co m /dw 0 8

scripts = zopepy
versions.cfg
[versions]
# Use the following from the command line to get the latest versions:
# bin/buildout -vvvvv |sed -ne 's/^Picked: //p' | sort | uniq
PILwoTk = 1.1.6.4
elementtree = 1.2.7-20070827-preview
infrae.subversion = 1.1
plone.recipe.distros = 1.3
plone.recipe.plone = 3.1.6
plone.recipe.zope2install = 2.3
plone.recipe.zope2instance = 2.5
plone.recipe.zope2zeoserver = 0.13
python-openid = 2.2.1
my.package = 1.0



                                                        si xf eet up .co m /dw 0 8
prod.cfg
    [buildout]
    extends = base.cfg versions.cfg
    parts += instance2
    versions = versions

    [instance]
    zope2-location = ${zope2:location}
    http-address = 9080
    zeo-address = 9100
    eggs += Products.CacheSetup
    z2-log-level = CRITICAL
    zodb-cache-size = 15000

    [instance2]
    recipe = collective.recipe.zope2cluster
    instance-clone = instance
    http-address = 10080
                                              si xf eet up .co m /dw 0 8
Command Line




               si xf eet up .co m /dw 0 8
Baby Steps
  $ cd path/to/mybuildout

  $ python2.4 bootstrap.py
  Creating directory 'mybuildout/bin'.
  Creating directory 'mybuildout/parts'.
  Creating directory 'mybuildout/develop-eggs'.
  Generated script 'mybuildout/bin/buildout'.

  $ bin/buildout

  $ bin/instance start




                                                  si xf eet up .co m /dw 0 8
Options
•   -v and -q
    •    increase and decrease verbosity
•   -n and -N
    •    Newest and non-newest modes
•   -O and -o
    •    online and offline mode
•   -t
    •    socket timeout
                                           si xf eet up .co m /dw 0 8
Update your buildout

   $ bin/buildout -v

   $ bin/buildout -Nvvv

   $ bin/buildout -No

   $ bin/buildout -t 60




                          si xf eet up .co m /dw 0 8
Assignments

   $ bin/buildout instance:debug-mode=on

   $ bin/buildout buildout:log-level=70

   $ bin/buildout -N instance:debug-mode=on -v




                                                 si xf eet up .co m /dw 0 8
Commands

  $ bin/buildout install

  $ bin/buildout -Nv install zope2 instance

  $ bin/buildout -nv install instance




                                              si xf eet up .co m /dw 0 8
Create Recipes


   $ paster create -t recipe my.recipe.example




                                                 si xf eet up .co m /dw 0 8
Recipe
•   Recipe class
•   constructor
•   install
•   update
•   uninstall (optional)



                           si xf eet up .co m /dw 0 8
class Recipe:
    quot;quot;quot;quot;A recipe
    quot;quot;quot;quot;
    def __init__(self, buildout, name, options):
         self.buildout = buildout
         self.name = name
         self.options = options
         # gather options from other parts here
         options['notmine'] = buildout['someotherpart']['foobar']

    def install(self):
        quot;quot;quot;quot;Install method
        quot;quot;quot;
        options = self.options
        location = options['location']
        # must return a string, or an iterable of strings
        return location

    def update(self):
        quot;quot;quot;Update method
        quot;quot;quot;
        pass
                                                        si xf eet up .co m /dw 0 8
class Recipe:

  Real World
    quot;quot;quot;infrae.subversion recipe.
    quot;quot;quot;

    def __init__(self, buildout, name, options):
        self.buildout = buildout
        self.name = name
        self.options = options

        options['location'] = self.location = os.path.join(
            buildout['buildout']['parts-directory'], self.name)
        self.urls = [l.split()
                     for l in options['urls'].splitlines()
                     if l.strip()]
        self.export = options.get('export')
        self.newest = (
            buildout['buildout'].get('offline', 'false') == 'false'
            and
            buildout['buildout'].get('newest', 'true') == 'true'
            )
        self.verbose = buildout['buildout'].get('verbosity', 0)
                                                        si xf eet up .co m /dw 0 8
Install Method
def install(self):
        quot;quot;quot;Checkout the checkouts.
        quot;quot;quot;
        for (url, name) in self.urls:
            wc = py.path.svnwc(self.location).join(name)
            if self.export:
                raise Exception('Unimplemented feature')
            if self.verbose:
                print quot;Fetch %squot; % url
            wc.checkout(url)
        return self.location




                                                   si xf eet up .co m /dw 0 8
def update(self):
    quot;quot;quot;Update the checkoutsquot;quot;quot;
    if not self.newest:
        return self.location
    if self.export:
        return self.location
    if self.options.get('ignore_updates', False):
        return self.location
    num_release = re.compile('.*@[0-9]+$')
    part = py.path.local(self.location)
    for link, sub_path in self.urls:
        if num_release.match(link):
            if self.verbose:
                print quot;Given num release for %s, skipping.quot; % link
            continue
        wc = py.path.svnwc(self.location).join(sub_path)
        if self.verbose:
            print quot;Updating %squot; % link
        wc.update()
    return self.location

                                                      si xf eet up .co m /dw 0 8
Wrapping Up
•   Buildout
    •   Parts
    •   Recipes
    •   Command Line
•   ZopeSkel
    •   Create Buildouts
    •   Custom Recipes


                           si xf eet up .co m /dw 0 8
Plone Deployment Workshop




  sixfeetup.com/dw08
      Register by October 17
          and save $100!
Links
•   http://buildout.zope.org
•   http://pypi.python.org/pypi/zc.buildout
•   https://svn.sixfeetup.com/svn/public/buildout/debug.cfg
•   http://www.sixfeetup.com/swag/buildout-quick-reference-card
•   http://plone.org/documentation/tutorial/buildout
•   http://pypi.python.org



                                                       si xf eet up .co m /dw 0 8
Photo Credits
•   http://flickr.com/photos/monsieurlam/2645956083/
•   http://flickr.com/photos/_boris/2796908072/
•   http://flickr.com/photos/b-tal/163450213/
•   http://flickr.com/photos/bullish1974/2648544508/
•   http://flickr.com/photos/haydnseek/87432002/
•   http://flickr.com/photos/disowned/1158260369/
•   http://flickr.com/photos/7603557@N08/2662531345/
•   http://flickr.com/photos/julishannon/2151986631/
•   http://flickr.com/photos/julishannon/2152778524/
•   http://flickr.com/photos/lollyknit/1155225799/
•   http://flickr.com/photos/binary_koala/86227485/




                                                      si xf eet up .co m /dw 0 8

More Related Content

More from Clayton Parker

Current State of Python Packaging
Current State of Python PackagingCurrent State of Python Packaging
Current State of Python Packaging
Clayton Parker
 
Notre Dame Seamless Syndication with Lineage
Notre Dame Seamless Syndication with LineageNotre Dame Seamless Syndication with Lineage
Notre Dame Seamless Syndication with Lineage
Clayton Parker
 
Pioneer a Strategic Change in Content Organization with Plone
Pioneer a Strategic Change in Content Organization with PlonePioneer a Strategic Change in Content Organization with Plone
Pioneer a Strategic Change in Content Organization with Plone
Clayton Parker
 
Using Buildout, GenericSetup and a Policy Package to Rule the World
Using Buildout, GenericSetup and a Policy Package to Rule the WorldUsing Buildout, GenericSetup and a Policy Package to Rule the World
Using Buildout, GenericSetup and a Policy Package to Rule the World
Clayton Parker
 
Make Plone Search Act Like Google Using Solr
Make Plone Search Act Like Google Using SolrMake Plone Search Act Like Google Using Solr
Make Plone Search Act Like Google Using Solr
Clayton Parker
 
Migrating from drupal to plone with transmogrifier
Migrating from drupal to plone with transmogrifierMigrating from drupal to plone with transmogrifier
Migrating from drupal to plone with transmogrifier
Clayton Parker
 
Buildout for the Future
Buildout for the FutureBuildout for the Future
Buildout for the Future
Clayton Parker
 
Buildout future
Buildout futureBuildout future
Buildout future
Clayton Parker
 
Laying Pipe with Transmogrifier
Laying Pipe with TransmogrifierLaying Pipe with Transmogrifier
Laying Pipe with Transmogrifier
Clayton Parker
 
LDAP and Active Directory Authentication in Plone
LDAP and Active Directory Authentication in PloneLDAP and Active Directory Authentication in Plone
LDAP and Active Directory Authentication in Plone
Clayton Parker
 
Code with Style - PyOhio
Code with Style - PyOhioCode with Style - PyOhio
Code with Style - PyOhio
Clayton Parker
 
Code with style
Code with styleCode with style
Code with style
Clayton Parker
 
Using Buildout to Develop and Deploy Python Projects
Using Buildout to Develop and Deploy Python ProjectsUsing Buildout to Develop and Deploy Python Projects
Using Buildout to Develop and Deploy Python Projects
Clayton Parker
 
Generic Setup De-Mystified
Generic Setup De-MystifiedGeneric Setup De-Mystified
Generic Setup De-Mystified
Clayton Parker
 
Buildout: Fostering Repeatability
Buildout: Fostering RepeatabilityBuildout: Fostering Repeatability
Buildout: Fostering Repeatability
Clayton Parker
 
Getting Plone Ready For The Prom
Getting Plone Ready For The PromGetting Plone Ready For The Prom
Getting Plone Ready For The Prom
Clayton Parker
 

More from Clayton Parker (16)

Current State of Python Packaging
Current State of Python PackagingCurrent State of Python Packaging
Current State of Python Packaging
 
Notre Dame Seamless Syndication with Lineage
Notre Dame Seamless Syndication with LineageNotre Dame Seamless Syndication with Lineage
Notre Dame Seamless Syndication with Lineage
 
Pioneer a Strategic Change in Content Organization with Plone
Pioneer a Strategic Change in Content Organization with PlonePioneer a Strategic Change in Content Organization with Plone
Pioneer a Strategic Change in Content Organization with Plone
 
Using Buildout, GenericSetup and a Policy Package to Rule the World
Using Buildout, GenericSetup and a Policy Package to Rule the WorldUsing Buildout, GenericSetup and a Policy Package to Rule the World
Using Buildout, GenericSetup and a Policy Package to Rule the World
 
Make Plone Search Act Like Google Using Solr
Make Plone Search Act Like Google Using SolrMake Plone Search Act Like Google Using Solr
Make Plone Search Act Like Google Using Solr
 
Migrating from drupal to plone with transmogrifier
Migrating from drupal to plone with transmogrifierMigrating from drupal to plone with transmogrifier
Migrating from drupal to plone with transmogrifier
 
Buildout for the Future
Buildout for the FutureBuildout for the Future
Buildout for the Future
 
Buildout future
Buildout futureBuildout future
Buildout future
 
Laying Pipe with Transmogrifier
Laying Pipe with TransmogrifierLaying Pipe with Transmogrifier
Laying Pipe with Transmogrifier
 
LDAP and Active Directory Authentication in Plone
LDAP and Active Directory Authentication in PloneLDAP and Active Directory Authentication in Plone
LDAP and Active Directory Authentication in Plone
 
Code with Style - PyOhio
Code with Style - PyOhioCode with Style - PyOhio
Code with Style - PyOhio
 
Code with style
Code with styleCode with style
Code with style
 
Using Buildout to Develop and Deploy Python Projects
Using Buildout to Develop and Deploy Python ProjectsUsing Buildout to Develop and Deploy Python Projects
Using Buildout to Develop and Deploy Python Projects
 
Generic Setup De-Mystified
Generic Setup De-MystifiedGeneric Setup De-Mystified
Generic Setup De-Mystified
 
Buildout: Fostering Repeatability
Buildout: Fostering RepeatabilityBuildout: Fostering Repeatability
Buildout: Fostering Repeatability
 
Getting Plone Ready For The Prom
Getting Plone Ready For The PromGetting Plone Ready For The Prom
Getting Plone Ready For The Prom
 

Recently uploaded

Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
Zilliz
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
danishmna97
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
Hiroshi SHIBATA
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
Chart Kalyan
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
名前 です男
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
Zilliz
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
DianaGray10
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Jeffrey Haguewood
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
IndexBug
 
Skybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoptionSkybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoption
Tatiana Kojar
 
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying AheadDigital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Wask
 
OpenID AuthZEN Interop Read Out - Authorization
OpenID AuthZEN Interop Read Out - AuthorizationOpenID AuthZEN Interop Read Out - Authorization
OpenID AuthZEN Interop Read Out - Authorization
David Brossard
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
saastr
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
Edge AI and Vision Alliance
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
Daiki Mogmet Ito
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
panagenda
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 

Recently uploaded (20)

Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
 
Skybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoptionSkybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoption
 
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying AheadDigital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying Ahead
 
OpenID AuthZEN Interop Read Out - Authorization
OpenID AuthZEN Interop Read Out - AuthorizationOpenID AuthZEN Interop Read Out - Authorization
OpenID AuthZEN Interop Read Out - Authorization
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 

Reaching Deployment Nirvana Using Buildout

  • 1. Reaching Deployment Nirvana Using Buildout Clayton Parker Plone Conference 2008 nowhere to go but open source s ix fe e tup . c om / dw 0 8
  • 2. Here’s to Plone si xf eet up .co m /dw 0 8
  • 3. To-do List • Buildout • Parts • Recipes • Command Line • ZopeSkel • Create Buildouts • Custom Recipes si xf eet up .co m /dw 0 8
  • 4. Why buildout? si xf eet up .co m /dw 0 8
  • 5. Eliminate Confusion si xf eet up .co m /dw 0 8
  • 6. Tracking Dependencies si xf eet up .co m /dw 0 8
  • 7. Roll Your Own • Installer • ZopeSkel si xf eet up .co m /dw 0 8
  • 8. ZopeSkel $ easy_install ZopeSkel $ paster create --list-templates plone3_buildout: A buildout for Plone 3 projects $ paster create -t plone3_buildout mybuildout si xf eet up .co m /dw 0 8
  • 9. Lingo si xf eet up .co m /dw 0 8
  • 10. Syntax [buildout] parts = zope2 plone instance [plone] recipe = plone.recipe.plone [zope2] recipe = plone.recipe.zope2install [instance] recipe = plone.recipe.zope2instance user = admin:admin eggs = ${plone:eggs} products = ${plone:products} si xf eet up .co m /dw 0 8
  • 11. Advanced Syntax Variable Substitution ${part:option} ${plone:eggs} ${buildout:directory} option = ${buildout:directory}/somefolder Option Addition and Removal options = foo bar options += baz options -= foo si xf eet up .co m /dw 0 8
  • 12. Reserved Characters :$ % { } si xf eet up .co m /dw 0 8
  • 13. Parts si xf eet up .co m /dw 0 8
  • 14. [buildout] parts = instance [instance] recipe = plone.recipe.zope2instance user = admin:admin eggs = ${plone:eggs} archetypes.schemaextender zcml = archetypes.schemaextender products = ${plone:products} environment-vars = TZ America/Chicago http-address = 51060 zeo-address = 53060 debug-mode = on verbose-security = on event-log-level = debug si xf eet up .co m /dw 0 8
  • 15. Recipes si xf eet up .co m /dw 0 8
  • 16. [buildout] parts = zope2 plone instance [plone] recipe = plone.recipe.plone [zope2] recipe = plone.recipe.zope2install [instance] recipe = plone.recipe.zope2instance user = admin:admin eggs = ${plone:eggs} products = ${plone:products} si xf eet up .co m /dw 0 8
  • 17. Buildout Directory • bin/ • bootstrap.py • buildout.cfg • develop-eggs/ • downloads/ • eggs/ • parts/ • products/ • src/ si xf eet up .co m /dw 0 8
  • 18. Buildout options • bin-directory • develop-eggs-directory • eggs-directory • parts • parts-directory • log-level si xf eet up .co m /dw 0 8
  • 19. Defaults [buildout] eggs-directory = /home/clayton/.buildout/eggs download-cache = /home/clayton/.buildout/downloads zope-directory = /home/clayton/.buildout/zope index = http://download.zope.org/ppix [instance] event-log-level = debug si xf eet up .co m /dw 0 8
  • 20. Recipes si xf eet up .co m /dw 0 8
  • 21. Plone Recipes • plone.recipe.plone • plone.recipe.zope2install • plone.recipe.zope2instance • plone.recipe.squid si xf eet up .co m /dw 0 8
  • 22. plone.recipe.zope2install [zope2] recipe = plone.recipe.zope2install url = ${plone:zope2-url} fake-zope-eggs = true additional-fake-eggs = ZODB3 skip-fake-eggs = zope.testing zope.component zope.i18n si xf eet up .co m /dw 0 8
  • 23. In The Wild si xf eet up .co m /dw 0 8
  • 24. Extending Configuration • buildout.cfg • profiles/ • base.cfg • development.cfg • debug.cfg • qa.cfg • prod.cfg • versions.cfg si xf eet up .co m /dw 0 8
  • 25. buildout.cfg [buildout] # the profile we want to use extends = profiles/development.cfg find-links = http://dist.plone.org http://download.zope.org/distribution/ http://effbot.org/downloads si xf eet up .co m /dw 0 8
  • 26. base.cfg [buildout] parts = PILwoTK plone zope2 instance zeoserver develop = src/my.package [PILwoTK] recipe = zc.recipe.egg find-links = http://download.zope.org/distribution/ [zope2] recipe = plone.recipe.zope2install url = ${plone:zope2-url} fake-zope-eggs = true additional-fake-eggs = ZODB3 skip-fake-eggs = zope.testing zope.component zope.i18n si xf eet up .co m /dw 0 8
  • 27. [plone] recipe = plone.recipe.plone [instance] recipe = plone.recipe.zope2instance zeo-client = True zope2-location = ${zope2:location} eggs = PILwoTK elementtree ${plone:eggs} my.package zcml = my.package products = ${plone:products} environment-vars = TZ America/New_York [zeoserver] recipe = plone.recipe.zope2zeoserver zope2-location = ${instance:zope2-location} zeo-address = ${instance:zeo-address} si xf eet up .co m /dw 0 8
  • 28. development.cfg [buildout] extends = base.cfg debug.cfg parts += ${debugging:parts} omelette [instance] user = admin:admin http-address = 8080 zeo-address = 8100 debug-mode = on verbose-security = on event-log-level = debug products += ${buildout:directory}/products ${debugging:debug-products} eggs += ${debugging:eggs} zcml += ${debugging:zcml} [omelette] recipe = collective.recipe.omelette eggs = ${instance:eggs} ignore-develop = True si xf eet up .co m /dw 0 8 ignores = setuptools
  • 29. debug.cfg [debugging] parts = debug-products debug-products-svn ipzope zopepy debug-products = ${debug-products:location} eggs = plone.reload Products.PDBDebugMode Products.DocFinderTab Products.Clouseau Products.PrintingMailHost zcml = plone.reload si xf eet up .co m /dw 0 8
  • 30. [debug-products] recipe = plone.recipe.distros urls = ...dcworkflowgraph-0_3.tgz ...PTProfiler-1.2.tgz [ipzope] recipe = zc.recipe.egg eggs = ipython ${instance:eggs} initialization = import sys, os os.environ[quot;SOFTWARE_HOMEquot;] = quot;${instance:zope2-location}/lib/ pythonquot; os.environ[quot;INSTANCE_HOMEquot;] = quot;${instance:location}quot; sys.argv[1:1] = quot;-p zopequot;.split() extra-paths = ${instance:zope2-location}/lib/python scripts = ipython=ipzope [zopepy] recipe = zc.recipe.egg eggs = ${instance:eggs} interpreter = zopepy extra-paths = ${instance:zope2-location}/lib/python si xf eet up .co m /dw 0 8 scripts = zopepy
  • 31. versions.cfg [versions] # Use the following from the command line to get the latest versions: # bin/buildout -vvvvv |sed -ne 's/^Picked: //p' | sort | uniq PILwoTk = 1.1.6.4 elementtree = 1.2.7-20070827-preview infrae.subversion = 1.1 plone.recipe.distros = 1.3 plone.recipe.plone = 3.1.6 plone.recipe.zope2install = 2.3 plone.recipe.zope2instance = 2.5 plone.recipe.zope2zeoserver = 0.13 python-openid = 2.2.1 my.package = 1.0 si xf eet up .co m /dw 0 8
  • 32. prod.cfg [buildout] extends = base.cfg versions.cfg parts += instance2 versions = versions [instance] zope2-location = ${zope2:location} http-address = 9080 zeo-address = 9100 eggs += Products.CacheSetup z2-log-level = CRITICAL zodb-cache-size = 15000 [instance2] recipe = collective.recipe.zope2cluster instance-clone = instance http-address = 10080 si xf eet up .co m /dw 0 8
  • 33. Command Line si xf eet up .co m /dw 0 8
  • 34. Baby Steps $ cd path/to/mybuildout $ python2.4 bootstrap.py Creating directory 'mybuildout/bin'. Creating directory 'mybuildout/parts'. Creating directory 'mybuildout/develop-eggs'. Generated script 'mybuildout/bin/buildout'. $ bin/buildout $ bin/instance start si xf eet up .co m /dw 0 8
  • 35. Options • -v and -q • increase and decrease verbosity • -n and -N • Newest and non-newest modes • -O and -o • online and offline mode • -t • socket timeout si xf eet up .co m /dw 0 8
  • 36. Update your buildout $ bin/buildout -v $ bin/buildout -Nvvv $ bin/buildout -No $ bin/buildout -t 60 si xf eet up .co m /dw 0 8
  • 37. Assignments $ bin/buildout instance:debug-mode=on $ bin/buildout buildout:log-level=70 $ bin/buildout -N instance:debug-mode=on -v si xf eet up .co m /dw 0 8
  • 38. Commands $ bin/buildout install $ bin/buildout -Nv install zope2 instance $ bin/buildout -nv install instance si xf eet up .co m /dw 0 8
  • 39. Create Recipes $ paster create -t recipe my.recipe.example si xf eet up .co m /dw 0 8
  • 40. Recipe • Recipe class • constructor • install • update • uninstall (optional) si xf eet up .co m /dw 0 8
  • 41. class Recipe: quot;quot;quot;quot;A recipe quot;quot;quot;quot; def __init__(self, buildout, name, options): self.buildout = buildout self.name = name self.options = options # gather options from other parts here options['notmine'] = buildout['someotherpart']['foobar'] def install(self): quot;quot;quot;quot;Install method quot;quot;quot; options = self.options location = options['location'] # must return a string, or an iterable of strings return location def update(self): quot;quot;quot;Update method quot;quot;quot; pass si xf eet up .co m /dw 0 8
  • 42. class Recipe: Real World quot;quot;quot;infrae.subversion recipe. quot;quot;quot; def __init__(self, buildout, name, options): self.buildout = buildout self.name = name self.options = options options['location'] = self.location = os.path.join( buildout['buildout']['parts-directory'], self.name) self.urls = [l.split() for l in options['urls'].splitlines() if l.strip()] self.export = options.get('export') self.newest = ( buildout['buildout'].get('offline', 'false') == 'false' and buildout['buildout'].get('newest', 'true') == 'true' ) self.verbose = buildout['buildout'].get('verbosity', 0) si xf eet up .co m /dw 0 8
  • 43. Install Method def install(self): quot;quot;quot;Checkout the checkouts. quot;quot;quot; for (url, name) in self.urls: wc = py.path.svnwc(self.location).join(name) if self.export: raise Exception('Unimplemented feature') if self.verbose: print quot;Fetch %squot; % url wc.checkout(url) return self.location si xf eet up .co m /dw 0 8
  • 44. def update(self): quot;quot;quot;Update the checkoutsquot;quot;quot; if not self.newest: return self.location if self.export: return self.location if self.options.get('ignore_updates', False): return self.location num_release = re.compile('.*@[0-9]+$') part = py.path.local(self.location) for link, sub_path in self.urls: if num_release.match(link): if self.verbose: print quot;Given num release for %s, skipping.quot; % link continue wc = py.path.svnwc(self.location).join(sub_path) if self.verbose: print quot;Updating %squot; % link wc.update() return self.location si xf eet up .co m /dw 0 8
  • 45. Wrapping Up • Buildout • Parts • Recipes • Command Line • ZopeSkel • Create Buildouts • Custom Recipes si xf eet up .co m /dw 0 8
  • 46. Plone Deployment Workshop sixfeetup.com/dw08 Register by October 17 and save $100!
  • 47. Links • http://buildout.zope.org • http://pypi.python.org/pypi/zc.buildout • https://svn.sixfeetup.com/svn/public/buildout/debug.cfg • http://www.sixfeetup.com/swag/buildout-quick-reference-card • http://plone.org/documentation/tutorial/buildout • http://pypi.python.org si xf eet up .co m /dw 0 8
  • 48. Photo Credits • http://flickr.com/photos/monsieurlam/2645956083/ • http://flickr.com/photos/_boris/2796908072/ • http://flickr.com/photos/b-tal/163450213/ • http://flickr.com/photos/bullish1974/2648544508/ • http://flickr.com/photos/haydnseek/87432002/ • http://flickr.com/photos/disowned/1158260369/ • http://flickr.com/photos/7603557@N08/2662531345/ • http://flickr.com/photos/julishannon/2151986631/ • http://flickr.com/photos/julishannon/2152778524/ • http://flickr.com/photos/lollyknit/1155225799/ • http://flickr.com/photos/binary_koala/86227485/ si xf eet up .co m /dw 0 8