Commit 8bac3bfe authored by Jamie Tanna's avatar Jamie Tanna

Add drafts for Chef 13 upgrades

Don't show TOC as these posts are all short enough to not need headings
parent ad16bc61
---
title: 'Chef 13 Upgrade: Rubocop Changes for `lazy` Parameters'
description: 'How to resolve the `Parenthesize the param lazy` Rubocop error when upgrading your cookbook to Chef 13.'
categories: findings chef-13-upgrade
tags: findings chef-13-upgrade chef-13-upgrade-rubocop chef rubocop chef-13 rubocop-0-49
no_toc: true
---
{% include posts/chef-13/intro.html %}
When running Rubocop from ChefDK 2 against the following code, we receive the error `Parenthesize the param lazy { ... } to make sure that the block will be associated with the lazy method call` twice:
```ruby
template 'Chef deploy user\'s authorized_keys' do
source 'authorized_keys.erb'
path lazy { "#{node['etc']['passwd']['chef']['dir']}/.ssh/authorized_keys" }
user 'chef'
group 'chef'
mode '0600'
variables lazy {
{
public_keys: node['authorized_keys'] + [node.run_state['public_key/deploy']]
}
}
end
```
This error can be resolved by adding a parentheses around the whole `lazy { }` blocks:
```diff
template 'Chef deploy user\'s authorized_keys' do
source 'authorized_keys.erb'
- path lazy { "#{node['etc']['passwd']['chef']['dir']}/.ssh/authorized_keys" }
+ path(lazy { "#{node['etc']['passwd']['chef']['dir']}/.ssh/authorized_keys" })
user 'chef'
group 'chef'
mode '0600'
- variables lazy {
+ variables(lazy do
{
public_keys: node['authorized_keys'] + [node.run_state['public_key/deploy']]
}
- }
+ end)
end
```
Note that I've also converted the multi-line block to a `do` / `end` block, as that was another complaint of Rubocop.
---
title: 'Chef 13 Upgrade: Rubocop Changes for Testing `render_file` with ChefSpec and a `with_content` Block'
description: 'How to resolve the `Parenthesize the param render_file` Rubocop error when upgrading your cookbook to Chef 13.'
categories: findings chef-13-upgrade
tags: findings chef-13-upgrade chef-13-upgrade-chefspec chef chefspec
no_toc: true
---
{% include posts/chef-13/intro.html %}
When testing that Chef's `template`s are being rendered correctly, the easiest way to do this is via `render_file(...).with_content(&block)`.
However, when running the below code against Chef 13's Rubocop, this gives the error `Parenthesize the param render_file`:
```ruby
expect(chef_run).to render_file('/chef/.ssh/authorized_keys')
.with_content do |content|
expect(content).to match(%r{^ssh-rsa this is long key$})
expect(content).to match(%r{^ssh-another key$})
expect(content).to match(%r{^wibble deploy$})
end
```
The fix is to have the whole `render_file` method call wrapped in parentheses, such as:
```diff
-expect(chef_run).to render_file('/chef/.ssh/authorized_keys')
- .with_content { |content|
+expect(chef_run).to(render_file('/chef/.ssh/authorized_keys')
+ .with_content do |content|
expect(content).to match(%r{^ssh-rsa this is long key$})
expect(content).to match(%r{^ssh-another key$})
expect(content).to match(%r{^wibble deploy$})
- }
+ end)
```
Additionally, I've converted the multi-line block to a `do` / `end` block, as that was another complaint of Rubocop.
---
title: 'Chef 13 Upgrade: Testing `ruby_block`s with ChefSpec'
description: 'Replace your `block.old_run_action` with `block.block.call` to trigger `ruby_block`s within ChefSpec 7 and Chef 13.'
categories: findings chef-13-upgrade
tags: findings chef-13-upgrade chef-13-upgrade-chefspec chef chefspec chef-13 chefspec-7
no_toc: true
---
{% include posts/chef-13/intro.html %}
ChefSpec doesn't execute `ruby_block`s by default, and instead requires you to manually trigger it within your test. In Chef 12, we would be able to do this by calling `block.old_run_action(:run)`:
```ruby
# recipe
ruby_block "get the '#{key_name}' key" do
block do
node.run_state["public_key/#{safe_key_name}"] = ::File.read("#{node['etc']['passwd'][username]['dir']}/.ssh/#{safe_key_name}.pub")
Chef::Recipe::RubyBlockHelper.run_state_public_key(node, username, safe_key_name)
end
end
# spec
it ' ... ' do
block = chef_run.find_resource('ruby_block', 'get the \'blah blah key\' key')
block.old_run_action(:run)
expect(chef_run.node.run_state['public_key/blah_blah_key']).to eq 'ssh-rsa blah'
end
```
This was removed in Chef 13, so instead we must use `block.block.call`:
```diff
# spec
it ' ... ' do
block = chef_run.find_resource('ruby_block', 'get the \'blah blah key\' key')
- block.old_run_action(:run)
+ block.block.call
expect(chef_run.node.run_state['public_key/blah_blah_key']).to eq 'ssh-rsa blah'
end
```
This works on both Chef 12 and Chef 13, due to the fact that `ruby_block`'s `block` property is of type `Proc` ([`Proc#call`][proc-call]).
[proc-call]: https://ruby-doc.org/core-2.4.2/Proc.html#method-i-call
---
title: 'Chef 13 Upgrade: Lessons Learnt and Documented for Posterity'
description: 'Notes on the main problems encountered when upgrading from Chef 12 to Chef 13, both with ChefSpec and Rubocop.'
categories: findings chef-13-upgrade
tags: findings chef-13-upgrade chef-13-upgrade-rubocop chef-13-upgrade-chefspec chef rubocop chefspec chef-13 chefspec-7 rubocop-0-49
no_toc: true
---
I've recently been working through upgrading my Chef 12 cookbooks to Chef 13, as Chef 12 is to be [End of Life'd in April 2018][chef-12-eol].
As part of this, there have been a few snags I've hit with respect to [Chef 13 + Rubocop][chef-13-upgrade-rubocop] and [Chef 13 + ChefSpec][chef-13-upgrade-chefspec] within my existing cookbooks.
For reasons I won't go into, I'm still using Rubocop over the Chef-recommended [CookStyle][cookstyle], which it seems would have resolved a few of these issues.
Note that some, but not all, of the Rubocop fixes can be automagically resolved using `rubocop --auto-correct`.
[chef-12-eol]: https://www.chef.io/eol-chef12-and-chefdk1/
[chef-13-upgrade-rubocop]: /tags/chef-13-upgrade-rubocop/
[chef-13-upgrade-chefspec]: /tags/chef-13-upgrade-chefspec/
[cookstyle]: https://docs.chef.io/cookstyle.html
---
title: 'Chef 13 Upgrade: Rubocop Changes for Word Array Literals (`%w`)'
description: 'A one-liner shell command to fix Rubocop errors `%w-literals should be delimited by [ and ].`'
categories: findings chef-13-upgrade
tags: findings chef-13-upgrade chef-13-upgrade-rubocop chef rubocop chef-13 rubocop-0-49
no_toc: true
---
{% include posts/chef-13/intro.html %}
One recommended change with the new version of Rubocop is the error `%w-literals should be delimited by [ and ]`.
For instance:
```diff
-arr = %w(this is an array)
+arr = %w[this is an array]
```
For most cases, you will be able to perform one of the following commands:
```sh
# use Rubocop's automagic autocorrect, if possible
rubocop --auto-correct
# or fall back to a search and replace
find . -iname "*.rb" -exec sed 's/%w(\([^)]*\))/%w[\1]/g' {} \;
```
As part of an <a href="{{ post_url 2018-03-06-chef-13-upgrades }}">upgrade from Chef 12 to Chef 13</a>, this is one of the posts in which I've been <a href="/tags/chef-13-upgrade">detailing the issues I've encountered, and how I've resolved them </a>.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment