跳转到主要内容

ZC Buildout recipe for Unix deployments

项目描述

zc.recipe.deployment 脚本提供在 Unix 系统上部署具有多个进程的应用程序的支持。(也许以后还会添加对其他系统的支持。)它创建目录以存储应用程序实例配置、日志和运行时文件。它还可以设置或读取其他程序可以读取的选项,以确定文件放置的位置

cache-directory

应用程序实例应写入可替换数据缓存副本的目录名称。默认为 /var/cache/NAME,其中 NAME 是部署名称。

crontab-directory

cron 作业应放置的目录名称。默认为 /etc/cron.d。

etc-directory

配置文件应放置的目录名称。默认为 /etc/NAME,其中 NAME 是部署名称。

var-prefix

所有应用程序配置存储的目录路径。默认为 /etc。

lib-directory

应用程序实例应写入有价值数据的目录名称。默认为 /var/lib/NAME,其中 NAME 是部署名称。

log-directory

应用程序实例应写入其日志文件的目录名称。默认为 /var/log/NAME,其中 NAME 是部署名称。

logrotate-directory

日志旋转配置文件应放置的目录名称,通常是 /etc/logrotate.d。

run-directory

应用程序实例应放置其运行时文件(如 pid 文件和进程间通信套接字文件)的目录名称。默认为 /var/run/NAME,其中 NAME 是部署名称。

rc-directory

运行控制脚本应安装的目录名称。默认为 /etc/init.d。

var-prefix

所有应用程序数据存储的目录路径。默认为 /var。

在 /var 层次结构中传统上放置的目录以这种方式创建,使得目录归用户所有,该用户指定在 user 选项中,并且用户及其组可以写入。通常在 /etc 层次结构中找到的目录以由 etc-user 设置指定的用户所有(默认为 'root'),具有相同的权限

位于 etc-prefix 目录中的系统范围配置文件 zc.recipe.deployment.cfg,可以用来指定 var-prefix 设置。该文件使用 Python 标准的 ConfigParser 语法

[deployment]
var-prefix = /mnt/fatdisk

请注意,部分名称与正在构建的部署部分的名称无关;这是一个系统范围的设置,而不是针对任何特定部署。这对于识别非常大的分区非常有用,在这些分区中控制 /var 本身很困难。

变更

  • Python 3 支持。

1.3.0 (2015-11-11)

  • on-change 选项添加到配置脚本,当配置文件更改时运行命令。

1.1.0 (2013-11-04)

  • 如果内容未更改,则不要触摸现有的配置文件。

1.0.0 (2013-04-24)

  • name 选项添加到 configuration 脚本,以允许显式控制生成的文件路径。

0.10.2 (2013-04-10)

  • 修复打包错误。

0.10.1 (2013-04-10)

  • 修复 0.9 -> 0.10 .installed.cfg 迁移问题。

0.10.0 (2013-03-28)

  • 添加 etc-prefixvar-prefix 以指定整个树的这些新位置。这些路径的最终版本已导出。

  • 之前未记录且未测试的etclogrun设置已弃用。如果使用它们的值,则会记录警告。

  • cache-directorylib-directory添加到输出目录集。

  • 添加系统级配置,允许为整个机器指定“根”目录的位置。

  • 允许*-directory选项(例如log-directory)被配置数据覆盖。

0.9.0 (2011-11-21)

  • 修复了测试依赖问题。

  • 使用Python的doctest模块代替已弃用的zope.testing.doctest

  • 为配置添加了目录选项以覆盖默认的etc目录。

0.8.0 (2010-05-18)

新增功能

添加了更新可能被多个应用程序共享的配置文件的配方。

0.7.1 (2010-03-05)

已修复错误。

  • 修复了一个严重错误,该错误导致使用较旧构建包的新版本部署配方时构建包失败。

  • 卸载现在对即将删除已删除的目录更加宽容。

0.7.0 (2010-02-01)

新增功能

现在可以为cron表条目指定不同于部署用户的用户。

0.6 (2008-02-01)

新增功能

添加了独立于部分名称的名称指定功能。还为配方提供了名称选项。

重要提示:配方作者应使用部署名称选项而不是部署名称来计算生成文件的名称。

0.5 (2007年3月23日)

新增功能

添加了在/etc/cron.d中生成cron表文件的配方。

