{ "info": { "author": "4teamwork AG", "author_email": "mailto:info@4teamwork.ch", "bugtrack_url": null, "classifiers": [ "Framework :: Buildout :: Recipe", "Intended Audience :: Developers", "License :: OSI Approved :: Zope Public License", "Programming Language :: Python", "Topic :: Software Development :: Build Tools" ], "description": ".. contents::\n\nIntroduction\n============\n\nThis recipe provides support for configuring various unix services when\ndeploying Plone/Zope2 with buildout.\n\nAs for now the following features are provided:\n\n* Create Logrotate configuration for all Zope 2 instance and ZEO parts,\n as well as ``ftw.structlog`` logfiles.\n\n* Create RedHat-like run-control scripts.\n\n* Create packall script for packing of all storages.\n\n* Create filebeat prospector configs for ``ftw.structlog`` and\n ``ftw.contentstats`` logs.\n\n\nSupported options\n=================\n\nThe recipe supports the following options:\n\nlogrotate-directory\n The directory where the logrotate configuration file will be created.\n Defaults to ``${buildout:directory}/etc/logrotate.d``. Add this parameter\n with no arguments to supress generation of logrotate configuration.\n\n If this parameter is set, this recipe will create logrotate configs for\n all Zope 2 instance and ZEO parts that are present, and (unconditionally)\n a logrotate config for ``ftw.structlog`` logfiles.\n\nlogrotate-options\n A list of logrotate options that should be added to the logrotate\n configuration.\n\n Configuration for reopening rotated logfiles is added automatically if\n ``postrotate`` is not specified in ``logrotate-options``.\n\n Example::\n\n logrotate-options =\n rotate 4\n weekly\n missingok\n notifempty\n nomail\n\n The logrotate config for ``ftw.structlog`` logfiles will be created with\n settings similar to the other logfiles, except:\n\n * No ``postrotate`` script will be automatically inserted if not already\n present in ``logrotate-options``\n * ``missingok`` will always be included\n * Rotation mode will always be ``copytruncate``, and ``nocopytruncate``\n will be ignored\n\nstartup-directory\n If specified, a start script is created in the given directory.\n Generation of run-control scripts is disabled if this option is present.\n\nshutdown-directory\n If specified, a shutdown script is created in the given directory.\n Generation of run-control scripts is disabled if this option is present.\n\nrc-directory\n The directory where run-control scripts should be installed.\n Defaults to ``${buildout:directory}/bin``. Add this parameter with no\n arguments to supress generation of run-control scripts.\n\nrc-prefix\n Name prefix for run-control scripts. Defaults to ``rc-``.\n\nrc-user\n The name of the user used to start processes by run-control scripts.\n Defaults to ``zope``.\n\nhas-supervisor\n Boolean indication whether supervisor is beeing used. If true, a run\n control script is generated for supervisor only. If false, run control\n scripts are generated for all zope and zeo parts. By default, the recipe\n tries to automatically determine if supervisor is beeing used.\n\nzopes\n A list of Zope 2 instance parts. Defaults to all parts using the\n ``plone.recipe.zope2instance`` recipe.\n\nzeos\n A list of ZEO server parts. Defaults to all parts using either the\n ``plone.recipe.zeoserver`` or ``plone.recipe.zope2zeoserver`` recipe.\n\npackall-symlink-directory\n Creates a symlink to the packall script in the given directory. Can\n be used to automate packing for multiple deployments.\n\ncreate-filebeat-config\n Boolean to indicate whether a filebeat config should be created for this\n deployment. Defaults to true. Set to ``false`` to suppress creation of\n a filebeat config.\n\n\nLinks\n=====\n\n- Github: https://github.com/4teamwork/ftw.recipe.deployment\n- Issues: https://github.com/4teamwork/ftw.recipe.deployment/issues\n- Pypi: http://pypi.python.org/pypi/ftw.recipe.deployment\n- Continuous integration: https://jenkins.4teamwork.ch/search?q=ftw.recipe.deployment\n\n\nCopyright\n---------\n\nThis package is copyright by `4teamwork `_.\n\n``ftw.recipe.deployment`` is licensed under GNU General Public License, version 2.\n\nChangelog\n=========\n\n1.4.3 (2019-02-04)\n------------------\n\n- Skip duplicate zope parts when generating logrotate config.\n [lgraf]\n\n\n1.4.2 (2019-02-04)\n------------------\n\n- Add option to suppress creation of filebeat config.\n [lgraf]\n\n\n1.4.1 (2018-01-10)\n------------------\n\n- Only chmod scripts to executable if they're not already executable.\n [buchi]\n\n\n1.4.0 (2017-12-08)\n------------------\n\n- Generate filebeat prospector configs for ftw.structlog and\n ftw.contentstats logs.\n [lgraf]\n\n- Respect current umask when making scripts executable.\n [buchi]\n\n\n1.3.0 (2017-09-11)\n------------------\n\n- Generate logrotate config for ftw.structlog's logfiles.\n [lgraf]\n\n\n1.2.0 (2016-02-10)\n------------------\n\n- Let ``bin/packall`` log on success to ``var/log/pack.log``.\n [jone]\n\n- Add option to create startup and shutdown scripts in a global\n directory instead of run-control scripts.\n [buchi]\n\n- Create packall script for packing of all storages.\n [buchi]\n\n- Fix handling of logrotate options in buildout 2.x by no longer dropping the\n first option.\n [buchi]\n\n\n1.1.1 (2014-01-21)\n------------------\n\n- Make postrotate command fail silently if pid file is missing.\n [buchi]\n\n\n1.1 (2013-03-05)\n----------------\n\n- Added option to specify the user under which run-control scripts start\n processes.\n [buchi]\n\n- Added status command to supervisor run-control script.\n [buchi]\n\n\n1.0.1 (2012-03-12)\n------------------\n\n- Fixed handling of logrotate options containing whitespaces.\n [buchi]\n\n\n1.0 (2012-03-12)\n----------------\n\n- Initial release.\n [buchi]\n\nExample usage\n=============\n\nFirst we create a fake ``plone.recipe.zope2instance`` recipe, which we can\nuse in our tests.\n\nCreate a recipes source directory::\n\n >>> mkdir(sample_buildout, 'plone.recipe.zope2instance')\n\nand then create a source file with the fake recipe::\n\n >>> write(sample_buildout, 'plone.recipe.zope2instance',\n ... 'zope2instance.py',\n ... \"\"\"\n ... import os, zc.buildout\n ...\n ... class Recipe(object):\n ...\n ... def __init__(self, buildout, name, options):\n ... self.name, self.options = name, options\n ... options['event-log'] = os.path.join(\n ... buildout['buildout']['directory'],\n ... 'var', 'log', self.name + '.log'\n ... )\n ... options['z2-log'] = os.path.join(\n ... buildout['buildout']['directory'],\n ... 'var', 'log', self.name + '-Z2.log'\n ... )\n ...\n ... def install(self):\n ... return tuple()\n ...\n ... def update(self):\n ... pass\n ... \"\"\")\n\nProvide packaging information so that the recipe can be installed as a develop\negg::\n\n >>> write(sample_buildout, 'plone.recipe.zope2instance', 'setup.py',\n ... \"\"\"\n ... from setuptools import setup\n ...\n ... setup(\n ... name = \"plone.recipe.zope2instance\",\n ... entry_points = {'zc.buildout': ['default = zope2instance:Recipe']},\n ... )\n ... \"\"\")\n\nAdd a README.txt to avoid an annoying warning from distutils::\n\n >>> write(sample_buildout, 'plone.recipe.zope2instance', 'README.txt', \" \")\n\nWe'll start by creating a simple buildout that uses our recipe::\n\n >>> write('buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... develop = plone.recipe.zope2instance\n ... parts = instance1 deployment\n ...\n ... [instance1]\n ... recipe = plone.recipe.zope2instance\n ...\n ... [deployment]\n ... recipe = ftw.recipe.deployment\n ... \"\"\")\n\nRunning the buildout gives us::\n\n >>> print system(buildout)\n Develop: '/sample-buildout/plone.recipe.zope2instance'\n Installing instance1.\n Installing deployment.\n \n\nWe should now have a file with the same name as our buildout directory\ncontaining our logrotate configuration::\n\n >>> cat(sample_buildout, 'etc', 'logrotate.d', 'sample-buildout')\n ... #doctest: -NORMALIZE_WHITESPACE\n /sample-buildout/var/log/instance1.log\n /sample-buildout/var/log/instance1-Z2.log {\n sharedscripts\n postrotate\n /bin/kill -SIGUSR2 `cat /sample-buildout/var/instance1.pid 2>/dev/null` >/dev/null 2>&1 || true\n endscript\n }\n /sample-buildout/var/log/instance1-json.log {\n copytruncate\n missingok\n }\n\nWe should also have a run-control script for instance1::\n\n >>> ls(sample_buildout, 'bin')\n - buildout\n - rc-instance1\n\n >>> cat(sample_buildout, 'bin', 'rc-instance1')\n #!/bin/sh\n \n # chkconfig: 345 90 10\n # description: Starts Zope\n \n START_SCRIPT=\"/sample-buildout/bin/instance1\"\n \n [ -f $START_SCRIPT ] || exit 1\n \n # Source function library.\n . /etc/init.d/functions\n \n RETVAL=0\n \n if [ $(whoami) != \"root\" ]; then\n echo \"You must be root.\"\n exit 1\n fi\n \n case $1 in\n start|stop)\n su zope -c \"$START_SCRIPT $*\" >> cat(sample_buildout, 'etc', 'filebeat.d', 'sample-buildout.yml')\n ... #doctest: -NORMALIZE_WHITESPACE\n - type: log\n fields:\n event_type: contentstats\n deployment: sample-buildout\n fields_under_root: true\n json.keys_under_root: true\n json.add_error_key: true\n paths:\n - /sample-buildout/var/log/contentstats-json.log\n - type: log\n fields:\n event_type: structlog\n deployment: sample-buildout\n fields_under_root: true\n json.keys_under_root: true\n json.add_error_key: true\n paths:\n - /sample-buildout/var/log/instance1-json.log\n\nExcept if we specifically disable creation of the filebeat config::\n\n >>> write('buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... develop = plone.recipe.zope2instance\n ... parts = instance1 deployment\n ...\n ... [instance1]\n ... recipe = plone.recipe.zope2instance\n ...\n ... [deployment]\n ... recipe = ftw.recipe.deployment\n ... create-filebeat-config = false\n ... \"\"\")\n\nAnd then run buildout again::\n\n >>> print system(buildout)\n Develop: '/sample-buildout/plone.recipe.zope2instance'\n Uninstalling deployment.\n Updating instance1.\n Installing deployment.\n \n\nWe should NOT have a filebeat config for our deployment::\n\n >>> import os\n >>> os.path.isfile(os.path.join(sample_buildout, 'etc', 'filebeat.d', 'sample-buildout.yml'))\n False\n\nIf we mistakenly add duplicate plone.recipe.zope2instance instances to parts::\n\n >>> write('buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... develop = plone.recipe.zope2instance\n ... parts = instance1 instance1 instance1 instance1 instance1 deployment\n ...\n ... [instance1]\n ... recipe = plone.recipe.zope2instance\n ...\n ... [deployment]\n ... recipe = ftw.recipe.deployment\n ... \"\"\")\n\nRunning buildout will print a warning::\n\n >>> print system(buildout)\n Develop: '/sample-buildout/plone.recipe.zope2instance'\n ftw.recipe.deployment:\n ##########################################################\n # Duplicate zope parts found!\n # ['instance1', 'instance1', 'instance1', 'instance1', 'instance1']\n # This could be caused by extending from multiple zeoclients/\n # .cfg files instead of just one, and should be avoided.\n # To prevent generating invalid logrotate configs, duplicate\n # parts will be skipped, but you should still fix this issue.\n ##########################################################\n \n Uninstalling deployment.\n Updating instance1.\n Installing deployment.\n \n\nAnd we still end up with a valid logrotate config (no duplicated paths)::\n\n >>> cat(sample_buildout, 'etc', 'logrotate.d', 'sample-buildout')\n ... #doctest: -NORMALIZE_WHITESPACE\n /sample-buildout/var/log/instance1.log\n /sample-buildout/var/log/instance1-Z2.log {\n sharedscripts\n postrotate\n /bin/kill -SIGUSR2 `cat /sample-buildout/var/instance1.pid 2>/dev/null` >/dev/null 2>&1 || true\n endscript\n }\n /sample-buildout/var/log/instance1-json.log {\n copytruncate\n missingok\n }\n\nLet's also add a zeo part. Thus we first need a fake ``plone.recipe.zeoserver``\nrecipe::\n\n >>> mkdir(sample_buildout, 'plone.recipe.zeoserver')\n >>> write(sample_buildout, 'plone.recipe.zeoserver', 'zeoserver.py',\n ... \"\"\"\n ... import os, zc.buildout\n ...\n ... class Recipe(object):\n ...\n ... def __init__(self, buildout, name, options):\n ... self.name, self.options = name, options\n ... options['zeo-log'] = os.path.join(\n ... buildout['buildout']['directory'],\n ... 'var', 'log', self.name + '.log'\n ... )\n ... self.storage_number = options.get('storage-number', '1')\n ... self.blob_storage = options.get('blob-storage', '')\n ...\n ... def install(self):\n ... return tuple()\n ...\n ... def update(self):\n ... pass\n ... \"\"\")\n >>> write(sample_buildout, 'plone.recipe.zeoserver', 'setup.py',\n ... \"\"\"\n ... from setuptools import setup\n ...\n ... setup(\n ... name = \"plone.recipe.zeoserver\",\n ... entry_points = {'zc.buildout': ['default = zeoserver:Recipe']},\n ... )\n ... \"\"\")\n >>> write(sample_buildout, 'plone.recipe.zeoserver', 'README.txt', \" \")\n\nCreate a buildout with multiple instance parts and a zeo part::\n\n >>> write('buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... develop = plone.recipe.zope2instance plone.recipe.zeoserver\n ... parts = instance1 instance2 zeo deployment\n ...\n ... [instance1]\n ... recipe = plone.recipe.zope2instance\n ...\n ... [instance2]\n ... <= instance1\n ...\n ... [zeo]\n ... recipe = plone.recipe.zeoserver\n ...\n ... [deployment]\n ... recipe = ftw.recipe.deployment\n ... \"\"\")\n\nRunning the buildout gives us::\n\n >>> print system(buildout)\n Develop: '/sample-buildout/plone.recipe.zope2instance'\n Develop: '/sample-buildout/plone.recipe.zeoserver'\n Updating instance1.\n Installing instance2.\n Installing zeo.\n Updating deployment.\n \n\nVerify the contents of the logrotate configuration file::\n\n >>> cat(sample_buildout, 'etc', 'logrotate.d', 'sample-buildout')\n /sample-buildout/var/log/instance1.log\n /sample-buildout/var/log/instance1-Z2.log {\n sharedscripts\n postrotate\n /bin/kill -SIGUSR2 `cat /sample-buildout/var/instance1.pid 2>/dev/null` >/dev/null 2>&1 || true\n endscript\n }\n /sample-buildout/var/log/instance2.log\n /sample-buildout/var/log/instance2-Z2.log {\n sharedscripts\n postrotate\n /bin/kill -SIGUSR2 `cat /sample-buildout/var/instance2.pid 2>/dev/null` >/dev/null 2>&1 || true\n endscript\n }\n /sample-buildout/var/log/zeo.log {\n copytruncate\n }\n /sample-buildout/var/log/instance1-json.log {\n copytruncate\n missingok\n }\n /sample-buildout/var/log/instance2-json.log {\n copytruncate\n missingok\n }\n\nVerify the zeo run control script::\n\n >>> cat(sample_buildout, 'bin', 'rc-zeo')\n #!/bin/sh\n \n # chkconfig: 345 85 15\n # description: Starts ZEO server\n \n START_SCRIPT=\"/sample-buildout/bin/zeo\"\n \n [ -f $START_SCRIPT ] || exit 1\n \n # Source function library.\n . /etc/init.d/functions\n \n RETVAL=0\n \n if [ $(whoami) != \"root\" ]; then\n echo \"You must be root.\"\n exit 1\n fi\n \n case $1 in\n start|stop)\n su zope -c \"$START_SCRIPT $*\" >> cat(sample_buildout, 'bin', 'rc-instance2')\n #!/bin/sh\n \n # chkconfig: 345 90 10\n # description: Starts Zope\n \n START_SCRIPT=\"/sample-buildout/bin/instance2\"\n \n [ -f $START_SCRIPT ] || exit 1\n \n # Source function library.\n . /etc/init.d/functions\n \n RETVAL=0\n \n if [ $(whoami) != \"root\" ]; then\n echo \"You must be root.\"\n exit 1\n fi\n \n case $1 in\n start|stop)\n su zope -c \"$START_SCRIPT $*\" >> cat(sample_buildout, 'bin', 'packall')\n #!/bin/sh\n /sample-buildout/bin/zeopack -S 1 -B /sample-buildout/var/blobstorage \\\n && echo `date +%Y-%m-%dT%H:%M:%S%z` \"packed Data (blobstorage)\" >> /sample-buildout/var/log/pack.log\n\nWe can specify the user that should be used to run processes::\n\n >>> write('buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... develop = plone.recipe.zope2instance plone.recipe.zeoserver\n ... parts = instance1 instance2 zeo deployment\n ...\n ... [instance1]\n ... recipe = plone.recipe.zope2instance\n ...\n ... [instance2]\n ... <= instance1\n ...\n ... [zeo]\n ... recipe = plone.recipe.zeoserver\n ...\n ... [deployment]\n ... recipe = ftw.recipe.deployment\n ... rc-user = plone\n ... \"\"\")\n\nRunning the buildout gives us::\n\n >>> print system(buildout)\n Develop: '/sample-buildout/plone.recipe.zope2instance'\n Develop: '/sample-buildout/plone.recipe.zeoserver'\n Uninstalling deployment.\n Updating instance1.\n Updating instance2.\n Updating zeo.\n Installing deployment.\n \n\nVerify the run control script for instance 1::\n\n >>> cat(sample_buildout, 'bin', 'rc-instance1')\n #!/bin/sh\n \n # chkconfig: 345 90 10\n # description: Starts Zope\n \n START_SCRIPT=\"/sample-buildout/bin/instance1\"\n \n [ -f $START_SCRIPT ] || exit 1\n \n # Source function library.\n . /etc/init.d/functions\n \n RETVAL=0\n \n if [ $(whoami) != \"root\" ]; then\n echo \"You must be root.\"\n exit 1\n fi\n \n case $1 in\n start|stop)\n su plone -c \"$START_SCRIPT $*\" >> mkdir(sample_buildout, 'collective.recipe.supervisor')\n >>> write(sample_buildout, 'collective.recipe.supervisor', 'supervisor.py',\n ... \"\"\"\n ... import os, zc.buildout\n ...\n ... class Recipe(object):\n ...\n ... def __init__(self, buildout, name, options):\n ... pass\n ...\n ... def install(self):\n ... return tuple()\n ...\n ... def update(self):\n ... pass\n ... \"\"\")\n >>> write(sample_buildout, 'collective.recipe.supervisor', 'setup.py',\n ... \"\"\"\n ... from setuptools import setup\n ...\n ... setup(\n ... name = \"collective.recipe.supervisor\",\n ... entry_points = {'zc.buildout': ['default = supervisor:Recipe']},\n ... )\n ... \"\"\")\n >>> write(sample_buildout, 'collective.recipe.supervisor', 'README.txt',\n ... \" \")\n\nCreate a buildout with a supervisor part::\n\n >>> write('buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... develop =\n ... plone.recipe.zope2instance\n ... plone.recipe.zeoserver\n ... collective.recipe.supervisor\n ... parts = instance1 instance2 zeo supervisor deployment\n ...\n ... [instance1]\n ... recipe = plone.recipe.zope2instance\n ...\n ... [instance2]\n ... <= instance1\n ...\n ... [zeo]\n ... recipe = plone.recipe.zeoserver\n ...\n ... [supervisor]\n ... recipe = collective.recipe.supervisor\n ...\n ... [deployment]\n ... recipe = ftw.recipe.deployment\n ... rc-user = plone\n ... \"\"\")\n\nRunning the buildout gives us::\n\n >>> print system(buildout)\n Develop: '/sample-buildout/plone.recipe.zope2instance'\n Develop: '/sample-buildout/plone.recipe.zeoserver'\n Develop: '/sample-buildout/collective.recipe.supervisor'\n Updating instance1.\n Updating instance2.\n Updating zeo.\n Installing supervisor.\n Updating deployment.\n \n\nVerify the supervisor control script::\n\n >>> cat(sample_buildout, 'bin', 'rc-supervisor')\n #!/bin/sh\n \n # chkconfig: 345 90 10\n # description: Starts supervisor\n \n SUPERVISORCTL=\"/sample-buildout/bin/supervisorctl\"\n SUPERVISORD=\"/sample-buildout/bin/supervisord\"\n \n [ -f $SUPERVISORD ] || exit 1\n [ -f $SUPERVISORCTL ] || exit 1\n \n # Source function library.\n . /etc/init.d/functions\n \n RETVAL=0\n \n if [ $(whoami) != \"root\" ]; then\n echo \"You must be root.\"\n exit 1\n fi\n \n start() {\n echo -n \"Starting supervisor: \"\n su plone -c \"$SUPERVISORD\"\n RETVAL=$?\n if [ $RETVAL -eq 0 ]; then\n echo_success\n else\n echo_failure\n fi\n return $RETVAL\n }\n \n stop() {\n echo -n \"Stopping supervisor: \"\n su plone -c \"$SUPERVISORCTL shutdown\"\n RETVAL=$?\n if [ $RETVAL -eq 0 ]; then\n echo_success\n else\n echo_failure\n fi\n return $RETVAL\n }\n \n status() {\n su plone -c \"$SUPERVISORCTL status\"\n }\n \n case \"$1\" in\n start)\n start\n ;;\n \n stop)\n stop\n ;;\n \n restart)\n stop\n start\n ;;\n \n status)\n status\n ;;\n esac\n \n exit $REVAL\n\nWe can provide some additional logrotate options::\n\n >>> write('buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... develop =\n ... plone.recipe.zope2instance\n ... plone.recipe.zeoserver\n ... collective.recipe.supervisor\n ...\n ... parts = instance1 deployment\n ...\n ... [instance1]\n ... recipe = plone.recipe.zope2instance\n ...\n ... [deployment]\n ... recipe = ftw.recipe.deployment\n ... logrotate-options =\n ... rotate 4\n ... weekly\n ... missingok\n ... notifempty\n ... nomail\n ... \"\"\")\n\nRunning the buildout gives us::\n\n >>> print system(buildout)\n Develop: '/sample-buildout/plone.recipe.zope2instance'\n Develop: '/sample-buildout/plone.recipe.zeoserver'\n Develop: '/sample-buildout/collective.recipe.supervisor'\n Uninstalling deployment.\n Uninstalling supervisor.\n Uninstalling zeo.\n Uninstalling instance2.\n Updating instance1.\n Installing deployment.\n \n\nVerify that the file contains our logrotate options::\n\n >>> cat(sample_buildout, 'etc', 'logrotate.d', 'sample-buildout')\n ... #doctest: -NORMALIZE_WHITESPACE\n /sample-buildout/var/log/instance1.log\n /sample-buildout/var/log/instance1-Z2.log {\n rotate 4\n weekly\n missingok\n notifempty\n nomail\n sharedscripts\n postrotate\n /bin/kill -SIGUSR2 `cat /sample-buildout/var/instance1.pid 2>/dev/null` >/dev/null 2>&1 || true\n endscript\n }\n /sample-buildout/var/log/instance1-json.log {\n rotate 4\n weekly\n missingok\n notifempty\n nomail\n copytruncate\n }\n\nWe can provide custom storage options::\n\n >>> write('buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... develop = plone.recipe.zope2instance plone.recipe.zeoserver\n ... parts = instance1 zeo deployment\n ...\n ... [instance1]\n ... recipe = plone.recipe.zope2instance\n ...\n ... [zeo]\n ... recipe = plone.recipe.zeoserver\n ... storage-number = main\n ... blob-storage = blobstorage-main\n ...\n ... [deployment]\n ... recipe = ftw.recipe.deployment\n ... \"\"\")\n\nRunning the buildout gives us::\n\n >>> print system(buildout)\n Develop: '/sample-buildout/plone.recipe.zope2instance'\n Develop: '/sample-buildout/plone.recipe.zeoserver'\n Uninstalling deployment.\n Updating instance1.\n Installing zeo.\n Installing deployment.\n \n\nOur packall script should contain the correct storage parameters::\n\n >>> cat(sample_buildout, 'bin', 'packall')\n #!/bin/sh\n /sample-buildout/bin/zeopack -S main -B /sample-buildout/var/blobstorage-main \\\n && echo `date +%Y-%m-%dT%H:%M:%S%z` \"packed main (blobstorage-main)\" >> /sample-buildout/var/log/pack.log\n\nLet's add a filestorage part. Thus we first need a fake ``collective.recipe.filestorage``\nrecipe::\n\n >>> mkdir(sample_buildout, 'collective.recipe.filestorage')\n >>> write(sample_buildout, 'collective.recipe.filestorage', 'filestorage.py',\n ... \"\"\"\n ... import os, zc.buildout\n ...\n ... class Recipe(object):\n ...\n ... def __init__(self, buildout, name, options):\n ... self.name, self.options = name, options\n ... self.subparts = options.get('parts', '').split()\n ...\n ... def install(self):\n ... return tuple()\n ...\n ... def update(self):\n ... pass\n ... \"\"\")\n >>> write(sample_buildout, 'collective.recipe.filestorage', 'setup.py',\n ... \"\"\"\n ... from setuptools import setup\n ...\n ... setup(\n ... name = \"collective.recipe.filestorage\",\n ... entry_points = {'zc.buildout': ['default = filestorage:Recipe']},\n ... )\n ... \"\"\")\n >>> write(sample_buildout, 'collective.recipe.filestorage', 'README.txt', \" \")\n\nCreate a buildout with a filestorage part::\n\n >>> write('buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... develop = plone.recipe.zope2instance plone.recipe.zeoserver collective.recipe.filestorage\n ... parts = instance1 zeo filestorage deployment\n ...\n ... [instance1]\n ... recipe = plone.recipe.zope2instance\n ...\n ... [zeo]\n ... recipe = plone.recipe.zeoserver\n ...\n ... [filestorage]\n ... recipe = collective.recipe.filestorage\n ... parts = storage1\n ...\n ... [deployment]\n ... recipe = ftw.recipe.deployment\n ... \"\"\")\n\nRunning the buildout gives us::\n\n >>> print system(buildout)\n Develop: '/sample-buildout/plone.recipe.zope2instance'\n Develop: '/sample-buildout/plone.recipe.zeoserver'\n Develop: '/sample-buildout/collective.recipe.filestorage'\n Uninstalling zeo.\n Updating instance1.\n Installing zeo.\n Installing filestorage.\n Updating deployment.\n \n\nOur packall script should contain pack commands for all storages::\n\n >>> cat(sample_buildout, 'bin', 'packall')\n #!/bin/sh\n /sample-buildout/bin/zeopack -S 1 -B /sample-buildout/var/blobstorage \\\n && echo `date +%Y-%m-%dT%H:%M:%S%z` \"packed Data (blobstorage)\" >> /sample-buildout/var/log/pack.log\n /sample-buildout/bin/zeopack -S storage1 \\\n && echo `date +%Y-%m-%dT%H:%M:%S%z` \"packed storage1\" >> /sample-buildout/var/log/pack.log\n\nLet's create a buildout with multiple filestorages and blobs::\n\n >>> write('buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... develop = plone.recipe.zope2instance plone.recipe.zeoserver collective.recipe.filestorage\n ... parts = instance1 zeo filestorage deployment\n ...\n ... [instance1]\n ... recipe = plone.recipe.zope2instance\n ...\n ... [zeo]\n ... recipe = plone.recipe.zeoserver\n ...\n ... [filestorage]\n ... recipe = collective.recipe.filestorage\n ... parts = storage1 storage2\n ... blob-storage = var/blobstorage-%(fs_part_name)s\n ... zeo-storage = %(fs_part_name)s_storage\n ...\n ... [deployment]\n ... recipe = ftw.recipe.deployment\n ... \"\"\")\n\nRunning the buildout gives us::\n\n >>> print system(buildout)\n Develop: '/sample-buildout/plone.recipe.zope2instance'\n Develop: '/sample-buildout/plone.recipe.zeoserver'\n Develop: '/sample-buildout/collective.recipe.filestorage'\n Uninstalling filestorage.\n Updating instance1.\n Updating zeo.\n Installing filestorage.\n Updating deployment.\n \n\nOur packall script should contain pack commands for all storages::\n\n >>> cat(sample_buildout, 'bin', 'packall')\n #!/bin/sh\n /sample-buildout/bin/zeopack -S 1 -B /sample-buildout/var/blobstorage \\\n && echo `date +%Y-%m-%dT%H:%M:%S%z` \"packed Data (blobstorage)\" >> /sample-buildout/var/log/pack.log\n /sample-buildout/bin/zeopack -S storage1_storage -B /sample-buildout/var/blobstorage-storage1 \\\n && echo `date +%Y-%m-%dT%H:%M:%S%z` \"packed storage1_storage (blobstorage-storage1)\" >> /sample-buildout/var/log/pack.log\n /sample-buildout/bin/zeopack -S storage2_storage -B /sample-buildout/var/blobstorage-storage2 \\\n && echo `date +%Y-%m-%dT%H:%M:%S%z` \"packed storage2_storage (blobstorage-storage2)\" >> /sample-buildout/var/log/pack.log\n\nCreate a buildout with the packall-symlink-directory option::\n\n >>> write('buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... develop = plone.recipe.zope2instance plone.recipe.zeoserver collective.recipe.filestorage\n ... parts = instance1 zeo deployment\n ...\n ... [instance1]\n ... recipe = plone.recipe.zope2instance\n ...\n ... [zeo]\n ... recipe = plone.recipe.zeoserver\n ...\n ... [deployment]\n ... recipe = ftw.recipe.deployment\n ... packall-symlink-directory = etc/zodbpack.d\n ... \"\"\")\n\nRunning the buildout gives us::\n\n >>> print system(buildout)\n Develop: '/sample-buildout/plone.recipe.zope2instance'\n Develop: '/sample-buildout/plone.recipe.zeoserver'\n Develop: '/sample-buildout/collective.recipe.filestorage'\n Uninstalling deployment.\n Uninstalling filestorage.\n Updating instance1.\n Updating zeo.\n Installing deployment.\n \n\nWe should now have a symlink in the given directory::\n\n >>> ls(sample_buildout, 'etc', 'zodbpack.d')\n l sample-buildout\n\nCreate a buildout with startup/shutdown directory option::\n\n >>> write('buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... develop = plone.recipe.zope2instance plone.recipe.zeoserver collective.recipe.supervisor\n ... parts = instance1 zeo supervisor deployment\n ...\n ... [instance1]\n ... recipe = plone.recipe.zope2instance\n ...\n ... [zeo]\n ... recipe = plone.recipe.zeoserver\n ...\n ... [supervisor]\n ... recipe = collective.recipe.supervisor\n ...\n ... [deployment]\n ... recipe = ftw.recipe.deployment\n ... startup-directory = etc/startup.d\n ... shutdown-directory = etc/shutdown.d\n ... \"\"\")\n\nRunning the buildout gives us::\n\n >>> print system(buildout)\n Develop: '/sample-buildout/plone.recipe.zope2instance'\n Develop: '/sample-buildout/plone.recipe.zeoserver'\n Develop: '/sample-buildout/collective.recipe.supervisor'\n Uninstalling deployment.\n Updating instance1.\n Updating zeo.\n Installing supervisor.\n Installing deployment.\n\nVerify the startup script::\n\n >>> cat(sample_buildout, 'etc', 'startup.d', 'sample-buildout')\n #!/bin/sh\n /sample-buildout/bin/supervisord\n\nVerify the shutdown script::\n\n >>> cat(sample_buildout, 'etc', 'shutdown.d', 'sample-buildout')\n #!/bin/sh\n /sample-buildout/bin/supervisorctl shutdown", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/4teamwork/ftw.recipe.deployment", "keywords": "", "license": "GPL2", "maintainer": "", "maintainer_email": "", "name": "ftw.recipe.deployment", "package_url": "https://pypi.org/project/ftw.recipe.deployment/", "platform": "", "project_url": "https://pypi.org/project/ftw.recipe.deployment/", "project_urls": { "Homepage": "https://github.com/4teamwork/ftw.recipe.deployment" }, "release_url": "https://pypi.org/project/ftw.recipe.deployment/1.4.3/", "requires_dist": null, "requires_python": "", "summary": "A zc.buildout recipe for Plone deployments which configures various unix system services.", "version": "1.4.3" }, "last_serial": 5823446, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "e7c994ec1502019b68b25285baa9392f", "sha256": "8a6cf0b2085fb9c0316751a469f396f94507b5494d820aeece3447db0296b822" }, "downloads": -1, "filename": "ftw.recipe.deployment-1.0.tar.gz", "has_sig": false, "md5_digest": "e7c994ec1502019b68b25285baa9392f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9201, "upload_time": "2012-03-12T13:53:29", "url": "https://files.pythonhosted.org/packages/ee/12/003717b768aafa5199f2d7be743dc6e6716c89cba4bc9825b59594a36d35/ftw.recipe.deployment-1.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "4292c84560ed762e4321b4dd57f565d8", "sha256": "501cf990103d1c3c971d74e0408133848118423454773fdc0e1fc0beaeac2e7c" }, "downloads": -1, "filename": "ftw.recipe.deployment-1.0.1.tar.gz", "has_sig": false, "md5_digest": "4292c84560ed762e4321b4dd57f565d8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9693, "upload_time": "2012-03-12T14:42:31", "url": "https://files.pythonhosted.org/packages/32/32/effc5c59643051b76cdc12f644b64a89e29f7dc11e8c4b44f2a0533f4c70/ftw.recipe.deployment-1.0.1.tar.gz" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "33882db7c0d08b8a3ee9ba74cfc62f1e", "sha256": "1e09eb39d4d387f55cac3f02c00e81ef0aa69571283b62937de4d30867920c73" }, "downloads": -1, "filename": "ftw.recipe.deployment-1.1.tar.gz", "has_sig": false, "md5_digest": "33882db7c0d08b8a3ee9ba74cfc62f1e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18277, "upload_time": "2013-03-05T14:46:51", "url": "https://files.pythonhosted.org/packages/74/d7/7fcaf589f691a4883030bdc61c6aa00705e7c1e439dbc6779643a73703dc/ftw.recipe.deployment-1.1.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "cc4aba7966142d7cdde97ffc0cc8db3f", "sha256": "900f57c21eaa14a0dcc674b84e842324f914bb4f8f2f974145a8109adb72c449" }, "downloads": -1, "filename": "ftw.recipe.deployment-1.1.1.zip", "has_sig": false, "md5_digest": "cc4aba7966142d7cdde97ffc0cc8db3f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28149, "upload_time": "2014-01-21T12:49:03", "url": "https://files.pythonhosted.org/packages/e9/b6/8f6268764f6ce4cb1c4630d2219ad2453cb3235ef70817b627cb108d715d/ftw.recipe.deployment-1.1.1.zip" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "7bc2f13fc3c393fc54b0434cdaaa8073", "sha256": "f4bb1cd676fea12bc673244c99582d877f4adf2847d8b336eb5b7bc6a1c463eb" }, "downloads": -1, "filename": "ftw.recipe.deployment-1.2.0.tar.gz", "has_sig": false, "md5_digest": "7bc2f13fc3c393fc54b0434cdaaa8073", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21626, "upload_time": "2016-02-10T15:07:18", "url": "https://files.pythonhosted.org/packages/14/17/0ea8899f49e2f0d6cf139202f85e2cd1e90e3a7bef71087d13d969e99c4e/ftw.recipe.deployment-1.2.0.tar.gz" } ], "1.3.0": [ { "comment_text": "", "digests": { "md5": "5059eee467441ebdce8acf2b5c35ba4d", "sha256": "c8b06d627230d2bd92f2bd6f0adb8cdf6fc8fd526109b39d5e9f781fa790a42c" }, "downloads": -1, "filename": "ftw.recipe.deployment-1.3.0.tar.gz", "has_sig": false, "md5_digest": "5059eee467441ebdce8acf2b5c35ba4d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22727, "upload_time": "2017-09-11T07:11:01", "url": "https://files.pythonhosted.org/packages/50/c8/db1a2859986507ac3144795ce5eed138052b344c18b4fc8e4b970f561f5d/ftw.recipe.deployment-1.3.0.tar.gz" } ], "1.4.0": [ { "comment_text": "", "digests": { "md5": "60ed881c1732e303a34d50b682367868", "sha256": "d1c167998d125f46566465975584dce8530d3fe3c71eb286da8022a9a99d6db1" }, "downloads": -1, "filename": "ftw.recipe.deployment-1.4.0.tar.gz", "has_sig": false, "md5_digest": "60ed881c1732e303a34d50b682367868", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23813, "upload_time": "2017-12-08T15:50:49", "url": "https://files.pythonhosted.org/packages/60/20/aa2c7d0704ce46700e2d08b119812647ebbafc8c934f2e4de6464ba5f99b/ftw.recipe.deployment-1.4.0.tar.gz" } ], "1.4.1": [ { "comment_text": "", "digests": { "md5": "bbdb55a47ac5b9d8c925c00d77ba9c7f", "sha256": "c142f3548ca206d16c1bf765be2073dd2a81dd2c8a85713d74859e84d9b4ab8f" }, "downloads": -1, "filename": "ftw.recipe.deployment-1.4.1.tar.gz", "has_sig": false, "md5_digest": "bbdb55a47ac5b9d8c925c00d77ba9c7f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28579, "upload_time": "2018-01-10T16:30:48", "url": "https://files.pythonhosted.org/packages/bd/d9/e77ceaaa66ed7a62df9be7c2cd03c2766e4ea109bf1fcd3cbe3bfed62eed/ftw.recipe.deployment-1.4.1.tar.gz" } ], "1.4.2": [ { "comment_text": "", "digests": { "md5": "616f9b964c1e491b0afa0f849108775d", "sha256": "2ae8e9361da8d890d059ecc90a68621bbc9162cca2f94f824fbf95e23af98eeb" }, "downloads": -1, "filename": "ftw.recipe.deployment-1.4.2.tar.gz", "has_sig": false, "md5_digest": "616f9b964c1e491b0afa0f849108775d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24734, "upload_time": "2019-02-04T09:21:25", "url": "https://files.pythonhosted.org/packages/8a/9b/a4eab54a0e6d6e7463045833b403a1e4035d6fde44ed38a236cf15a3d8dc/ftw.recipe.deployment-1.4.2.tar.gz" } ], "1.4.3": [ { "comment_text": "", "digests": { "md5": "5e4a48e2177aab70f25ee420632ddfe9", "sha256": "aedb81d58ab9c08717bbffc01fe4b7aedb0a1db9168862e827ca184ff372f464" }, "downloads": -1, "filename": "ftw.recipe.deployment-1.4.3.tar.gz", "has_sig": false, "md5_digest": "5e4a48e2177aab70f25ee420632ddfe9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25779, "upload_time": "2019-02-04T09:50:37", "url": "https://files.pythonhosted.org/packages/38/7f/251461864d6acb8fb17feae690e1723995534eaff0b6e199ec0dd32c0169/ftw.recipe.deployment-1.4.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "5e4a48e2177aab70f25ee420632ddfe9", "sha256": "aedb81d58ab9c08717bbffc01fe4b7aedb0a1db9168862e827ca184ff372f464" }, "downloads": -1, "filename": "ftw.recipe.deployment-1.4.3.tar.gz", "has_sig": false, "md5_digest": "5e4a48e2177aab70f25ee420632ddfe9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25779, "upload_time": "2019-02-04T09:50:37", "url": "https://files.pythonhosted.org/packages/38/7f/251461864d6acb8fb17feae690e1723995534eaff0b6e199ec0dd32c0169/ftw.recipe.deployment-1.4.3.tar.gz" } ] }