Using Buildout, GenericSetup and a Policy Package to Rule the World
Upcoming SlideShare
Loading in...5
×
 

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

on

  • 898 views

So you have your code on the filesystem and you are using buildout;...

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 the
amount of manual steps needed to create and maintain your site. Using
collective.recipe.plonesite, you can ensure that every member of your
team is working on an identical Plone site at any given time.

Without the plonesite recipe, when you run your buildout for the first
time, you are left with an empty Zope site. This talk will show you how
to utilize buildout to create a Plone site for you and make sure it is
all set up via a policy package and GenericSetup so you can hit the
ground running.

Statistics

Views

Total Views
898
Views on SlideShare
810
Embed Views
88

Actions

Likes
3
Downloads
15
Comments
0

2 Embeds 88

http://www.scoop.it 84
http://coderwall.com 4

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

  • Using Buildout,GenericSetup and a PolicyPackage 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(upse12.policy:default)
  • Setuphandlers PLONE SYMPOSIUM EAST 2012from sixfeetup.utils import helpers as sfutilsdef 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(upse12.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 2012from Products.CMFCore.utils import getToolByNamefrom sixfeetup.utils import helpers as sfutilsdef intranet_setup(context): """Set up the placeful workflow for the intranet """ portal = getSite() # If the intranet doesnt 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 2012def 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 doesnt 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 doesnt 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 .comsi xfee