SlideShare a Scribd company logo
1 of 50
Download to read offline
Using Buildout,
GenericSetup and a Policy
Package to Rule the World
    Clayton Parker | Senior Developer
        PLONE SYMPOSIUM EAST 2012
Who Am I
What will we learn?                        PLONE SYMPOSIUM EAST 2012




• Policy Package
• GenericSetup
• Plone Site Buildout Recipe

             http://github.com/sixfeetup
Demo
Realization
• Repeatable environments
• Fewer commands
• Repeatable product installation
PLONE SYMPOSIUM EAST 2012
Human Err0r                                 PLONE SYMPOSIUM EAST 2012




  “Hey Bob, did you run the fizzbang.widget profile
  on production”

  “I think so, Doug”

  “Do you know why the client is yelling at me
  right now?”

  “Maybe I didn’t, let me fix that real quick”
Policy Package
Create the package*                            PLONE SYMPOSIUM EAST 2012




          $ cd path/to/buildout/src
          $ zopeskel sfu_policy pse12.policy
          $ cd pse12.policy
          .. git init / add / etc ...




* This example uses sixieskel for brevity,
   you might use the “plone” template
Package layout                         PLONE SYMPOSIUM EAST 2012



    !"" setup.py
    #"" src
        #"" pse12
            !"" __init__.py
            #"" policy
                 !"" __init__.py
                 !"" configure.zcml
                 !"" profiles
                 %   !"" default
                 %   %   #"" metadata.xml
                 %   #"" initial
                 %       #"" metadata.xml
                 !"" setuphandlers.py
                 !"" upgrades.py
                 #"" upgrades.zcml
Add to buildout                     PLONE SYMPOSIUM EAST 2012




    [buildout]
    extensions = mr.developer
    auto-checkout = True
    parts = instance

    [sources]
    pse12.policy = git <git url here>

    [instance]
    eggs = pse12.policy
Dependencies                  PLONE SYMPOSIUM EAST 2012




   # pse12.policy/setup.py
   install_requires=[
       'setuptools',
       'Plone',
       'Pillow',
       'plone.app.caching',
   ],
ZCML                                   PLONE SYMPOSIUM EAST 2012



       # pse12.policy setup.py
       entry_points="""
       [z3c.autoinclude.plugin]
       target = plone
       """,



<!-- pse12.policy configure.zcml -->
<includePlugins package="." />
<includeDependencies package="." />
Generic Setup
Default profile                                 PLONE SYMPOSIUM EAST 2012




 <!-- pse12.policy configure.zcml -->
 <genericsetup:registerProfile
     name="default"
     title="pse12.policy (default)"
     directory="profiles/default"
     description="Installation profile for pse12.policy"
     provides="Products.GenericSetup.interfaces.EXTENSION"
     />
Initial profile                                 PLONE SYMPOSIUM EAST 2012




 <!-- pse12.policy configure.zcml -->
 <genericsetup:registerProfile
     name="initial"
     title="pse12.policy (initial)"
     directory="profiles/initial"
     description="Initial profile for pse12.policy"
     provides="Products.GenericSetup.interfaces.EXTENSION"
     />
Metadata                            PLONE SYMPOSIUM EAST 2012




   <?xml version="1.0"?>
   <metadata>
       <version>001</version>
       <dependencies>...</dependencies>
   </metadata>
Add-ons
Package                            PLONE SYMPOSIUM EAST 2012




    # Inside setup.py
    install_requires=[
        ...
        ‘plonetheme.transition’,
    ],
Package                                                 PLONE SYMPOSIUM EAST 2012




 <?xml version="1.0"?>

 <!-- pse12.policy metadata.xml -->
 <metadata>
     <version>001</version>
     <dependencies>
         <dependency>profile-plone.app.theming:default</dependency>
     </dependencies>
 </metadata>
Package   PLONE SYMPOSIUM EAST 2012
Package                                                                                PLONE SYMPOSIUM EAST 2012


   # profiles/default/registry.xml
   <registry>
     <record field="enabled" interface="plone.app.theming.interfaces.IThemeSettings"
              name="plone.app.theming.interfaces.IThemeSettings.enabled">
       <field type="plone.registry.field.Bool">
         <default>False</default>
         <description>enable_theme_globally</description>
         <title>enabled</title>
       </field>
       <value>True</value>
     </record>
     <record field="absolutePrefix" interface="plone.app.theming.interfaces.IThemeSettings"
              name="plone.app.theming.interfaces.IThemeSettings.absolutePrefix">
       <field type="plone.registry.field.TextLine">
         <description>convert_relative_url</description>
         <required>False</required>
         <title>absolute_url_prefix</title>
       </field>
       <value>/++theme++plonetheme.transition</value>
     </record>
     <record field="currentTheme" interface="plone.app.theming.interfaces.IThemeSettings"
              name="plone.app.theming.interfaces.IThemeSettings.currentTheme">
       <field type="plone.registry.field.TextLine">
         <description>current_theme_description</description>
         <title>current_theme</title>
       </field>
       <value>plonetheme.transition</value>
     </record>
     <record field="rules" interface="plone.app.theming.interfaces.IThemeSettings"
              name="plone.app.theming.interfaces.IThemeSettings.rules">
       <field type="plone.registry.field.TextLine">
         <description>rules_file_path</description>
         <required>False</required>
         <title>rules_file</title>
       </field>
       <value>/++theme++plonetheme.transition/rules.xml</value>
     </record>
   </registry>
