Merge branch 'add_kitchen_init' into 'master'
add kitchen init
Update content as you need it. The file is intended to be used mainly with existing repos to quickly add kitchen test to existing formulas.
Further decisions to be made:
- how to add/update Makefile on existing repos.
See merge request !1
diff --git a/README.rst b/README.rst
index 9bf6152..ce5caef 100644
--- a/README.rst
+++ b/README.rst
@@ -11,3 +11,26 @@
pip install cookiecutter
cookiecutter cookiecutter-salt-formula
+
+
+Init Kitchen CI
+===============
+
+Install prerequisite (Render jinja2 templates on the command line with shell environment variables)
+
+.. code-block:: bash
+
+ pip install envtpl
+
+Once you create your `tests/pillar` structure (required if you want to auto populate kitchen test suites)
+
+.. code-block:: bash
+
+ pip install envtpl
+ ./kitchen-init.sh
+
+Instantly for latest version or on existing formulas:
+
+.. code-block:: bash
+
+ curl -sL "https://git.tcpcloud.eu/cookiecutter-templates/cookiecutter-salt-formula/raw/master/kitchen-init.sh" | bash -s --
diff --git a/cookiecutter.json b/cookiecutter.json
index 7e65fdf..eb95831 100644
--- a/cookiecutter.json
+++ b/cookiecutter.json
@@ -4,5 +4,10 @@
"project_name": "{{ cookiecutter.service_name }}-formula",
"repo_name": "{{ cookiecutter.service_name|replace('_', '-') }}-formula",
"license_holder": "tcp cloud a.s.",
- "author_contact": "Ales Komarek <ales.komarek@tcpcloud.eu>"
+ "author_contact": "tcpcloud <cloud@tcpcloud.eu>",
+
+ "kitchen_driver": "vagrant",
+ "kitchen_verifier": "inspec",
+ "kitchen_formula": "{{ cookiecutter.service_name }}",
+ "kitchen_suites": ""
}
diff --git a/kitchen-init.sh b/kitchen-init.sh
new file mode 100755
index 0000000..c059ca5
--- /dev/null
+++ b/kitchen-init.sh
@@ -0,0 +1,135 @@
+#!/bin/bash
+
+# Script to add Kitchen configuration to existing formulas.
+# usage:
+# curl -sL "https://git.tcpcloud.eu/cookiecutter-templates/cookiecutter-salt-formula/raw/master/kitchen-init.sh" | bash -s --
+
+
+# CONFIG
+###################################
+
+export driver=${driver:-vagrant} # vagrant, dokken, openstack, ...
+export verifier=${verifier:-inspec} # serverspec, pester
+
+export formula=${formula:-$(awk -f: '/name/{gsub(/[\ \"]/,"");print $2}' metadata.yml)}
+export suites=$(ls tests/pillar|xargs -i{} basename {} .sls)
+
+export SOURCE_REPO_URI="https://git.tcpcloud.eu/cookiecutter-templates/cookiecutter-salt-formula/raw/master/%7B%7Bcookiecutter.project_name%7D%7D"
+
+which envtpl &> /dev/null|| pip3 install envtpl
+
+# INIT
+###################################
+test ! -e .kitchen.yml || {
+ kitchen init -D kitchen-docker -P kitchen-salt --no-create-gemfile
+ echo .kitchen >> .gitignore
+ rm -rf test
+ rm -f .kitchen.yml
+ rm -f chefignore
+}
+
+
+# CONFIGURE & SCAFFOLD TEST DIR
+###################################
+test -d tests/integration || {
+ for suite in $SUITES; do
+ mkdir -p tests/integration/$suite/$VERIFIER
+ done
+ mkdir -p tests/integration/helpers/$VERIFIER/
+ touch $_/spec_helper.rb
+}
+
+
+# .KITCHEN.YML
+###################################
+
+test -e .kitchen.yml || \
+envtpl < <(curl -sL "${SOURCE_REPO_URI}/.kitchen.yaml" -- | sed 's/cookiecutter\.kitchen_//g') > .kitchen.yml
+
+[[ "$DRIVER" != "docker" ]] && {
+ test -e .kitchen.docker.yml || \
+ envtpl < <(curl -sL "${SOURCE_REPO_URI}/.kitchen.yaml" -- | sed 's/cookiecutter\.kitchen_//g' | head -n12 ) > .kitchen.docker.yml
+}
+
+test -e .kitchen.openstack.yml || \
+envtpl < <(curl -sL "${SOURCE_REPO_URI}/.kitchen.openstack.yaml" -- | sed 's/cookiecutter\.kitchen_//g') > .kitchen.openstack.yml
+
+
+
+# UPDATE README, etc...
+###################################
+
+grep -Eoq 'Development and testing' README.* || {
+
+KITCHEN_LIST=$(kitchen list|tail -n+2)
+cat >> README.* <<-\EOF
+
+ Development and testing
+ =======================
+
+ Development and test workflow with `Test Kitchen <http://kitchen.ci>`_ and
+ `kitchen-salt <https://github.com/simonmcc/kitchen-salt>`_ provisioner plugin.
+
+ Test Kitchen is a test harness tool to execute your configured code on one or more platforms in isolation.
+ There is a ``.kitchen.yml`` in main directory that defines *platforms* to be tested and *suites* to execute on them.
+
+ Kitchen CI can spin instances locally or remote, based on used *driver*.
+ For local development ``.kitchen.yml`` defines a `vagrant <https://github.com/test-kitchen/kitchen-vagrant>`_ or
+ `docker <https://github.com/test-kitchen/kitchen-docker>`_ driver.
+
+ To use backend drivers or implement your CI follow the section `INTEGRATION.rst#Continuous Integration`__.
+
+ A listing of scenarios to be executed:
+
+ .. code-block:: shell
+
+ $ kitchen list
+
+ Instance Driver Provisioner Verifier Transport Last Action
+
+EOF
+
+echo "$KITCHEN_LIST" | sed 's/^/ /' >> README.*
+
+cat >> README.* <<-\EOF
+
+ The `Busser <https://github.com/test-kitchen/busser>`_ *Verifier* is used to setup and run tests
+ implementated in `<repo>/test/integration`. It installs the particular driver to tested instance
+ (`Serverspec <https://github.com/neillturner/kitchen-verifier-serverspec>`_,
+ `InSpec <https://github.com/chef/kitchen-inspec>`_, Shell, Bats, ...) prior the verification is executed.
+
+
+ Usage:
+
+ .. code-block:: shell
+
+ # list instances and status
+ kitchen list
+
+ # manually execute integration tests
+ kitchen [test || [create|converge|verify|exec|login|destroy|...]] [instance] -t tests/integration
+
+ # use with provided Makefile (ie: within CI pipeline)
+ make kitchen
+
+EOF
+}
+
+test -e INTEGRATION.rst || \
+curl -sL "${SOURCE_REPO_URI}/INTEGRATION.rst" -o INTEGRATION.rst
+
+
+# ADD CHANGES TO GIT
+###################################
+
+# update Makefile, but do not auto-add to git
+curl -sL "${SOURCE_REPO_URI}/Makefile" -o Makefile
+
+git add \
+ .gitignore \
+ .kitchen*yml \
+ INTEGRATION.rst \
+ README.rst
+
+git status
+
diff --git "a/\173\173cookiecutter.project_name\175\175/.gitignore" "b/\173\173cookiecutter.project_name\175\175/.gitignore"
index bacd7c7..aa8e42a 100644
--- "a/\173\173cookiecutter.project_name\175\175/.gitignore"
+++ "b/\173\173cookiecutter.project_name\175\175/.gitignore"
@@ -1,3 +1,4 @@
+.kitchen
tests/build/
*.swp
*.pyc
diff --git "a/\173\173cookiecutter.project_name\175\175/.kitchen.docker.yml" "b/\173\173cookiecutter.project_name\175\175/.kitchen.docker.yml"
new file mode 100644
index 0000000..4d0816f
--- /dev/null
+++ "b/\173\173cookiecutter.project_name\175\175/.kitchen.docker.yml"
@@ -0,0 +1,28 @@
+---
+driver:
+ name: docker
+ hostname: {{ cookiecutter.kitchen_formula }}.ci.local
+ use_sudo: false
+
+
+provisioner:
+ name: salt_solo
+ salt_install: bootstrap
+ salt_bootstrap_url: https://bootstrap.saltstack.com
+ salt_version: latest
+ formula: {{ cookiecutter.kitchen_formula }}
+ log_level: info
+ state_top:
+ base:
+ "*":
+ - {{ cookiecutter.kitchen_formula }}
+ pillars:
+ top.sls:
+ base:
+ "*":
+ - {{ cookiecutter.kitchen_formula }}
+ grains:
+ noservices: True
+
+
+# vim: ft=yaml sw=2 ts=2 sts=2 tw=125
diff --git "a/\173\173cookiecutter.project_name\175\175/.kitchen.openstack.yml" "b/\173\173cookiecutter.project_name\175\175/.kitchen.openstack.yml"
new file mode 100644
index 0000000..6dbf7b2
--- /dev/null
+++ "b/\173\173cookiecutter.project_name\175\175/.kitchen.openstack.yml"
@@ -0,0 +1,41 @@
+
+# usage: `KITCHEN_LOCAL_YAML=.kitchen.openstack.yml kitchen test`
+
+# https://docs.chef.io/config_yml_kitchen.html
+# https://github.com/test-kitchen/kitchen-openstack
+
+---
+driver:
+ name: openstack
+ openstack_auth_url: <%= ENV['OS_AUTH_URL'] %>/tokens
+ openstack_username: <%= ENV['OS_USERNAME'] || 'ci' %>
+ openstack_api_key: <%= ENV['OS_PASSWORD'] || 'ci' %>
+ openstack_tenant: <%= ENV['OS_TENANT_NAME'] || 'ci_jenkins' %>
+
+ #floating_ip_pool: <%= ENV['OS_FLOATING_IP_POOL'] || 'nova' %>
+ key_name: <%= ENV['BOOTSTRAP_SSH_KEY_NAME'] || 'bootstrap_insecure' %>
+ private_key_path: <%= ENV['BOOTSTRAP_SSH_KEY_PATH'] || "#{ENV['HOME']}/.ssh/id_rsa_bootstrap_insecure" %>
+
+
+platforms:
+ - name: ubuntu-14.04
+ driver:
+ username: <%= ENV['OS_UBUNTU_IMAGE_USER'] || 'root' %>
+ image_ref: <%= ENV['OS_UBUNTU_IMAGE_REF'] || 'ubuntu-14-04-x64-1455869035' %>
+ flavor_ref: m1.medium
+ network_ref:
+ <% if ENV['OS_NETWORK_REF'] -%>
+ - <% ENV['OS_NETWORK_REF'] %>
+ <% else -%>
+ - ci-net
+ <% end -%>
+ # force update apt cache on the image
+ run_list:
+ - recipe[apt]
+ attributes:
+ apt:
+ compile_time_update: true
+transport:
+ username: <%= ENV['OS_UBUNTU_IMAGE_USER'] || 'root' %>
+
+# vim: ft=yaml sw=2 ts=2 sts=2 tw=125
diff --git "a/\173\173cookiecutter.project_name\175\175/.kitchen.yml" "b/\173\173cookiecutter.project_name\175\175/.kitchen.yml"
new file mode 100644
index 0000000..188c204
--- /dev/null
+++ "b/\173\173cookiecutter.project_name\175\175/.kitchen.yml"
@@ -0,0 +1,62 @@
+---
+driver:
+ name: {{ cookiecutter.kitchen_driver }}
+{%- if cookiecutter.kitchen_driver == 'docker' %}
+ hostname: {{ cookiecutter.kitchen_formula }}.ci.local
+ use_sudo: false
+{%- elif cookiecutter.kitchen_driver == 'vagrant' %}
+ vm_hostname: {{ cookiecutter.kitchen_formula }}.ci.local
+ use_sudo: false
+ customize:
+ memory: 512
+{%- endif %}
+
+
+provisioner:
+ name: salt_solo
+ salt_install: bootstrap
+ salt_bootstrap_url: https://bootstrap.saltstack.com
+ salt_version: latest
+ formula: {{ cookiecutter.kitchen_formula }}
+ log_level: info
+ state_top:
+ base:
+ "*":
+ - {{ cookiecutter.kitchen_formula }}
+ pillars:
+ top.sls:
+ base:
+ "*":
+ - {{ cookiecutter.kitchen_formula }}
+ grains:
+ noservices: {{ 'True' if cookiecutter.kitchen_driver =='docker' else 'False' }}
+
+
+verifier:
+ name: {{ cookiecutter.kitchen_verifier }}
+ sudo: true
+
+
+platforms:
+ - name: ubuntu-14.04
+ - name: ubuntu-16.04
+ - name: centos-7.1
+
+
+suites:
+ {%- if cookiecutter.kitchen_suites == "" %}
+ #- name: default
+ # provisioner:
+ # pillars-from-files:
+ # {{ cookiecutter.kitchen_formula }}.sls: tests/pillar/default.sls
+ {%- else %}
+ {%- for suite in cookiecutter.kitchen_suites.split() %}
+
+ - name: {{ suite }}
+ provisioner:
+ pillars-from-files:
+ {{ cookiecutter.kitchen_formula }}.sls: tests/pillar/{{suite}}.sls
+ {%- endfor %}
+ {%- endif %}
+
+# vim: ft=yaml sw=2 ts=2 sts=2 tw=125
diff --git "a/\173\173cookiecutter.project_name\175\175/INTEGRATION.rst" "b/\173\173cookiecutter.project_name\175\175/INTEGRATION.rst"
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ "b/\173\173cookiecutter.project_name\175\175/INTEGRATION.rst"
diff --git "a/\173\173cookiecutter.project_name\175\175/Makefile" "b/\173\173cookiecutter.project_name\175\175/Makefile"
index c6a75af..fa15e0f 100644
--- "a/\173\173cookiecutter.project_name\175\175/Makefile"
+++ "b/\173\173cookiecutter.project_name\175\175/Makefile"
@@ -3,9 +3,26 @@
RECLASSDIR=/usr/share/salt-formulas/reclass
FORMULANAME=$(shell grep name: metadata.yml|head -1|cut -d : -f 2|grep -Eo '[a-z0-9\-\_]*')
+MAKE_PID := $(shell echo $$PPID)
+JOB_FLAG := $(filter -j%, $(subst -j ,-j,$(shell ps T | grep "^\s*$(MAKE_PID).*$(MAKE)")))
+
+ifneq ($(subst -j,,$(JOB_FLAG)),)
+JOBS := $(subst -j,,$(JOB_FLAG))
+else
+JOBS := 1
+endif
+
+KITCHEN_LOCAL_YAML?=.kitchen.yml
+KITCHEN_OPTS?="--concurrency=$(JOBS)"
+KITCHEN_OPTS_CREATE?=""
+KITCHEN_OPTS_CONVERGE?=""
+KITCHEN_OPTS_VERIFY?=""
+KITCHEN_OPTS_TEST?=""
+
all:
@echo "make install - Install into DESTDIR"
@echo "make test - Run tests"
+ @echo "make kitchen - Run Kitchen CI tests (create, converge, verify)"
@echo "make clean - Cleanup after tests run"
install:
@@ -21,6 +38,29 @@
test:
[ ! -d tests ] || (cd tests; ./run_tests.sh)
+kitchen: kitchen-create kitchen-converge kitchen-verify kitchen-list
+
+kitchen-create:
+ kitchen create ${KITCHEN_OPTS} ${KITCHEN_OPTS_CREATE}
+ [ "$(shell echo $(KITCHEN_LOCAL_YAML)|grep -Eo docker)" = "docker" ] || sleep 120
+
+kitchen-converge:
+ kitchen converge ${KITCHEN_OPTS} ${KITCHEN_OPTS_CONVERGE} &&\
+ kitchen converge ${KITCHEN_OPTS} ${KITCHEN_OPTS_CONVERGE}
+
+kitchen-verify:
+ [ ! -d tests/integration ] || kitchen verify -t tests/integration ${KITCHEN_OPTS} ${KITCHEN_OPTS_VERIFY}
+ [ -d tests/integration ] || kitchen verify ${KITCHEN_OPTS} ${KITCHEN_OPTS_VERIFY}
+
+kitchen-test:
+ [ ! -d tests/integration ] || kitchen test -t tests/integration ${KITCHEN_OPTS} ${KITCHEN_OPTS_TEST}
+ [ -d tests/integration ] || kitchen test ${KITCHEN_OPTS} ${KITCHEN_OPTS_TEST}
+
+kitchen-list:
+ kitchen list
+
clean:
+ [ ! -x "$(shell which kitchen)" ] || kitchen destroy
+ [ ! -d .kitchen ] || rm -rf .kitchen
[ ! -d tests/build ] || rm -rf tests/build
[ ! -d build ] || rm -rf build
diff --git "a/\173\173cookiecutter.project_name\175\175/README.rst" "b/\173\173cookiecutter.project_name\175\175/README.rst"
index a62942b..50931f1 100644
--- "a/\173\173cookiecutter.project_name\175\175/README.rst"
+++ "b/\173\173cookiecutter.project_name\175\175/README.rst"
@@ -17,6 +17,42 @@
enabled: true
version: icehouse
+
+Development and testing
+=======================
+
+Development and test workflow with `Test Kitchen <http://kitchen.ci>`_ and
+`kitchen-salt <https://github.com/simonmcc/kitchen-salt>`_ provisioner plugin.
+
+Test Kitchen is a test harness tool to execute your configured code on one or more platforms in isolation.
+There is a ``.kitchen.yml`` in main directory that defines *platforms* to be tested and *suites* to execute on them.
+
+Kitchen CI can spin instances locally or remote, based on used *driver*.
+For local development ``.kitchen.yml`` defines a `vagrant <https://github.com/test-kitchen/kitchen-vagrant>`_ or
+`docker <https://github.com/test-kitchen/kitchen-docker>`_ driver.
+
+To use backend drivers or implement your CI follow the section `INTEGRATION.rst#Continuous Integration`__.
+
+The `Busser <https://github.com/test-kitchen/busser>`_ *Verifier* is used to setup and run tests
+implementated in `<repo>/test/integration`. It installs the particular driver to tested instance
+(`Serverspec <https://github.com/neillturner/kitchen-verifier-serverspec>`_,
+`InSpec <https://github.com/chef/kitchen-inspec>`_, Shell, Bats, ...) prior the verification is executed.
+
+Usage:
+
+.. code-block:: shell
+
+ # list instances and status
+ kitchen list
+
+ # manually execute integration tests
+ kitchen [test || [create|converge|verify|exec|login|destroy|...]] [instance] -t tests/integration
+
+ # use with provided Makefile (ie: within CI pipeline)
+ make kitchen
+
+
+
Read more
=========