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

50
Clayton Parker | Senior Developer Using Buildout, GenericSetup and a Policy Package to Rule the World PLONE SYMPOSIUM EAST 2012

description

So you have your code on the filesystem and you are using buildout;what's next? You can take your build to the next level by reducing theamount of manual steps needed to create and maintain your site. Usingcollective.recipe.plonesite, you can ensure that every member of yourteam is working on an identical Plone site at any given time.Without the plonesite recipe, when you run your buildout for the firsttime, you are left with an empty Zope site. This talk will show you howto utilize buildout to create a Plone site for you and make sure it isall set up via a policy package and GenericSetup so you can hit theground running.

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

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

Clayton Parker | Senior Developer

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

PLONE SYMPOSIUM EAST 2012

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

Who Am I

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

PLONE SYMPOSIUM EAST 2012What will we learn?

• Policy Package

• GenericSetup

• Plone Site Buildout Recipe

http://github.com/sixfeetup

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

Demo

Page 5: Using Buildout, GenericSetup and a Policy Package to Rule the World
Page 6: Using Buildout, GenericSetup and a Policy Package to Rule the World
Page 7: Using Buildout, GenericSetup and a Policy Package to Rule the World

Realization• Repeatable environments

• Fewer commands

• Repeatable product installation

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

PLONE SYMPOSIUM EAST 2012

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

PLONE SYMPOSIUM EAST 2012Human Err0r

“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”

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

Policy Package

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

PLONE SYMPOSIUM EAST 2012Create the package*

$ 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

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

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

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

PLONE SYMPOSIUM EAST 2012Add to buildout

[buildout]extensions = mr.developerauto-checkout = Trueparts = instance

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

[instance]eggs = pse12.policy

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

PLONE SYMPOSIUM EAST 2012Dependencies

# pse12.policy/setup.pyinstall_requires=[ 'setuptools', 'Plone', 'Pillow', 'plone.app.caching',],

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

PLONE SYMPOSIUM EAST 2012ZCML# pse12.policy setup.pyentry_points="""[z3c.autoinclude.plugin]target = plone""",

<!-- pse12.policy configure.zcml --><includePlugins package="." /><includeDependencies package="." />

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

Generic Setup

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

PLONE SYMPOSIUM EAST 2012Default profile

<!-- 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" />

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

PLONE SYMPOSIUM EAST 2012Initial profile

<!-- 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" />

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

PLONE SYMPOSIUM EAST 2012Metadata

<?xml version="1.0"?><metadata> <version>001</version> <dependencies>...</dependencies></metadata>

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

Add-ons

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

PLONE SYMPOSIUM EAST 2012Package

# Inside setup.pyinstall_requires=[ ... ‘plonetheme.transition’,],

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

PLONE SYMPOSIUM EAST 2012Package

<?xml version="1.0"?>

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

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

PLONE SYMPOSIUM EAST 2012Package

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

PLONE SYMPOSIUM EAST 2012Package# 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>

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

PLONE SYMPOSIUM EAST 2012Blog

# Inside pse12.policy setup.pyinstall_requires=[ ... ‘collective.blog.star’,],

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

PLONE SYMPOSIUM EAST 2012Blog

<?xml version="1.0"?>

<!-- pse12.policy metadata.xml --><metadata> <version>001</version> <dependencies> ... <dependency>profile-collective.blog.star:default</dependency> </dependencies></metadata>

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

Content

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

PLONE SYMPOSIUM EAST 2012Package

$ zopeskel plone pse12.initialcontent

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

PLONE SYMPOSIUM EAST 2012Package

# Inside pse12.initialcontent setup.pyinstall_requires=[ ‘quintagroup.transmogrifier’,],

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

PLONE SYMPOSIUM EAST 2012Package

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

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

PLONE SYMPOSIUM EAST 2012Package

<?xml version="1.0"?>

<!-- pse12.initialcontent metadata.xml --><metadata> <version>001</version> <dependencies> <dependency>profile-pse12.policy:default</dependency> </dependencies></metadata>

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

PLONE SYMPOSIUM EAST 2012!"" __init__.py!"" configure.zcml!"" 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

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

Upgrades and Setuphandlers

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

PLONE SYMPOSIUM EAST 2012Setuphandlersfrom 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': '[email protected]', 'fullname': 'Site Staff', 'username': 'staff' } } ] sfutils.addUserAccounts(members)

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

PLONE SYMPOSIUM EAST 2012Setuphandlers

<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>

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

PLONE SYMPOSIUM EAST 2012Setuphandlers

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')

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

PLONE SYMPOSIUM EAST 2012Setuphandlers

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')

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

PLONE SYMPOSIUM EAST 2012Upgrades <!-- 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" />

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

PLONE SYMPOSIUM EAST 2012from zope.app.component.hooks import getSitefrom Products.CMFCore.utils import getToolByNamefrom 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')

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

PLONE SYMPOSIUM EAST 2012from zope.app.component.hooks import getSite

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()

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

Plone Site Recipe

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

PLONE SYMPOSIUM EAST 2012What is it?

• Create a Plone site

• Run profiles

• Re-create a site

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

PLONE SYMPOSIUM EAST 2012Add it to buildout

[buildout]parts = plonesite

[plonesite]recipe = collective.recipe.plonesiteinstance = instancezeoserver = zeoserversite-id = Ploneadmin-user = admin

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

PLONE SYMPOSIUM EAST 2012Add profiles

[plonesite]...profiles-initial = pse12.policy:initialprofiles = pse12.policy:default

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

PLONE SYMPOSIUM EAST 2012Buildout run

$ bin/buildout install plonesiteInstalling plonesite.Retrieved the admin userAdded Plone SiteQuick installing: []Running profiles: ['pse12.policy:initial']FinishedRunning profiles: ['pse12.policy:default', 'sixfeetup.customfolderalert:default', 'plone.app.debugtoolbar:default']

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

PLONE SYMPOSIUM EAST 2012Dynamic options

$ bin/buildout plonesite:enabled=false

$ bin/buildout plonesite:site-replace=true

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

Upgrade Demo

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

PLONE SYMPOSIUM EAST 2012Links

• 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/)

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

PLONE SYMPOSIUM EAST 2012Photo Credits• 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

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

Check out

sixfeetup.com/demos

Questions?