Blog                                    PLONE SYMPOSIUM EAST 2012




       # Inside pse12.policy setup.py
       install_requires=[
           ...
           ‘collective.blog.star’,
       ],
Blog                                                      PLONE SYMPOSIUM EAST 2012




 <?xml version="1.0"?>

 <!-- pse12.policy metadata.xml -->
 <metadata>
     <version>001</version>
     <dependencies>
         ...
         <dependency>profile-collective.blog.star:default</dependency>
     </dependencies>
 </metadata>
Content
Package                                     PLONE SYMPOSIUM EAST 2012




    $ zopeskel plone pse12.initialcontent
Package                             PLONE SYMPOSIUM EAST 2012




   # Inside pse12.initialcontent setup.py
   install_requires=[
       ‘quintagroup.transmogrifier’,
   ],
Package                                       PLONE SYMPOSIUM EAST 2012




<!-- pse12.initialcontent configure.zcml -->
<genericsetup:registerProfile
    name="default"
    title="pse12.initialcontent (default)"
    directory="profiles/default"
    description="Content generation package"
    provides="Products.GenericSetup.interfaces.EXTENSION"
    />
Package                                         PLONE SYMPOSIUM EAST 2012




<?xml version="1.0"?>

<!-- pse12.initialcontent metadata.xml -->
<metadata>
    <version>001</version>
    <dependencies>
        <dependency>profile-pse12.policy:default</dependency>
    </dependencies>
</metadata>
!""   __init__.py
!""   configure.zcml                                  PLONE SYMPOSIUM EAST 2012
!""   profiles
#     %"" default
#         !"" metadata.xml
#         !"" pse12_initialcontent-default.txt
#         !"" quintagroup.transmogrifier-import.txt
#         %"" structure
#              !"" .objects.xml
#              !"" .portlets.xml
#              !"" .properties.xml
#              !"" about
#              #   !"" .marshall.xml
#              #   !"" .objects.xml
#              #   !"" .portlets.xml
#              #   !"" .properties.xml
#              #   !"" about-us
#              #   #   !"" .marshall.xml
#              #   #   %"" .portlets.xml
#              #   %"" meet-the-team
#              #        !"" .marshall.xml
#              #        %"" .portlets.xml
#              !"" files
#              #   !"" .marshall.xml
#              #   %"" .portlets.xml
#              !"" front-page
#              #   !"" .marshall.xml
#              #   %"" .portlets.xml
#              %"" images
#                   !"" .marshall.xml
#                   !"" .objects.xml
#                   %"" .portlets.xml
!""   setuphandlers.py
!""   upgrades.py
%""   upgrades.zcml
Upgrades and Setuphandlers
Setuphandlers                                           PLONE SYMPOSIUM EAST 2012



  from sixfeetup.utils import helpers as sfutils


  def importVariousInitial(context):
      """Run the setup handlers for the initial profile"""
      if context.readDataFile('pse12_policy-initial.txt') is None:
          return
      members = [
          {'id': 'staff',
            'password': 'staff',
            'roles': ['Manager', 'Member'],
            'properties': {
                'email': 'changeme@example.com',
                'fullname': 'Site Staff',
                'username': 'staff'
            }
          }
      ]
      sfutils.addUserAccounts(members)
Setuphandlers                                          PLONE SYMPOSIUM EAST 2012




  <genericsetup:importStep
      name="pse12.policy: initial"
      title="pse12.policy: Various Initial steps"
      description="Initial Setup handlers for pse12.policy"
      handler="pse12.policy.setuphandlers.importVariousInitial">
    <depends name="content"/>
  </genericsetup:importStep>
Setuphandlers                                           PLONE SYMPOSIUM EAST 2012




  from sixfeetup.utils import helpers as sfutils


  def importVarious(context):
      """Run the setup handlers for the default profile"""
      if context.readDataFile('pse12_policy-default.txt') is None:
          return
      # automagically run a plone migration if needed
      sfutils.runPortalMigration()
      # automagically run the upgrade steps for this package
      sfutils.runUpgradeSteps(u'pse12.policy:default')
Setuphandlers                                             PLONE SYMPOSIUM EAST 2012




from sixfeetup.utils import helpers as sfutils


