Reputation: 125
In OpsWorks, I'm trying to test the number suffix on a hostname of a given node, and to extract that number if it isn't 1. If the number isn't 1, I have this regex to match the number:
/([\d]+)$/
Which is run against a node naming scheme that follows this pattern:
I've verified this works using Rubular: http://rubular.com/r/Ei0kqjaxQn
However, when I run this against an instance with OpsWorks, this match returns nil, no matter what number the hostname has at the end. The OpsWorks agent version is the latest at time of writing (4023), using Chef 12.13.37.
This is the code in the cookbook trying use the matched number:
short_app_name.to_s + node['hostname'][/([\d]+)$/, 1].to_s + '.' + app['domains'].first
The run fails with type error no implicit conversion of nil into String
. However, regex searches against that property work earlier in the recipe, when checking the node's number suffix. Is there a different method I should be using to extract the node's suffix?
Edit: app['domains'].first
is populated. This line still fails with the same type error if it is swapped out with domain.com
.
Upvotes: 0
Views: 113
Reputation: 29488
You error has nothing to do with the regex.
The issue is when you try to concatenate your existing String
with
app['domains'].first
This is the only place this error would be raised because even if your String#slice
returned nil
you are calling to_s
so it is an empty String
but String
+ nil
as would be the case if app['domains'].first
is nil
will raise this error.
breakdown
#short_app_name can be nil because of explicit #to_s
short_app_name.to_s
####
# assuming node is a Hash
# node must have 'hostname' key
# or NoMethodError: undefined method `[]' for nil:NilClass wil be raised
# node['hostname'][/([\d]+)$/, 1] can be nil because of explicit #to_s
node['hostname'][/([\d]+)$/, 1].to_s
#####
# assuming app is a Hash
# app must contain 'domains' key and the value must respond to first
# and the first value must be a String or be implicitly coercible (#to_str) or it will fail with
# TypeError: no implicit conversion of ClassName into String
# could explicitly coerce (#to_s) like you do previously
app['domains'].first
Example:
node = {"hostname" => 'nodable'}
app = {"domains" => []}
node['hostname'][/([\d]+)$/, 1]
#=> nil
node['hostname'][/([\d]+)$/, 1].to_s
#=> ""
app["domains"].first
#=> nil
node['hostname'][/([\d]+)$/, 1].to_s + '.' + app["domains"].first
#=> TypeError: no implicit conversion of nil into String
node = {"hostname" => 'node2'}
app = {"domains" => ['here.com']}
node['hostname'][/([\d]+)$/, 1].to_s + '.' + app["domains"].first
#=> "2.here.com"
Upvotes: 0
Reputation: 11060
When I copy your regex and paste it into my terminal to test, there's a soft hyphen character after the dollar sign at the end of the regex, removing this makes things work:
The website isn't showing it even when I copy it from my terminal, but a screenshot shows the issue:
That second line ('irb(main):002:0') is what I copy/pasted from your cookbook code, the character is "\xc2\xad"
Upvotes: 1
Reputation: 830
Judging from the cookbook code and the error message, the problem may be that app['domains']
is an empty array during the run. So you may want to verify that its value is correct.
Upvotes: 1