0.4 (2007年3月22日)

新增功能

  • 添加了logrotate配置目录的设置。

已修复的错误

  • 文档中给出了错误的crontab-directory选项名称。

0.3 (2007年2月14日)

新增功能

  • 添加了创建配置文件的配置配方。

0.2.1 (2007年2月13日)

  • 修复了设置文件中的错误。

0.2 (2007年2月7日)

已修复的错误

  • 在卸载和重新安装期间删除了非空日志和运行目录。

详细文档

使用部署配方非常简单。只需指定部署名称,通过部分名称指定,以及部署用户。

让我们向示例构建包添加一个部署

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo
...
... [foo]
... prefix = %s
... recipe = zc.recipe.deployment
... user = %s
... etc-user = %s
... ''' % (sample_buildout, user, user))
>>> from six import print_
>>> print_(system(join('bin', 'buildout')), end='')
Installing foo.
zc.recipe.deployment:
    Creating 'PREFIX/etc/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/cache/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/lib/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/log/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/run/foo',
    mode 750, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/cron.d',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/init.d',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/logrotate.d',
    mode 755, user 'USER', group 'GROUP'

注意,我们在这里提供了前缀和etc用户。这些选项的默认值分别为“/”和“root”。

现在我们可以看到在PREFIX/etcPREFIX/var/logPREFIX/var/run中已创建了名为foo的目录

>>> import os
>>> print_(ls(os.path.join(sample_buildout, 'etc/foo')))
drwxr-xr-x USER GROUP PREFIX/etc/foo
>>> print_(ls(os.path.join(sample_buildout, 'var/cache/foo')))
drwxr-xr-x USER GROUP PREFIX/var/cache/foo
>>> print_(ls(os.path.join(sample_buildout, 'var/lib/foo')))
drwxr-xr-x USER GROUP PREFIX/var/lib/foo
>>> print_(ls(os.path.join(sample_buildout, 'var/log/foo')))
drwxr-xr-x USER GROUP PREFIX/var/log/foo
>>> print_(ls(os.path.join(sample_buildout, 'var/run/foo')))
drwxr-x--- USER GROUP PREFIX/var/run/foo

通过查看.installed.cfg,我们可以看到可用于其他配方使用的选项

>>> cat('.installed.cfg') # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
[buildout]
...
[foo]
__buildout_installed__ =
...
cache-directory = PREFIX/var/cache/foo
crontab-directory = PREFIX/etc/cron.d
etc-directory = PREFIX/etc/foo
etc-prefix = PREFIX/etc
etc-user = USER
lib-directory = PREFIX/var/lib/foo
log-directory = PREFIX/var/log/foo
logrotate-directory = PREFIX/etc/logrotate.d
name = foo
prefix = PREFIX
rc-directory = PREFIX/etc/init.d
recipe = zc.recipe.deployment
run-directory = PREFIX/var/run/foo
user = USER
var-prefix = PREFIX/var

如果我们卸载,则删除目录。

>>> print_(system(join('bin', 'buildout')+' buildout:parts='), end='')
Uninstalling foo.
Running uninstall recipe.
zc.recipe.deployment: Removing 'PREFIX/etc/foo'
zc.recipe.deployment: Removing 'PREFIX/etc/cron.d'.
zc.recipe.deployment: Removing 'PREFIX/etc/init.d'.
zc.recipe.deployment: Removing 'PREFIX/etc/logrotate.d'.
zc.recipe.deployment: Removing 'PREFIX/var/cache/foo'.
zc.recipe.deployment: Removing 'PREFIX/var/lib/foo'.
zc.recipe.deployment: Removing 'PREFIX/var/log/foo'.
zc.recipe.deployment: Removing 'PREFIX/var/run/foo'.
>>> import os
>>> os.path.exists(os.path.join(sample_buildout, 'etc/foo'))
False
>>> os.path.exists(os.path.join(sample_buildout, 'var/cache/foo'))
False
>>> os.path.exists(os.path.join(sample_buildout, 'var/lib/foo'))
False
>>> os.path.exists(os.path.join(sample_buildout, 'var/log/foo'))
False
>>> os.path.exists(os.path.join(sample_buildout, 'var/run/foo'))
False

如果目录为空,则只删除缓存、库、日志和运行目录。为了验证这一点,我们将文件放入每个创建的目录中

>>> print_(system(join('bin', 'buildout')), end='')
... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
Installing foo.
zc.recipe.deployment:
    Creating 'PREFIX/etc/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/cache/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/lib/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/log/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/run/foo',
    mode 750, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/cron.d',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/init.d',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/logrotate.d',
    mode 755, user 'USER', group 'GROUP'
>>> write(os.path.join(sample_buildout, 'etc/foo/x'), '')
>>> write(os.path.join(sample_buildout, 'var/cache/foo/x'), '')
>>> write(os.path.join(sample_buildout, 'var/lib/foo/x'), '')
>>> write(os.path.join(sample_buildout, 'var/log/foo/x'), '')
>>> write(os.path.join(sample_buildout, 'var/run/foo/x'), '')

然后卸载

>>> print_(system(join('bin', 'buildout')+' buildout:parts='), end='')
Uninstalling foo.
Running uninstall recipe.
zc.recipe.deployment: Removing 'PREFIX/etc/foo'
zc.recipe.deployment: Removing 'PREFIX/etc/cron.d'.
zc.recipe.deployment: Removing 'PREFIX/etc/init.d'.
zc.recipe.deployment: Removing 'PREFIX/etc/logrotate.d'.
zc.recipe.deployment: Can't remove non-empty directory 'PREFIX/var/cache/foo'.
zc.recipe.deployment: Can't remove non-empty directory 'PREFIX/var/lib/foo'.
zc.recipe.deployment: Can't remove non-empty directory 'PREFIX/var/log/foo'.
zc.recipe.deployment: Can't remove non-empty directory 'PREFIX/var/run/foo'.
>>> os.path.exists(os.path.join(sample_buildout, 'etc/foo'))
False
>>> print_(ls(os.path.join(sample_buildout, 'var/cache/foo')))
drwxr-xr-x USER GROUP PREFIX/var/cache/foo
>>> print_(ls(os.path.join(sample_buildout, 'var/lib/foo')))
drwxr-xr-x USER GROUP PREFIX/var/lib/foo
>>> print_(ls(os.path.join(sample_buildout, 'var/log/foo')))
drwxr-xr-x USER GROUP PREFIX/var/log/foo
>>> print_(ls(os.path.join(sample_buildout, 'var/run/foo')))
drwxr-x--- USER GROUP PREFIX/var/run/foo

在这里我们可以看到var和run目录被保留。etc目录被丢弃,因为只有构建包应该写入它,并且其所有数据都是可替换的。

如果我们重新安装、删除文件并卸载,则删除目录

>>> print_(system(join('bin', 'buildout')), end='')
Installing foo.
zc.recipe.deployment:
    Creating 'PREFIX/etc/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Updating 'PREFIX/var/cache/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Updating 'PREFIX/var/lib/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Updating 'PREFIX/var/log/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Updating 'PREFIX/var/run/foo',
    mode 750, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/cron.d',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/init.d',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/logrotate.d',
    mode 755, user 'USER', group 'GROUP'
>>> os.remove(os.path.join(sample_buildout, 'var/cache/foo/x'))
>>> os.remove(os.path.join(sample_buildout, 'var/lib/foo/x'))
>>> os.remove(os.path.join(sample_buildout, 'var/log/foo/x'))
>>> os.remove(os.path.join(sample_buildout, 'var/run/foo/x'))
>>> print_(system(join('bin', 'buildout')+' buildout:parts='), end='')
Uninstalling foo.
Running uninstall recipe.
zc.recipe.deployment: Removing 'PREFIX/etc/foo'
zc.recipe.deployment: Removing 'PREFIX/etc/cron.d'.
zc.recipe.deployment: Removing 'PREFIX/etc/init.d'.
zc.recipe.deployment: Removing 'PREFIX/etc/logrotate.d'.
zc.recipe.deployment: Removing 'PREFIX/var/cache/foo'.
zc.recipe.deployment: Removing 'PREFIX/var/lib/foo'.
zc.recipe.deployment: Removing 'PREFIX/var/log/foo'.
zc.recipe.deployment: Removing 'PREFIX/var/run/foo'.
>>> os.path.exists('' + os.path.join(sample_buildout, 'PREFIX/etc/foo'))
False
>>> os.path.exists('' + os.path.join(sample_buildout, 'PREFIX/var/cache/foo'))
False
>>> os.path.exists('' + os.path.join(sample_buildout, 'PREFIX/var/lib/foo'))
False
>>> os.path.exists('' + os.path.join(sample_buildout, 'PREFIX/var/log/foo'))
False
>>> os.path.exists('' + os.path.join(sample_buildout, 'PREFIX/var/run/foo'))
False

在zc.recipe.deployment 0.10.0之前,一些目录(例如,cache-directory、lib-directory)不由zc.recipe.deployment管理。因此,在卸载时,我们可以期望任何不存在的目录键被静默忽略。

>>> _ = system(join('bin', 'buildout')), # doctest: +NORMALIZE_WHITESPACE
>>> new_installed_contents = ""
>>> with open(
...         os.path.join(sample_buildout, ".installed.cfg")) as fi:
...     for line in fi.readlines():
...         if (not line.startswith("cache-directory = ") and
...                 not line.startswith("lib-directory = ")):
...             new_installed_contents += line
>>> with open(
...         os.path.join(sample_buildout, ".installed.cfg"), 'w') as fi:
...     _ = fi.write(new_installed_contents)
>>> print_(system(join('bin', 'buildout')+' buildout:parts='), end='')
Uninstalling foo.
Running uninstall recipe.
zc.recipe.deployment: Removing '/tmp/tmpcokpi_buildoutSetUp/_TEST_/sample-buildout/etc/foo'
zc.recipe.deployment: Removing '/tmp/tmpcokpi_buildoutSetUp/_TEST_/sample-buildout/etc/cron.d'.
zc.recipe.deployment: Removing '/tmp/tmpcokpi_buildoutSetUp/_TEST_/sample-buildout/etc/init.d'.
zc.recipe.deployment: Removing '/tmp/tmpcokpi_buildoutSetUp/_TEST_/sample-buildout/etc/logrotate.d'.
zc.recipe.deployment: Removing '/tmp/tmpcokpi_buildoutSetUp/_TEST_/sample-buildout/var/log/foo'.
zc.recipe.deployment: Removing '/tmp/tmpcokpi_buildoutSetUp/_TEST_/sample-buildout/var/run/foo'.

我们将完成清理修改后的.installed.cfg遗漏的部分。

>>> os.removedirs(os.path.join(sample_buildout, 'var/cache/foo'))
>>> os.removedirs(os.path.join(sample_buildout, 'var/lib/foo'))

部署名称

部署名称用于命名生成文件和目录。部署名称默认为部分名称,但可以显式指定部署名称。

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... name = bar
... user = %s
... etc-user = %s
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Installing foo.
zc.recipe.deployment:
    Creating 'PREFIX/etc/bar',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/cache/bar',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/lib/bar',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/log/bar',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/run/bar',
    mode 750, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/cron.d',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/init.d',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/logrotate.d',
    mode 755, user 'USER', group 'GROUP'
>>> print_(ls(os.path.join(sample_buildout, 'etc/bar')))
drwxr-xr-x USER GROUP PREFIX/etc/bar
>>> print_(ls(os.path.join(sample_buildout, 'var/cache/bar')))
drwxr-xr-x USER GROUP PREFIX/var/cache/bar
>>> print_(ls(os.path.join(sample_buildout, 'var/lib/bar')))
drwxr-xr-x USER GROUP PREFIX/var/lib/bar
>>> print_(ls(os.path.join(sample_buildout, 'var/log/bar')))
drwxr-xr-x USER GROUP PREFIX/var/log/bar
>>> print_(ls(os.path.join(sample_buildout, 'var/run/bar')))
drwxr-x--- USER GROUP PREFIX/var/run/bar
>>> cat('.installed.cfg') # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
[buildout]
installed_develop_eggs =
parts = foo
<BLANKLINE>
[foo]
__buildout_installed__ =
...
cache-directory = PREFIX/var/cache/bar
crontab-directory = PREFIX/etc/cron.d
etc-directory = PREFIX/etc/bar
etc-prefix = PREFIX/etc
etc-user = USER
lib-directory = PREFIX/var/lib/bar
log-directory = PREFIX/var/log/bar
logrotate-directory = PREFIX/etc/logrotate.d
name = bar
prefix = PREFIX
rc-directory = PREFIX/etc/init.d
recipe = zc.recipe.deployment
run-directory = PREFIX/var/run/bar
user = USER
var-prefix = PREFIX/var

注意(在此处以及之前),选项包括名称选项,默认值为部分名称。使用部署名称的其他部分应使用名称选项而不是部分名称。

配置文件

通常,配置文件是由专门的配方创建的。有时,在buildout配置文件中指定配置文件是有用的。可以使用zc.recipe.deployment:configuration配方来完成此操作。

让我们向我们的buildout添加一个配置文件

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo x.cfg
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... user = %s
... etc-user = %s
...
... [x.cfg]
... recipe = zc.recipe.deployment:configuration
... text = xxx
...        yyy
...        zzz
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Uninstalling foo.
Running uninstall recipe.
zc.recipe.deployment: Removing 'PREFIX/etc/bar'
zc.recipe.deployment: Removing 'PREFIX/etc/cron.d'.
zc.recipe.deployment: Removing 'PREFIX/etc/init.d'.
zc.recipe.deployment: Removing 'PREFIX/etc/logrotate.d'.
zc.recipe.deployment: Removing 'PREFIX/var/cache/bar'.
zc.recipe.deployment: Removing 'PREFIX/var/lib/bar'.
zc.recipe.deployment: Removing 'PREFIX/var/log/bar'.
zc.recipe.deployment: Removing 'PREFIX/var/run/bar'.
Installing foo.
zc.recipe.deployment:
    Creating 'PREFIX/etc/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/cache/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/lib/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/log/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/run/foo',
    mode 750, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/cron.d',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/init.d',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/logrotate.d',
    mode 755, user 'USER', group 'GROUP'
Installing x.cfg.

默认情况下,配置作为部分安装

>>> cat('parts', 'x.cfg')
xxx
yyy
zzz

如果指定了部署,则文件将放置在部署etc目录中

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo x.cfg
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... user = %s
... etc-user = %s
...
... [x.cfg]
... recipe = zc.recipe.deployment:configuration
... text = xxx
...        yyy
...        zzz
... deployment = foo
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Uninstalling x.cfg.
Updating foo.
Installing x.cfg.
zc.recipe.deployment:
    Updating 'PREFIX/etc/foo',
    mode 755, user 'USER', group 'GROUP'
>>> os.path.exists(join('parts', 'x.cfg'))
False
>>> cat(os.path.join(sample_buildout, 'etc/foo/x.cfg'))
xxx
yyy
zzz

如果指定了目录,则文件将放置在该目录中。

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo x.cfg
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... user = %s
... etc-user = %s
...
... [x.cfg]
... recipe = zc.recipe.deployment:configuration
... text = xxx
...        yyy
...        zzz
... directory = etc/foobar
... deployment = foo
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Uninstalling x.cfg.
Updating foo.
Installing x.cfg.
zc.recipe.deployment:
    Creating 'PREFIX/etc/foobar',
    mode 755, user 'USER', group 'GROUP'
>>> os.path.exists(join('parts', 'x.cfg'))
False
>>> os.path.exists(join(sample_buildout, 'etc/foo/x.cfg'))
False
>>> cat(os.path.join(sample_buildout, 'etc/foobar/x.cfg'))
xxx
yyy
zzz

目录选项仅与部署选项一起使用。

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo x.cfg
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... user = %s
... etc-user = %s
...
... [x.cfg]
... recipe = zc.recipe.deployment:configuration
... text = xxx
...        yyy
...        zzz
... directory = etc/foobar
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Uninstalling x.cfg.
Updating foo.
Installing x.cfg.
>>> os.path.exists(join('parts', 'x.cfg'))
True
>>> os.path.exists(join(sample_buildout, 'etc/foobar/x.cfg'))
False
>>> cat('parts', 'x.cfg')
xxx
yyy
zzz

我们可以从文件中读取数据,而不是在配置中指定

>>> write('x.in', '1\n2\n3\n')
>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo x.cfg
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... user = %s
... etc-user = %s
...
... [x.cfg]
... recipe = zc.recipe.deployment:configuration
... file = x.in
... deployment = foo
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Uninstalling x.cfg.
Updating foo.
Installing x.cfg.
zc.recipe.deployment:
    Updating 'PREFIX/etc/foo',
    mode 755, user 'USER', group 'GROUP'
>>> cat(os.path.join(sample_buildout, 'etc/foo/x.cfg'))
1
2
3

该配方设置一个位置选项,其他配方可以使用该选项

>>> cat('.installed.cfg') # doctest: +ELLIPSIS
[buildout]
...
[x.cfg]
...
location = PREFIX/etc/foo/x.cfg
...

默认情况下,部分名称用作文件名。您可以使用name选项显式指定名称

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo x.cfg
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... user = %s
... etc-user = %s
...
... [x.cfg]
... recipe = zc.recipe.deployment:configuration
... name = y.cfg
... text = this is y
... deployment = foo
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Uninstalling x.cfg.
Updating foo.
Installing x.cfg.
zc.recipe.deployment:
    Updating 'PREFIX/etc/foo',
    mode 755, user 'USER', group 'GROUP'
>>> cat(os.path.join(sample_buildout, 'etc/foo/y.cfg'))
this is y

如果提供了名称,则仅创建此名称的文件

>>> os.path.exists(os.path.join(sample_buildout, 'etc', 'foo', 'x.cfg'))
False

名称可以是路径,甚至是绝对路径

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo x.cfg
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... user = %s
... etc-user = %s
...
... [x.cfg]
... recipe = zc.recipe.deployment:configuration
... name = ${buildout:directory}/y.cfg
... text = this is y also
... deployment = foo
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Uninstalling x.cfg.
Updating foo.
Installing x.cfg.
zc.recipe.deployment:
    Updating 'PREFIX/etc/foo',
    mode 755, user 'USER', group 'GROUP'
>>> cat('y.cfg')
this is y also

如果在构建之间配置文件的 内容未更改,并且路径未更改,则实际上不会在后续构建中写入文件。如果使用该文件的过程正在监视更改,这将很有帮助。

>>> mod_time = os.stat('y.cfg').st_mtime
>>> print_(system(join('bin', 'buildout')), end='')
Updating foo.
Updating x.cfg.
zc.recipe.deployment:
    Updating 'PREFIX/etc/foo',
    mode 755, user 'USER', group 'GROUP'
>>> os.stat('y.cfg').st_mtime == mod_time
True

当配置文件更改时运行命令

通常,在处理配置文件时,您需要在配置文件更改时重新启动进程。您可以使用on-change选项指定在配置文件更改时运行的命令

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo x.cfg
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... user = %s
... etc-user = %s
...
... [x.cfg]
... recipe = zc.recipe.deployment:configuration
... name = ${buildout:directory}/y.cfg
... text = this is y
... deployment = foo
... on-change = echo /etc/init.d/x start
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Uninstalling x.cfg.
Updating foo.
Installing x.cfg.
zc.recipe.deployment:
    Updating 'PREFIX/etc/foo',
    mode 755, user 'USER', group 'GROUP'
/etc/init.d/x start

Cron 支持

crontab配方提供创建crontab文件的支持。它使用times选项指定运行命令的时间,并使用包含命令的command选项。

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo cron
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... user = %s
... etc-user = %s
...
... [cron]
... recipe = zc.recipe.deployment:crontab
... times = 30 23 * * *
... command = echo hello world!
... deployment = foo
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Updating foo.
Installing cron.

此示例创建PREFIX/etc/cron.d/foo-cron

>>> open(os.path.join(sample_buildout, 'etc/cron.d/foo-cron')).read()
'30 23 * * *\tUSER\techo hello world!\n'

默认情况下,crontab配方从buildout的部署中获取用户,但这不是必须的。

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo cron
...
... [foo]
... recipe = zc.recipe.deployment
... name = bar
... prefix = %s
... user = %s
... etc-user = %s
...
... [cron]
... recipe = zc.recipe.deployment:crontab
... times = 30 23 * * *
... user = bob
... command = echo hello world!
... deployment = foo
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Uninstalling cron.
Updating foo.
Installing cron.
>>> open('etc/cron.d/bar-cron').read()
'30 23 * * *\tbob\techo hello world!\n'

SharedConfig

此配方可用于更新多个应用程序共享的配置文件。必须指定文件的绝对路径。此外,配置文件必须接受以“#”开头的注释。

与配置配方类似,可以使用“text”或“file”选项提供要添加到配置文件中的内容。

首先,让我们创建一个用作共享配置文件的文件。

>>> _ = open('y.cfg', 'w').write(
... '''Some
... existing
... configuration
... ''')

现在创建我们的buildout配置,并使用“sharedconfig”配方运行buildout。

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo y.cfg
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... user = %s
... etc-user = %s
...
... [y.cfg]
... recipe = zc.recipe.deployment:sharedconfig
... path = y.cfg
... deployment = foo
... text = xxx
...        yyy
...        zzz
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Installing foo.
zc.recipe.deployment:
    Creating 'PREFIX/etc/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/cache/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/lib/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/log/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/run/foo',
    mode 750, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Updating 'PREFIX/etc/cron.d',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Updating 'PREFIX/etc/init.d',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Updating 'PREFIX/etc/logrotate.d',
    mode 755, user 'USER', group 'GROUP'
Installing y.cfg.
>>> print_(open('y.cfg', 'r').read())
Some
existing
configuration
<BLANKLINE>
#[foo_y.cfg DO NOT MODIFY LINES FROM HERE#
xxx
yyy
zzz
#TILL HERE foo_y.cfg]#
<BLANKLINE>

再次运行buildout而不修改配置将保持文件不变。

>>> print_(system(join('bin', 'buildout')), end='')
Updating foo.
Updating y.cfg.
>>> print_(open('y.cfg', 'r').read())
Some
existing
configuration
<BLANKLINE>
#[foo_y.cfg DO NOT MODIFY LINES FROM HERE#
xxx
yyy
zzz
#TILL HERE foo_y.cfg]#
<BLANKLINE>

如果我们向文件中添加更多行

>>> _ = open('y.cfg', 'a').write(
... '''Some
... additional
... configuration
... ''')

并再次运行buildout,但这次在修改“y.cfg”的配置后,部分将被移动到文件末尾。

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo y.cfg
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... user = %s
... etc-user = %s
...
... [y.cfg]
... recipe = zc.recipe.deployment:sharedconfig
... path = y.cfg
... deployment = foo
... text = 111
...        222
...        333
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Uninstalling y.cfg.
Running uninstall recipe.
Updating foo.
Installing y.cfg.
>>> print_(open('y.cfg', 'r').read())
Some
existing
configuration
Some
additional
configuration
<BLANKLINE>
#[foo_y.cfg DO NOT MODIFY LINES FROM HERE#
111
222
333
#TILL HERE foo_y.cfg]#
<BLANKLINE>

要附加到共享配置文件中的文本也可以通过文件提供。

>>> write('x.cfg', '''
... [foo]
... a = 1
... b = 2
...
... [log]
... c = 1
... ''')
>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo y.cfg
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... user = %s
... etc-user = %s
...
... [y.cfg]
... recipe = zc.recipe.deployment:sharedconfig
... path = %s/etc/z.cfg
... deployment = foo
... file = x.cfg
... ''' % (sample_buildout, user, user, sample_buildout))
>>> print_(system(join('bin', 'buildout')), end='')
While:
  Installing.
  Getting section y.cfg.
  Initializing section y.cfg.