def importVarious(context):
    """Run the setup handlers for the default profile"""
    if context.readDataFile('pse12_initialcontent-default.txt') is None:
        return
    # automagically run the upgrade steps for this package
    sfutils.runUpgradeSteps(u'pse12.initialcontent:default')
Upgrades                                             PLONE SYMPOSIUM EAST 2012


   <!-- pse12.initialcontent upgrades.zcml -->
   <genericsetup:upgradeStep
       title="Set up intranet section"
       description=""
       source="001"
       destination="002"
       handler="pse12.initialcontent.upgrades.intranet_setup"
       sortkey="10"
       profile="pse12.initialcontent:default"
       />

   <genericsetup:upgradeStep
       title="Set up the default pages"
       description=""
       source="001"
       destination="002"
       handler="pse12.initialcontent.upgrades.default_pages"
       sortkey="20"
       profile="pse12.initialcontent:default"
       />
from zope.app.component.hooks import getSite
                                                           PLONE SYMPOSIUM EAST 2012
from Products.CMFCore.utils import getToolByName
from sixfeetup.utils import helpers as sfutils


def intranet_setup(context):
    """Set up the placeful workflow for the intranet
    """
    portal = getSite()
    # If the intranet doesn't exist, bail out
    if 'intranet' not in portal.objectIds():
        return
    intranet = portal['intranet']
    # If the placeful workflow is already in place, bail out
    if '.wf_policy_config' in intranet.objectIds():
        return
    placeful_workflow = getToolByName(portal, 'portal_placeful_workflow')
    product = 'CMFPlacefulWorkflow'
    intranet.manage_addProduct[product].manage_addWorkflowPolicyConfig()
    config = placeful_workflow.getWorkflowPolicyConfig(intranet)
    policy = 'intranet'
    config.setPolicyBelow(policy=policy)
    config.setPolicyIn(policy=policy)
    # Make everything in the intranet `private`
    path = '/'.join(intranet.getPhysicalPath())
    sfutils.publishEverything(context, path, 'hide')
from zope.app.component.hooks import getSite
                                                                          PLONE SYMPOSIUM EAST 2012

def default_pages(context):
    """There is a bug in quintagroup.transmogrifier that prevents
    the default page from being set. We will handle it here
    instead.
    """
    portal = getSite()
    items = {
        'about': dict(
             id='default_page',
             type='string',
             value='about-us'),
        'blog': dict(
             id='layout',
             type='string',
             value='blog_view'),
    }
    for path, prop in items.items():
        obj = portal.unrestrictedTraverse(path, None)
        # If the object doesn't exist, bail out
        if obj is None:
             continue
        target_obj = None
        if prop['id'] == 'default_page':
             target_obj = obj.unrestrictedTraverse(prop['value'], None)
             # Bail out if the default page target does not exist
             if target_obj is None:
                 continue
        obj._setProperty(prop['id'], prop['value'], prop['value'])
        if target_obj is not None:
             # ensure that it doesn't show in the navigation
             target_obj.reindexObject()
Plone Site Recipe
What is it?             PLONE SYMPOSIUM EAST 2012




• Create a Plone site
• Run profiles
• Re-create a site
Add it to buildout                   PLONE SYMPOSIUM EAST 2012




    [buildout]
    parts = plonesite

    [plonesite]
    recipe = collective.recipe.plonesite
    instance = instance
    zeoserver = zeoserver
    site-id = Plone
    admin-user = admin
Add profiles                         PLONE SYMPOSIUM EAST 2012




  [plonesite]
  ...
  profiles-initial = pse12.policy:initial
  profiles = pse12.policy:default
Buildout run                                PLONE SYMPOSIUM EAST 2012




    $ bin/buildout install plonesite
    Installing plonesite.
    Retrieved the admin user
    Added Plone Site
    Quick installing: []
    Running profiles: ['pse12.policy:initial']
    Finished
    Running profiles: ['pse12.policy:default',
    'sixfeetup.customfolderalert:default',
    'plone.app.debugtoolbar:default']
Dynamic options                             PLONE SYMPOSIUM EAST 2012




   $ bin/buildout plonesite:enabled=false




   $ bin/buildout plonesite:site-replace=true
Upgrade Demo
Links                                                                         PLONE SYMPOSIUM EAST 2012




•   sixieskel (http://github.com/sixfeetup/sixieskel)

•   pse12-example-buildout (http://github.com/sixfeetup/pse12-example-buildout)

•   pse12.policy (http://github.com/sixfeetup/pse12.policy)

•   pse12.initialcontent (http://github.com/sixfeetup/pse12.initialcontent)

•   quintagroup.transmogrifier (http://pypi.python.org/pypi/quintagroup.transmogrifier)

•   collective.blog.star (http://pypi.python.org/pypi/collective.blog.star)

•   plonetheme.transition (http://pypi.python.org/pypi/plonetheme.transition/)
Photo Credits                                                                 PLONE SYMPOSIUM EAST 2012




•   http://www.flickr.com/photos/naturegeak/5642083189/ (who)

•   https://secure.flickr.com/photos/campuspartymexico/5965708420/ (demo)

•   https://secure.flickr.com/photos/aon/2171253511/ (realization)

•   https://secure.flickr.com/photos/walkingsf/6930636483/ (policy)

•   https://secure.flickr.com/photos/myklroventine/3261364899/ (GS)

•   https://secure.flickr.com/photos/oskay/2157686638/ (add-ons)

•   https://secure.flickr.com/photos/simonpholzman/5132795241/ (plone site)

•   https://secure.flickr.com/photos/bitterjug/488731963// (upgrades)

•   https://secure.flickr.com/photos/campuspartymexico/5965153009/ (upgrade)

•   https://secure.flickr.com/photos/friarsbalsam/4609212148/ (content)




    Thanks to
Questions?




   heck out     /demos
 C
        tup .com
si xfee

More Related Content

What's hot

You've Got Plugins in Your Plugins: Bundling Plugin Dependencies - Atlassian ...
You've Got Plugins in Your Plugins: Bundling Plugin Dependencies - Atlassian ...You've Got Plugins in Your Plugins: Bundling Plugin Dependencies - Atlassian ...
You've Got Plugins in Your Plugins: Bundling Plugin Dependencies - Atlassian ...
Atlassian
 
Phing for power users - frOSCon8
Phing for power users - frOSCon8Phing for power users - frOSCon8
Phing for power users - frOSCon8
Stephan Hochdörfer
 

What's hot (20)

淺談 Geb 網站自動化測試(JCConf 2014)
淺談 Geb 網站自動化測試(JCConf 2014)淺談 Geb 網站自動化測試(JCConf 2014)
淺談 Geb 網站自動化測試(JCConf 2014)
 
SproutCore is Awesome - HTML5 Summer DevFest
SproutCore is Awesome - HTML5 Summer DevFestSproutCore is Awesome - HTML5 Summer DevFest
SproutCore is Awesome - HTML5 Summer DevFest
 
Grails Plugins(Console, DB Migration, Asset Pipeline and Remote pagination)
Grails Plugins(Console, DB Migration, Asset Pipeline and Remote pagination)Grails Plugins(Console, DB Migration, Asset Pipeline and Remote pagination)
Grails Plugins(Console, DB Migration, Asset Pipeline and Remote pagination)
 
Django for Beginners
Django for BeginnersDjango for Beginners
Django for Beginners
 
Pyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsPyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web apps
 
Implement rich snippets in your webshop
Implement rich snippets in your webshopImplement rich snippets in your webshop
Implement rich snippets in your webshop
 
关于 Html5 那点事
关于 Html5 那点事关于 Html5 那点事
关于 Html5 那点事
 
Intro to Selenium UI Tests with pytest & some useful pytest plugins
Intro to Selenium UI Tests with pytest & some useful pytest pluginsIntro to Selenium UI Tests with pytest & some useful pytest plugins
Intro to Selenium UI Tests with pytest & some useful pytest plugins
 
You've Got Plugins in Your Plugins: Bundling Plugin Dependencies - Atlassian ...
You've Got Plugins in Your Plugins: Bundling Plugin Dependencies - Atlassian ...You've Got Plugins in Your Plugins: Bundling Plugin Dependencies - Atlassian ...
You've Got Plugins in Your Plugins: Bundling Plugin Dependencies - Atlassian ...
 
ZopeSkel: The past, present and future
ZopeSkel: The past, present and futureZopeSkel: The past, present and future
ZopeSkel: The past, present and future
 
Intro to WordPress Plugin Development
Intro to WordPress Plugin DevelopmentIntro to WordPress Plugin Development
Intro to WordPress Plugin Development
 
Jumping Into WordPress Plugin Programming
Jumping Into WordPress Plugin ProgrammingJumping Into WordPress Plugin Programming
Jumping Into WordPress Plugin Programming
 
jQuery For Developers Stack Overflow Dev Days Toronto
jQuery For Developers Stack Overflow Dev Days TorontojQuery For Developers Stack Overflow Dev Days Toronto
jQuery For Developers Stack Overflow Dev Days Toronto
 
Phing for power users - frOSCon8
Phing for power users - frOSCon8Phing for power users - frOSCon8
Phing for power users - frOSCon8
 
BitSensor - How and when to start a business
BitSensor - How and when to start a businessBitSensor - How and when to start a business
BitSensor - How and when to start a business
 
Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)
 
Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel
 
You're Doing It Wrong
You're Doing It WrongYou're Doing It Wrong
You're Doing It Wrong
 
11 tools for your PHP devops stack
11 tools for your PHP devops stack11 tools for your PHP devops stack
11 tools for your PHP devops stack
 
Automatisation in development and testing - within budget
Automatisation in development and testing - within budgetAutomatisation in development and testing - within budget
Automatisation in development and testing - within budget
 

Similar to Using Buildout, GenericSetup and a Policy Package to Rule the World

IzPack at LyonJUG'11
IzPack at LyonJUG'11IzPack at LyonJUG'11
IzPack at LyonJUG'11
julien.ponge
 
How to Get Started Theming Plone
How to Get Started Theming PloneHow to Get Started Theming Plone
How to Get Started Theming Plone
cdw9
 
Sap Solman Instguide Dba Cockpit Setup
Sap Solman Instguide Dba Cockpit SetupSap Solman Instguide Dba Cockpit Setup
Sap Solman Instguide Dba Cockpit Setup
wlacaze
 
OpenERP e l'arte della gestione aziendale con Python
OpenERP e l'arte della gestione aziendale con PythonOpenERP e l'arte della gestione aziendale con Python
OpenERP e l'arte della gestione aziendale con Python
PyCon Italia
 
The Best (and Worst) of Django
The Best (and Worst) of DjangoThe Best (and Worst) of Django
The Best (and Worst) of Django
Jacob Kaplan-Moss
 

Similar to Using Buildout, GenericSetup and a Policy Package to Rule the World (20)

Martin Aspeli Extending And Customising Plone 3
Martin Aspeli   Extending And Customising Plone 3Martin Aspeli   Extending And Customising Plone 3
Martin Aspeli Extending And Customising Plone 3
 
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
 
Generic Setup De-Mystified
Generic Setup De-MystifiedGeneric Setup De-Mystified
Generic Setup De-Mystified
 
IzPack at LyonJUG'11
IzPack at LyonJUG'11IzPack at LyonJUG'11
IzPack at LyonJUG'11
 
Turbogears Presentation
Turbogears PresentationTurbogears Presentation
Turbogears Presentation
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
Using Renderless Components in Vue.js during your software development.
Using Renderless Components in Vue.js during your software development.Using Renderless Components in Vue.js during your software development.
Using Renderless Components in Vue.js during your software development.
 
How to Get Started Theming Plone
How to Get Started Theming PloneHow to Get Started Theming Plone
How to Get Started Theming Plone
 
Up & Running with Polymer
Up & Running with PolymerUp & Running with Polymer
Up & Running with Polymer
 
Building a Dynamic Website Using Django
Building a Dynamic Website Using DjangoBuilding a Dynamic Website Using Django
Building a Dynamic Website Using Django
 
Sap Solman Instguide Dba Cockpit Setup
Sap Solman Instguide Dba Cockpit SetupSap Solman Instguide Dba Cockpit Setup
Sap Solman Instguide Dba Cockpit Setup
 
Jaxitalia09 Spring Best Practices
Jaxitalia09 Spring Best PracticesJaxitalia09 Spring Best Practices
Jaxitalia09 Spring Best Practices
 
Angular JS2 Training Session #2
Angular JS2 Training Session #2Angular JS2 Training Session #2
Angular JS2 Training Session #2
 
OpenERP e l'arte della gestione aziendale con Python
OpenERP e l'arte della gestione aziendale con PythonOpenERP e l'arte della gestione aziendale con Python
OpenERP e l'arte della gestione aziendale con Python
 
Effective Python Package Management [PyCon Canada 2017]
Effective Python Package Management [PyCon Canada 2017]Effective Python Package Management [PyCon Canada 2017]
Effective Python Package Management [PyCon Canada 2017]
 
20190118_NetadashiMeetup#8_React2019
20190118_NetadashiMeetup#8_React201920190118_NetadashiMeetup#8_React2019
20190118_NetadashiMeetup#8_React2019
 
The Best (and Worst) of Django
The Best (and Worst) of DjangoThe Best (and Worst) of Django
The Best (and Worst) of Django
 
Dexterity in 15 minutes or less
Dexterity in 15 minutes or lessDexterity in 15 minutes or less
Dexterity in 15 minutes or less
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!
 
Quality Use Of Plugin
Quality Use Of PluginQuality Use Of Plugin
Quality Use Of Plugin
 

More from Clayton Parker

More from Clayton Parker (17)

Customizing Your Shell With Dotfiles
Customizing Your Shell With DotfilesCustomizing Your Shell With Dotfiles
Customizing Your Shell With Dotfiles
 
Vim for Mere Mortals
Vim for Mere MortalsVim for Mere Mortals
Vim for Mere Mortals
 
Fuzzy Feelings for Fuzzy Matching
Fuzzy Feelings for Fuzzy MatchingFuzzy Feelings for Fuzzy Matching
Fuzzy Feelings for Fuzzy Matching
 
Exploring Code with Pry!
Exploring Code with Pry!Exploring Code with Pry!
Exploring Code with Pry!
 
Zen and the Art of Python
Zen and the Art of PythonZen and the Art of Python
Zen and the Art of Python
 
So you think you can pdb?
So you think you can pdb?So you think you can pdb?
So you think you can pdb?
 
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
 
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
 
Buildout for the Future
Buildout for the FutureBuildout for the Future
Buildout for the 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
 
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

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Recently uploaded (20)

Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 

Using Buildout, GenericSetup and a Policy Package to Rule the World

  • 1. Using Buildout, GenericSetup and a Policy Package to Rule the World Clayton Parker | Senior Developer PLONE SYMPOSIUM EAST 2012
  • 3. What will we learn? PLONE SYMPOSIUM EAST 2012 • Policy Package • GenericSetup • Plone Site Buildout Recipe http://github.com/sixfeetup
  • 5.
  • 6.
  • 7. Realization • Repeatable environments • Fewer commands • Repeatable product installation
  • 9. Human Err0r PLONE SYMPOSIUM EAST 2012 “Hey Bob, did you run the fizzbang.widget profile on production” “I think so, Doug” “Do you know why the client is yelling at me right now?” “Maybe I didn’t, let me fix that real quick”
  • 11. Create the package* PLONE SYMPOSIUM EAST 2012 $ cd path/to/buildout/src $ zopeskel sfu_policy pse12.policy $ cd pse12.policy .. git init / add / etc ... * This example uses sixieskel for brevity, you might use the “plone” template
  • 12. Package layout PLONE SYMPOSIUM EAST 2012 !"" setup.py #"" src #"" pse12    !"" __init__.py    #"" policy    !"" __init__.py    !"" configure.zcml    !"" profiles    %   !"" default    %   %   #"" metadata.xml    %   #"" initial    %   #"" metadata.xml    !"" setuphandlers.py    !"" upgrades.py    #"" upgrades.zcml
  • 13. Add to buildout PLONE SYMPOSIUM EAST 2012 [buildout] extensions = mr.developer auto-checkout = True parts = instance [sources] pse12.policy = git <git url here> [instance] eggs = pse12.policy
  • 14. Dependencies PLONE SYMPOSIUM EAST 2012 # pse12.policy/setup.py install_requires=[ 'setuptools', 'Plone', 'Pillow', 'plone.app.caching', ],
  • 15. ZCML PLONE SYMPOSIUM EAST 2012 # pse12.policy setup.py entry_points=""" [z3c.autoinclude.plugin] target = plone """, <!-- pse12.policy configure.zcml --> <includePlugins package="." /> <includeDependencies package="." />
  • 17. Default profile PLONE SYMPOSIUM EAST 2012 <!-- pse12.policy configure.zcml --> <genericsetup:registerProfile name="default" title="pse12.policy (default)" directory="profiles/default" description="Installation profile for pse12.policy" provides="Products.GenericSetup.interfaces.EXTENSION" />
  • 18. Initial profile PLONE SYMPOSIUM EAST 2012 <!-- pse12.policy configure.zcml --> <genericsetup:registerProfile name="initial" title="pse12.policy (initial)" directory="profiles/initial" description="Initial profile for pse12.policy" provides="Products.GenericSetup.interfaces.EXTENSION" />
  • 19. Metadata PLONE SYMPOSIUM EAST 2012 <?xml version="1.0"?> <metadata> <version>001</version> <dependencies>...</dependencies> </metadata>
  • 21. Package PLONE SYMPOSIUM EAST 2012 # Inside setup.py install_requires=[ ... ‘plonetheme.transition’, ],
  • 22. Package PLONE SYMPOSIUM EAST 2012 <?xml version="1.0"?> <!-- pse12.policy metadata.xml --> <metadata> <version>001</version> <dependencies> <dependency>profile-plone.app.theming:default</dependency> </dependencies> </metadata>
  • 23. Package PLONE SYMPOSIUM EAST 2012
  • 24. Package PLONE SYMPOSIUM EAST 2012 # profiles/default/registry.xml <registry> <record field="enabled" interface="plone.app.theming.interfaces.IThemeSettings" name="plone.app.theming.interfaces.IThemeSettings.enabled"> <field type="plone.registry.field.Bool"> <default>False</default> <description>enable_theme_globally</description> <title>enabled</title> </field> <value>True</value> </record> <record field="absolutePrefix" interface="plone.app.theming.interfaces.IThemeSettings" name="plone.app.theming.interfaces.IThemeSettings.absolutePrefix"> <field type="plone.registry.field.TextLine"> <description>convert_relative_url</description> <required>False</required> <title>absolute_url_prefix</title> </field> <value>/++theme++plonetheme.transition</value> </record> <record field="currentTheme" interface="plone.app.theming.interfaces.IThemeSettings" name="plone.app.theming.interfaces.IThemeSettings.currentTheme"> <field type="plone.registry.field.TextLine"> <description>current_theme_description</description> <title>current_theme</title> </field> <value>plonetheme.transition</value> </record> <record field="rules" interface="plone.app.theming.interfaces.IThemeSettings" name="plone.app.theming.interfaces.IThemeSettings.rules"> <field type="plone.registry.field.TextLine"> <description>rules_file_path</description> <required>False</required> <title>rules_file</title> </field> <value>/++theme++plonetheme.transition/rules.xml</value> </record> </registry>
  • 25. Blog PLONE SYMPOSIUM EAST 2012 # Inside pse12.policy setup.py install_requires=[ ... ‘collective.blog.star’, ],
  • 26. Blog PLONE SYMPOSIUM EAST 2012 <?xml version="1.0"?> <!-- pse12.policy metadata.xml --> <metadata> <version>001</version> <dependencies> ... <dependency>profile-collective.blog.star:default</dependency> </dependencies> </metadata>
  • 28. Package PLONE SYMPOSIUM EAST 2012 $ zopeskel plone pse12.initialcontent
  • 29. Package PLONE SYMPOSIUM EAST 2012 # Inside pse12.initialcontent setup.py install_requires=[ ‘quintagroup.transmogrifier’, ],
  • 30. Package PLONE SYMPOSIUM EAST 2012 <!-- pse12.initialcontent configure.zcml --> <genericsetup:registerProfile name="default" title="pse12.initialcontent (default)" directory="profiles/default" description="Content generation package" provides="Products.GenericSetup.interfaces.EXTENSION" />
  • 31. Package PLONE SYMPOSIUM EAST 2012 <?xml version="1.0"?> <!-- pse12.initialcontent metadata.xml --> <metadata> <version>001</version> <dependencies> <dependency>profile-pse12.policy:default</dependency> </dependencies> </metadata>
  • 32. !"" __init__.py !"" configure.zcml PLONE SYMPOSIUM EAST 2012 !"" profiles #   %"" default #   !"" metadata.xml #   !"" pse12_initialcontent-default.txt #   !"" quintagroup.transmogrifier-import.txt #   %"" structure #   !"" .objects.xml #   !"" .portlets.xml #   !"" .properties.xml #   !"" about #   #   !"" .marshall.xml #   #   !"" .objects.xml #   #   !"" .portlets.xml #   #   !"" .properties.xml #   #   !"" about-us #   #   #   !"" .marshall.xml #   #   #   %"" .portlets.xml #   #   %"" meet-the-team #   #   !"" .marshall.xml #   #   %"" .portlets.xml #   !"" files #   #   !"" .marshall.xml #   #   %"" .portlets.xml #   !"" front-page #   #   !"" .marshall.xml #   #   %"" .portlets.xml #   %"" images #      !"" .marshall.xml #      !"" .objects.xml #     %"" .portlets.xml !"" setuphandlers.py !"" upgrades.py %"" upgrades.zcml
  • 34. Setuphandlers PLONE SYMPOSIUM EAST 2012 from sixfeetup.utils import helpers as sfutils def importVariousInitial(context): """Run the setup handlers for the initial profile""" if context.readDataFile('pse12_policy-initial.txt') is None: return members = [ {'id': 'staff', 'password': 'staff', 'roles': ['Manager', 'Member'], 'properties': { 'email': 'changeme@example.com', 'fullname': 'Site Staff', 'username': 'staff' } } ] sfutils.addUserAccounts(members)
  • 35. Setuphandlers PLONE SYMPOSIUM EAST 2012 <genericsetup:importStep name="pse12.policy: initial" title="pse12.policy: Various Initial steps" description="Initial Setup handlers for pse12.policy" handler="pse12.policy.setuphandlers.importVariousInitial"> <depends name="content"/> </genericsetup:importStep>
  • 36. Setuphandlers PLONE SYMPOSIUM EAST 2012 from sixfeetup.utils import helpers as sfutils def importVarious(context): """Run the setup handlers for the default profile""" if context.readDataFile('pse12_policy-default.txt') is None: return # automagically run a plone migration if needed sfutils.runPortalMigration() # automagically run the upgrade steps for this package sfutils.runUpgradeSteps(u'pse12.policy:default')
  • 37. Setuphandlers PLONE SYMPOSIUM EAST 2012 from sixfeetup.utils import helpers as sfutils def importVarious(context): """Run the setup handlers for the default profile""" if context.readDataFile('pse12_initialcontent-default.txt') is None: return # automagically run the upgrade steps for this package sfutils.runUpgradeSteps(u'pse12.initialcontent:default')
  • 38. Upgrades PLONE SYMPOSIUM EAST 2012 <!-- pse12.initialcontent upgrades.zcml --> <genericsetup:upgradeStep title="Set up intranet section" description="" source="001" destination="002" handler="pse12.initialcontent.upgrades.intranet_setup" sortkey="10" profile="pse12.initialcontent:default" /> <genericsetup:upgradeStep title="Set up the default pages" description="" source="001" destination="002" handler="pse12.initialcontent.upgrades.default_pages" sortkey="20" profile="pse12.initialcontent:default" />
  • 39. from zope.app.component.hooks import getSite PLONE SYMPOSIUM EAST 2012 from Products.CMFCore.utils import getToolByName from sixfeetup.utils import helpers as sfutils def intranet_setup(context): """Set up the placeful workflow for the intranet """ portal = getSite() # If the intranet doesn't exist, bail out if 'intranet' not in portal.objectIds(): return intranet = portal['intranet'] # If the placeful workflow is already in place, bail out if '.wf_policy_config' in intranet.objectIds(): return placeful_workflow = getToolByName(portal, 'portal_placeful_workflow') product = 'CMFPlacefulWorkflow' intranet.manage_addProduct[product].manage_addWorkflowPolicyConfig() config = placeful_workflow.getWorkflowPolicyConfig(intranet) policy = 'intranet' config.setPolicyBelow(policy=policy) config.setPolicyIn(policy=policy) # Make everything in the intranet `private` path = '/'.join(intranet.getPhysicalPath()) sfutils.publishEverything(context, path, 'hide')
  • 40. from zope.app.component.hooks import getSite PLONE SYMPOSIUM EAST 2012 def default_pages(context): """There is a bug in quintagroup.transmogrifier that prevents the default page from being set. We will handle it here instead. """ portal = getSite() items = { 'about': dict( id='default_page', type='string', value='about-us'), 'blog': dict( id='layout', type='string', value='blog_view'), } for path, prop in items.items(): obj = portal.unrestrictedTraverse(path, None) # If the object doesn't exist, bail out if obj is None: continue target_obj = None if prop['id'] == 'default_page': target_obj = obj.unrestrictedTraverse(prop['value'], None) # Bail out if the default page target does not exist if target_obj is None: continue obj._setProperty(prop['id'], prop['value'], prop['value']) if target_obj is not None: # ensure that it doesn't show in the navigation target_obj.reindexObject()
  • 42. What is it? PLONE SYMPOSIUM EAST 2012 • Create a Plone site • Run profiles • Re-create a site
  • 43. Add it to buildout PLONE SYMPOSIUM EAST 2012 [buildout] parts = plonesite [plonesite] recipe = collective.recipe.plonesite instance = instance zeoserver = zeoserver site-id = Plone admin-user = admin
  • 44. Add profiles PLONE SYMPOSIUM EAST 2012 [plonesite] ... profiles-initial = pse12.policy:initial profiles = pse12.policy:default
  • 45. Buildout run PLONE SYMPOSIUM EAST 2012 $ bin/buildout install plonesite Installing plonesite. Retrieved the admin user Added Plone Site Quick installing: [] Running profiles: ['pse12.policy:initial'] Finished Running profiles: ['pse12.policy:default', 'sixfeetup.customfolderalert:default', 'plone.app.debugtoolbar:default']
  • 46. Dynamic options PLONE SYMPOSIUM EAST 2012 $ bin/buildout plonesite:enabled=false $ bin/buildout plonesite:site-replace=true
  • 48. Links PLONE SYMPOSIUM EAST 2012 • sixieskel (http://github.com/sixfeetup/sixieskel) • pse12-example-buildout (http://github.com/sixfeetup/pse12-example-buildout) • pse12.policy (http://github.com/sixfeetup/pse12.policy) • pse12.initialcontent (http://github.com/sixfeetup/pse12.initialcontent) • quintagroup.transmogrifier (http://pypi.python.org/pypi/quintagroup.transmogrifier) • collective.blog.star (http://pypi.python.org/pypi/collective.blog.star) • plonetheme.transition (http://pypi.python.org/pypi/plonetheme.transition/)
  • 49. Photo Credits PLONE SYMPOSIUM EAST 2012 • http://www.flickr.com/photos/naturegeak/5642083189/ (who) • https://secure.flickr.com/photos/campuspartymexico/5965708420/ (demo) • https://secure.flickr.com/photos/aon/2171253511/ (realization) • https://secure.flickr.com/photos/walkingsf/6930636483/ (policy) • https://secure.flickr.com/photos/myklroventine/3261364899/ (GS) • https://secure.flickr.com/photos/oskay/2157686638/ (add-ons) • https://secure.flickr.com/photos/simonpholzman/5132795241/ (plone site) • https://secure.flickr.com/photos/bitterjug/488731963// (upgrades) • https://secure.flickr.com/photos/campuspartymexico/5965153009/ (upgrade) • https://secure.flickr.com/photos/friarsbalsam/4609212148/ (content) Thanks to
  • 50. Questions? heck out /demos C tup .com si xfee