Creation-of-chef-language-pack

Registered by Devdatta Kulkarni on 2014-06-19

Note: I will be creating a spec out of this soon.

High-level Description:
------------------------------------
This spec outlines approaches towards creating a Chef language pack.
A recommendation is made towards one particular approach.

Problem:
----------------
Within Solum we want to provide ability for application developers to test
their chef cookbooks. Testing chef cookbooks broadly involves two kinds of
tests. The first kind of tests are concerned with things such as ensuring that the cookbook code is
syntactically correct, stylistically correct, and the recipes are unit tested to ensure that the mutual
inter-dependencies are working fine. The tools available for these tasks are,
Knife for ruby syntax, foodcritic for linting (https://github.com/acrmp/foodcritic) and
ChefSpec for unit testing (https://github.com/sethvargo/chefspec).
The second kind of tests are concerned with testing whether the configuration
which resulted from running a set of recipes has indeed converged to the intended state.
The tool available for this is test kitchen (https://github.com/test-kitchen/test-kitchen).

In Solum we want to support application developers who are developing chef
recipes to use above tools for testing their recipes.

Proposed Solution:
-------------------------------
We propose to provide a Chef language pack (a VM image) in Solum with chef, foodcritic,
ChefSpec, and test kitchen installed on it.
Solum operator would create this language pack and register it within Solum's glance.
Developers would use this language pack id within their plan definition.

To create such a VM image language pack we intend to provide a bash script
installs each of the above mentioned tools. The installation commands
for each are identified below.

Installation commands and steps (a.k.a the 'What'):
-----------------------------------------------------------------------------
- Start with Ubuntu 12.04 image and install Docker on it:
  - Note: Docker is needed as we plan to use Docker driver within Test Kitchen
  - sudo apt-get update
  - sudo sh -c "wget -qO- https://get.docker.io/gpg | apt-key add -"
  - sudo sh -c "echo deb http://get.docker.io/ubuntu docker main\
    > /etc/apt/sources.list.d/docker.list"

- Install RVM
  - \curl -sSL https://get.rvm.io | bash -s stable --ruby

- Install ruby-1.9.3
  - Note: Foodcritic needs Ruby 1.9.2+
  - rvm install ruby-1.9.3
  - rvm use 1.9.3

- Install chef (this will install knife)
  - gem install chef

- Install Foodcritic
  - gem install foodcritic

- Install ChefSpec
  - sudo gem install rake chefspec --no-ri --no-rdoc

- Install TestKitchen
  - gem install kitchen-docker
  - gem install berkshelf
  - gem install test-kitchen

How to use:
------------------
- Knife
  - knife cookbook test <cookbook location> (this did not work for me)
- Foodcritic
  - foodcritic <cookbook folder> (may be preferred)
- ChefSpec
  - rspec <cookbook_name> --format RspecJunitFormatter --out test-results.xml
- TestKitchen
  - kitchen test

Developer will provide the exact command(s) for invoking the test.
These will be provided in the Plan file. For example, lets say there is a hello_world cookbook
in my git repository. Then in the plan file I may specify commands in the following manner:

{
   syntax_check: knife cookbook test /hello_world
   style_check: foodcritic /hello_world
   unit_test: rspec /hello_world --format RspecJunitFormatter --out test-results.xml
   integration_test: kitchen test /hello_world
}

Design Issues:
-----------------------
- How to pass custom style rules to foodcritic? Once this is possible
  we would invoke foodcritic like so:
  - foodcritic cookbooks --include foodcritic-rules.rb --tags ~FC001

- How to pass location of cookbooks on the running VM to the various commands
  - Probably through the Plan file

- Which test Kitchen driver should we use?
  - We propose to use Docker driver [1]

Implementation (a.k.a the 'How'):
----------------------------------------------------
There are at least three different ways one can build such a Chef language pack.
1) We could use disk-image-builder and write a 'Chef element' which provides a script with the installation instructions.
2) We could provide a Dockerfile to create a container image and use that as the Chef language pack.
3) We could customize Heroku's Ruby buildpack (https://github.com/heroku/heroku-buildpack-ruby) to
   install the required tools.