Error: Path 'PREFIX/etc/z.cfg' does not exist

哎呀。配置文件的路径必须存在。让我们创建一个。

>>> write(join(sample_buildout, 'etc', 'z.cfg'), '')
>>> print_(system(join('bin', 'buildout')), end='')
Uninstalling y.cfg.
Running uninstall recipe.
Updating foo.
Installing y.cfg.
>>> print_(open(join(sample_buildout, 'etc', 'z.cfg'), 'r').read())
<BLANKLINE>
#[foo_y.cfg DO NOT MODIFY LINES FROM HERE#
<BLANKLINE>
[foo]
a = 1
b = 2
<BLANKLINE>
[log]
c = 1
<BLANKLINE>
#TILL HERE foo_y.cfg]#
<BLANKLINE>

在卸载时,仅删除配方安装的行。

>>> print_(system(join('bin', 'buildout')+' buildout:parts='), end='')
Uninstalling y.cfg.
Running uninstall recipe.
Uninstalling foo.
Running uninstall recipe.
zc.recipe.deployment: Removing 'PREFIX/etc/foo'
zc.recipe.deployment: Removing 'PREFIX/etc/cron.d'.
zc.recipe.deployment: Removing 'PREFIX/etc/init.d'.
zc.recipe.deployment: Removing 'PREFIX/etc/logrotate.d'.
zc.recipe.deployment: Removing 'PREFIX/var/cache/foo'.
zc.recipe.deployment: Removing 'PREFIX/var/lib/foo'.
zc.recipe.deployment: Removing 'PREFIX/var/log/foo'.
zc.recipe.deployment: Removing 'PREFIX/var/run/foo'.

