Puppet .erb 模板:语法错误,意外的 $end,期待 ')'(或:将 .erb 中声明的变量插入到代码结束后的文本中)

Puppet .erb template: syntax error, unexpected $end, expecting ')' (or: inserting variables declared in .erb into text after end of code)

我正在 Puppet 中使用 .erb 来管理 Apache Flume 配置文件。 (Flume 将把日志发送到 Elasticsearch,以便可以在 Kibana 中搜索和排序它们。)

一些背景:它从一个名为 logpaths 的自定义事实中获取此信息,该事实以这种格式保存我的日志路径:

>MysqlBlah;/var/logs/mysql/error.log:/var/logs/mysql/slow_query.log
>TomcatBlah;/var/logs/tomcat/catalina.out:/var/logs/tomcat/error.log

因此每个服务都以 > 开头,日志列表以 ; 开头,日志路径以 : 分隔。

我希望我的 ERB 读取它,并遍历每个日志文件以得出我可以放入我的 flume 配置文件中的文本。

一切似乎都很好,但我遇到了一个我无法追踪的错误:

-:58: syntax error, unexpected $end, expecting ')'

我似乎在任何地方都没有任何未闭合的括号,所以我不确定如何查找导致此问题的原因。

编辑 1:

根据@Daiku,我在所有变量周围添加了双引号,现在它正在通过语法检查。但是,Puppet 现在出现此错误:

Could not find value for 'sourcenamelist'

这是范围问题吗?在 %>?

之后是否有另一种方法来访问变量(我在这个 erb 中声明的)

编辑 2:

我应该看看行号。事实证明,我可以按照原来的方式插入变量,导致问题的行号是我追加到列表的行号(这是有道理的,因为我在开始追加之前没有声明该变量)。我现在回到正轨;一旦我解决了我剩下的错误,post 将完成代码。

我的代码如下:

<%
#split on > to get each service
services = @logpaths.split(">")
services.each do |serviceline| 
#split on semicolon
service = serviceline.split(";")
servicename = service[0]
#split into logs on colon
logs = service[1].string.split(":")
lognumber = 0
logs.each do |log|
#sourcelist is a space-delimited list of names for each logfile (eg mysql3311-1)
lognumber += 1
sourcename = servicename + "-" + lognumber.to_s + " "
sourcenamelist << sourcename    
#sourceconfigs assigns each source to channel, exec path
sourceconfig = "a1.sources.#{sourcename}.type = exec\na1.sources.#{sourcename}.command = tail -F #{log}\na1.sources.#{sourcename}.channels = c1"
sourceconfiglist << sourceconfig
#sourceinterceptors appends sourcename, path, and servicename (you know, for search)
sourceinterceptors = "a1.sources.#{sourcename}.interceptors = i1 i2 i3 i4\na1.sources.#{sourcename}.interceptors.i1.type = timestamp"
sourceinterceptorlist << sourceinterceptors
end
end 
-%>

# Name the components on this agent
a1.sources = <%= #{sourcenamelist} -%>
a1.sinks = k1
a1.channels = c1

# Describe/configure the source 
<%= #{sourceconfiglist} -%>

# Describe the sink
a1.sinks.k1.type = elasticsearch
a1.sinks.k1.hostNames = (my elasticsearch host):9300
a1.sinks.k1.indexName = flume
a1.sinks.k1.indexType = flume_logs
a1.sinks.k1.clusterName = elasticsearch
a1.sinks.k1.batchSize = 1000
a1.sinks.k1.ttl = 2
a1.sinks.k1.serializer = org.apache.flume.sink.elasticsearch.ElasticSearchLogStashEventSerializer

# Use a channel which buffers events in memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

#interceptor
<%= #{sourceinterceptorlist} -%>

您需要在插入的 ruby 两边加上双引号:

a1.sources = <%= "#{sourcenamelist}" -%>

等等