Of the three, I propose that we rule out option 3. The reasons are as follows.
We could customize Heroku's buildpack in two ways. One, we maintain a fork of the buildpack repo.
This approach, even though possible, is lot of work.
Second approach would be to maintain just the customization bits and then 'apply' them
to the 'lp-cedarish's heroku-buildpack-ruby, which we clone and 'install' within the lp-cedarish flow.
The customization bits would essentially be installation logic written in a '.rb' file which
would need to be 'added' to the 'spec' directory of the heroku-buildpack-ruby.
The problem with this approach is that the creation of the language pack gets tied with
Heroku's Ruby buildpack.

Option 2, while feasible, may need work within Solum to allow using Docker images as language packs.
Conceptually though it should be possible.

So that leaves option 1. And I propose we start there.

(June 30, 2014, devkulkarni):

Using the Dockerfile approach (presented in custom-language-pack blueprint (https://blueprints.launchpad.net/solum/+spec/custom-language-packs)

Developer Impact:
------------------------------
- User 'docker' as driver name in .kitchen.yml
- Provide appropriate test commands in the plan file.

References:
-------------------
[1] https://github.com/portertech/kitchen-docker

Additional References:
-------------------------------------
- http://dracoater.blogspot.com/2013/09/testing-chef-cookbooks-part-1-foodcritic.html
- http://dracoater.blogspot.com/2013/09/testing-chef-cookbooks-part-2-chefspec.html

Blueprint information

Status:
Complete
Approver:
None
Priority:
Undefined
Drafter:
Devdatta Kulkarni
Direction:
Needs approval
Assignee:
Devdatta Kulkarni
Definition:
New
Series goal:
None
Implementation:
Implemented
Milestone target:
None
Started by
Adrian Otto on 2015-06-11
Completed by
Adrian Otto on 2015-06-11

Related branches

Sprints

Whiteboard

=== Start Comments by PaulCzar ===

If we use chefdk we get a jailed ruby and most of the tooling preinstalled - http://www.getchef.com/downloads/chef-dk/linux/

We also want to use a newer ubuntu than 12.04 so we get the better kernel etc for running docker.

the standard for syntax/style testing is now rubocop, not knife cookbook test.

the standard way to frame test commands is with Rake.

I maintain a tool ( and subsequent docker image ) for doing all of this in a somewhat automated fashion - https://github.com/paulczar/meez/blob/master/Dockerfile, https://registry.hub.docker.com/u/paulczar/meez/

Also I'm not sure that we want to use kitchen-docker for the testing ... We might be better seeing if we can utilize kitchen-openstack and let the hypervisor choice by the operator choose with to use. Or leave it up to the end-user to choose ( which they can do by including it in their own Gemfile in their repo ).

and finally there's a newish project that chef is working on called 'knife container' which we should look at utilizing for the language-pack / image building for chef cookbooks. https://github.com/opscode/knife-container

=== End Comments by PaulCzar ===

Cz,
Thanks for the comments and suggestions.

- new versions of ubuntu -- makes sense
- Meez and corresponding Dockerfile -- these would be good starting points for creating a Chef Docker language pack.
- kitchen-openstack -- thanks for pointing to this.
- knife container -- looks like this and Meez can be put together to create a Chef Docker language pack.

=== End Comments by devkulkarni ===

(June 30, 2014, devkulkarni):

Using the Dockerfile approach (presented in custom-language-pack blueprint (https://blueprints.launchpad.net/solum/+spec/custom-language-packs)

Gerrit topic: https://review.openstack.org/#q,topic:bp/chef-language-pack,n,z

Addressed by: https://review.openstack.org/103671
    Added a Dockerfile to create Chef language pack

(?)

Work Items

This blueprint contains Public information 
Everyone can see this information.