但文件不会被删除。

>>> os.path.exists('y.cfg')
True
>>> print_(open('y.cfg', 'r').read())
Some
existing
configuration
Some
additional
configuration
<BLANKLINE>
>>> os.path.exists(join(sample_buildout, 'etc', 'z.cfg'))
True
>>> print_(open(join(sample_buildout, 'etc', 'z.cfg'), 'r').read())
<BLANKLINE>

边缘情况

SharedConfig配方检查文件中的当前数据是否以新行结束。如果不存在,则添加一个。这是在配方在部分之前添加空白行以增强可读性之外。

>>> _ = open('anotherconfig.cfg', 'w').write('one')
>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo y.cfg
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... user = %s
... etc-user = %s
...
... [y.cfg]
... recipe = zc.recipe.deployment:sharedconfig
... path = anotherconfig.cfg
... deployment = foo
... text = I predict that there will be a blank line above this.
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Installing foo.
zc.recipe.deployment:
    Creating 'PREFIX/etc/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/cache/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/lib/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/log/foo',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/var/run/foo',
    mode 750, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/cron.d',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/init.d',
    mode 755, user 'USER', group 'GROUP'
zc.recipe.deployment:
    Creating 'PREFIX/etc/logrotate.d',
    mode 755, user 'USER', group 'GROUP'
Installing y.cfg.
>>> print_(open('anotherconfig.cfg').read())
one
<BLANKLINE>
#[foo_y.cfg DO NOT MODIFY LINES FROM HERE#
I predict that there will be a blank line above this.
#TILL HERE foo_y.cfg]#
<BLANKLINE>

但是,如果末尾已经有一个新行,配方不会添加新的行。

>>> _ = open('anotherconfig.cfg', 'w').write('ends with a new line\n')
>>> print_(open('anotherconfig.cfg').read())
ends with a new line
<BLANKLINE>

我们修改buildout配置,以便再次调用“install”

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo y.cfg
...
... [foo]
... recipe = zc.recipe.deployment
... prefix = %s
... user = %s
... etc-user = %s
...
... [y.cfg]
... recipe = zc.recipe.deployment:sharedconfig
... path = anotherconfig.cfg
... deployment = foo
... text = there will still be only a single blank line above.
... ''' % (sample_buildout, user, user))
>>> print_(system(join('bin', 'buildout')), end='')
Uninstalling y.cfg.
Running uninstall recipe.
Updating foo.
Installing y.cfg.
>>> print_(open('anotherconfig.cfg').read())
ends with a new line
<BLANKLINE>
#[foo_y.cfg DO NOT MODIFY LINES FROM HERE#
there will still be only a single blank line above.
#TILL HERE foo_y.cfg]#
<BLANKLINE>

如果我们卸载文件,数据将与“original_data”相同

>>> print_(system(join('bin', 'buildout')+' buildout:parts='), end='')
Uninstalling y.cfg.
Running uninstall recipe.
Uninstalling foo.
Running uninstall recipe.
zc.recipe.deployment: Removing 'PREFIX/etc/foo'
zc.recipe.deployment: Removing 'PREFIX/etc/cron.d'.
zc.recipe.deployment: Removing 'PREFIX/etc/init.d'.
zc.recipe.deployment: Removing 'PREFIX/etc/logrotate.d'.
zc.recipe.deployment: Removing 'PREFIX/var/cache/foo'.
zc.recipe.deployment: Removing 'PREFIX/var/lib/foo'.
zc.recipe.deployment: Removing 'PREFIX/var/log/foo'.
zc.recipe.deployment: Removing 'PREFIX/var/run/foo'.
>>> print_(open('anotherconfig.cfg').read())
ends with a new line
<BLANKLINE>

下载

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码分发

zc.recipe.deployment-1.3.0.tar.gz (29.2 kB 查看哈希值)

上传时间: 源代码

由以下支持