没有深入到杂草,Nginx迫使我的手,以通过虚幻和map
指令完成一些魔术。
是否有一个优雅的(相对)解决scheme来跨多个定义调用共享一个variables,它允许每个定义调用将其数据附加到全局variables? 在软件中,这将被称为单身。
– 杂草 –
Nginx有一个map
指令,它决定了哪个上游服务器池应该被传递,如下所示:
map $http_host $upstream_pool { hostnames; blog.example.com blog_example_com; repo.example.com repo_example_com; default example_com; }
如您所见,对blog.example.com的任何请求都将传递到blog_example_com上游服务器池(通过proxy_pass
)。
问题是map
指令的语法是它只能包含在主要的http
块(nginx.conf)中,而vhost特定的指令(如upstream
和location
可以包含在vhostconfiguration的server
块中。
我的nodes.pp清单看起来像这样:
service-a-1.example.com inherits project_dev { nginx::vhost { 'mothership': } nginx::vhost { 'mothership_blog': } nginx::vhost { 'repo': } }
正如你所看到的,在一个成功的木偶运行之后,我应该在/etc/nginx/vhost.d/
目录中得到3个不同的vhostconfiguration文件。
我遇到的问题是,为了使map
指令工作,我需要知道哪些虚拟主机已经加载,所以我可以将他们各自的上游id添加到我在主configuration中定义的map
指令中: /etc/nginx/nginx.conf
http
块中的/etc/nginx/nginx.conf
(其中只能有一个)。
– 我曾尝试过 – –
我有一个global.pp文件,它做了一些“引导”,并在这个文件中添加了一个$singleton = ''
语法,然后在nginx :: vhost定义中,我添加了这个语法:
$tpl_upstream_pool_labels = inline_template("<% tpl_upstream_pools.keys.sort.each do |role| %><%= role %>_<%= tpl_domain_primary %>_<%= tpl_domain_top_level %>|<% end %>") $singleton = "${singleton}${tpl_upstream_pool_labels}" notify { "\n--------------------- Nginx::Conf::Vhost::Touch | Timestamp: ${timestamp} | Pool labels: ${singleton} -------------------------\n": }
哪个应该导致pipe道分隔的上游id列表。 如前所述,在nodes.pp清单中,我对nginx :: vhost进行了三次调用,并希望每个调用都附加$singleton
全局variables,但不是,它只包含最后一次调用的数据。
我也试图通过写一个临时文件来解决这个问题:
$temp_file_upstream_pool_labels_uri = "/tmp/puppet_known_upstreams_${timestamp}.txt" exec { "event_record_known_upstream_${name}" : command => "touch ${temp_file_upstream_pool_labels_uri} && echo ${tpl_upstream_pool_labels} >> ${temp_file_upstream_pool_labels_uri}", provider => 'shell' }
然后在nginx :: conf :: touch的定义中,主要的configurationnginx.conf是由puppet写的,我试过这个:
$temp_file_upstream_pool_labels_uri = "/tmp/puppet_known_upstreams_${timestamp}.txt" $contents = file($temp_file_upstream_pool_labels_uri)
理论上应该把文件的内容加载到$ contentsvariables中。 但是当我使用这种方法运行puppet时,我得到一个文件不存在的错误。 我确保nginx :: conf :: touch调用不会在所有虚拟主机被考虑之前发出,但仍然无济于事。
Puppet中的全局variables的问题是你不能实际追加到它们。 允许使用+=
语法,但它会创build全局的本地副本 ,并附加右侧的值。
我已经实现了一个你想要的模式,但我并不自豪,不能推荐使用它。 不过,既然你问,这里是:
class nginx::conf { $global = '' file { '/etc/nginx/nginx.conf': content => template(...) } }
至less在2.7.x
可以附加类的variables。
define nginx::vhost(...) { include nginx::conf $nginx::conf::global += "new content here" nginx::override_conf_content { "for-vhost-$name": } }
神秘的事情发生在神秘的最后一行中,它实例化了另一个define
。
define nginx::override_conf_content() { include nginx::conf $global = $nginx::conf::global File<| title == '/etc/nginx/nginx.conf' |> { content => template(...) } }
nginx.conf
的content
属性被模板的另一个评估结果覆盖,并带有新的variables值。
充分披露,我不知道为什么这个工程。 它可能不应该,并可能依靠一个晦涩的错误。 它可能会停止在未来的版本工作。
请注意,我把它叫做$global
而不是$singleton
,因为就是这样。 单身人士可以用来实现全局的语义,但他们不是一回事。
最后,尽pipe我可以感受到Puppet 3更新所面临的痛苦,但是您应该花点时间并开始实施。 我们都可能无法承受运行2.x
更长的时间。
添加另一个答案,以保持问题分开。
结合exec
和file()
是有缺陷的,因为它们在不同的层面上工作。
exec
资源被添加到目录并发送到代理,在编译完成后评估它。 由于您正在尝试在编译时收集信息(在使用file()
函数收集信息之前),因此不能依赖任何资源。
应该可以通过依赖生成函数而不是exec
资源来构build您的想法。