Petr Michalec | d1ff7bd | 2016-07-14 10:43:13 +0200 | [diff] [blame^] | 1 | #!/bin/bash |
| 2 | |
| 3 | # usage: |
| 4 | # cd <formula repo>; ./kitchen_init.sh |
| 5 | |
| 6 | |
| 7 | # CONFIG |
| 8 | |
| 9 | export DRIVER=${DRIVER:-vagrant} # vagrant, dokken, openstack, ... |
| 10 | export VERIFIER=${VERIFIER:-inspec} # serverspec, pester |
| 11 | export KITCHEN_YML=${KITCHEN_YML:-.kitchen.yml} |
| 12 | |
| 13 | export FORMULA=${FORMULA:-$(awk -F: '/name/{gsub(/[\ \"]/,"");print $2}' metadata.yml)} |
| 14 | export SUITES=$(ls tests/pillar|xargs -I{} basename {} .sls) |
| 15 | |
| 16 | |
| 17 | # INIT |
| 18 | |
| 19 | test ! -e .kitchen.yml || { |
| 20 | kitchen init -D kitchen-docker -P kitchen-salt --no-create-gemfile |
| 21 | echo .kitchen >> .gitignore |
| 22 | rm -rf test |
| 23 | rm -f .kitchen.yml |
| 24 | rm -f chefignore |
| 25 | } |
| 26 | |
| 27 | test -e INTEGRATION.rst || \ |
| 28 | wget 'https://git.tcpcloud.eu/cookiecutter-templates/cookiecutter-salt-formula/raw/master/%7B%7Bcookiecutter.project_name%7D%7D/INTEGRATION.rst' -O INTEGRATION.rst 2>/dev/null |
| 29 | |
| 30 | # CONFIGURE & SCAFFOLD TEST STRUCTURE |
| 31 | |
| 32 | test -d tests/integration || { |
| 33 | for suite in $SUITES; do |
| 34 | mkdir -p tests/integration/$suite/$VERIFIER |
| 35 | done |
| 36 | mkdir -p tests/integration/helpers/$VERIFIER/ |
| 37 | touch $_/spec_helper.rb |
| 38 | } |
| 39 | |
| 40 | |
| 41 | # .KITCHEN.YML |
| 42 | |
| 43 | cat > .kitchen.yml.jinja <<-EOF |
| 44 | --- |
| 45 | driver: |
| 46 | name: $DRIVER |
| 47 | {%- if DRIVER == 'docker' %} |
| 48 | hostname: $FORMULA.ci.local |
| 49 | use_sudo: false |
| 50 | {%- elif DRIVER == 'vagrant' %} |
| 51 | vm_hostname: $FORMULA.ci.local |
| 52 | use_sudo: false |
| 53 | customize: |
| 54 | memory: 512 |
| 55 | {%- endif %} |
| 56 | |
| 57 | |
| 58 | provisioner: |
| 59 | name: salt_solo |
| 60 | salt_install: bootstrap |
| 61 | salt_bootstrap_url: https://bootstrap.saltstack.com |
| 62 | salt_version: latest |
| 63 | formula: $FORMULA |
| 64 | log_level: info |
| 65 | state_top: |
| 66 | base: |
| 67 | "*": |
| 68 | - $FORMULA |
| 69 | pillars: |
| 70 | top.sls: |
| 71 | base: |
| 72 | "*": |
| 73 | - $FORMULA |
| 74 | grains: |
| 75 | noservices: {{ 'True' if DRIVER=='docker' else 'False' }} |
| 76 | |
| 77 | |
| 78 | verifier: |
| 79 | name: $VERIFIER |
| 80 | sudo: true |
| 81 | |
| 82 | |
| 83 | platforms: |
| 84 | - name: ubuntu-14.04 |
| 85 | - name: ubuntu-16.04 |
| 86 | - name: centos-7.1 |
| 87 | |
| 88 | |
| 89 | suites: |
| 90 | {%- if DRIVER == 'vagrant' %} |
| 91 | # Default suite, smoke test, setup prerequisites and executes run ./tests/run_tests.sh |
| 92 | - name: default |
| 93 | includes: |
| 94 | - ubuntu-16.04 |
| 95 | driver: |
| 96 | name: local |
| 97 | provision_command: |
| 98 | - apt-get install -y git build-essential python-pip python-yaml python-dev python-virtualenv |
| 99 | provisioner: |
| 100 | name: shell |
| 101 | script: tests/bootstrap.sh |
| 102 | |
| 103 | {%- endif %} |
| 104 | {%- for suite in SUITES.split() %} |
| 105 | |
| 106 | - name: {{ suite }} |
| 107 | provisioner: |
| 108 | pillars-from-files: |
| 109 | $FORMULA.sls: tests/pillar/{{suite}}.sls |
| 110 | {%- endfor %} |
| 111 | |
| 112 | # vim: ft=yaml sw=2 ts=2 sts=2 tw=125 |
| 113 | EOF |
| 114 | |
| 115 | #FIXME, remove comment \{\% for name, value in environment('SUITE_') \%\} |
| 116 | |
| 117 | which envtpl &> /dev/null|| pip3 install envtpl |
| 118 | envtpl < .kitchen.yml.jinja > .kitchen.yml |
| 119 | |
| 120 | [[ "$DRIVER" != "docker" ]] && { |
| 121 | test -e .kitchen.docker.yml || \ |
| 122 | DRIVER=docker envtpl < <(head -n12 .kitchen.yml.jinja) > .kitchen.docker.yml |
| 123 | } |
| 124 | |
| 125 | |
| 126 | test -e .kitchen.openstack.yml || \ |
| 127 | cat > .kitchen.openstack.yml <<-\EOF |
| 128 | # usage: `KITCHEN_LOCAL_YAML=.kitchen.openstack.yml kitchen test` |
| 129 | |
| 130 | # https://docs.chef.io/config_yml_kitchen.html |
| 131 | # https://github.com/test-kitchen/kitchen-openstack |
| 132 | |
| 133 | --- |
| 134 | driver: |
| 135 | name: openstack |
| 136 | openstack_auth_url: <%= ENV['OS_AUTH_URL'] %>/tokens |
| 137 | openstack_username: <%= ENV['OS_USERNAME'] || 'ci' %> |
| 138 | openstack_api_key: <%= ENV['OS_PASSWORD'] || 'ci' %> |
| 139 | openstack_tenant: <%= ENV['OS_TENANT_NAME'] || 'ci_jenkins' %> |
| 140 | |
| 141 | #floating_ip_pool: <%= ENV['OS_FLOATING_IP_POOL'] || 'nova' %> |
| 142 | key_name: <%= ENV['BOOTSTRAP_SSH_KEY_NAME'] || 'bootstrap_insecure' %> |
| 143 | private_key_path: <%= ENV['BOOTSTRAP_SSH_KEY_PATH'] || "#{ENV['HOME']}/.ssh/id_rsa_bootstrap_insecure" %> |
| 144 | |
| 145 | |
| 146 | platforms: |
| 147 | - name: ubuntu-14.04 |
| 148 | driver: |
| 149 | username: <%= ENV['OS_UBUNTU_IMAGE_USER'] || 'root' %> |
| 150 | image_ref: <%= ENV['OS_UBUNTU_IMAGE_REF'] || 'ubuntu-14-04-x64-1455869035' %> |
| 151 | flavor_ref: m1.medium |
| 152 | network_ref: |
| 153 | <% if ENV['OS_NETWORK_REF'] -%> |
| 154 | - <% ENV['OS_NETWORK_REF'] %> |
| 155 | <% else -%> |
| 156 | - ci-net |
| 157 | <% end -%> |
| 158 | # force update apt cache on the image |
| 159 | run_list: |
| 160 | - recipe[apt] |
| 161 | attributes: |
| 162 | apt: |
| 163 | compile_time_update: true |
| 164 | transport: |
| 165 | username: <%= ENV['OS_UBUNTU_IMAGE_USER'] || 'root' %> |
| 166 | |
| 167 | # vim: ft=yaml sw=2 ts=2 sts=2 tw=125 |
| 168 | EOF |
| 169 | |
| 170 | |
| 171 | # CLEANUP |
| 172 | rm -f .kitchen.yml.jinja |
| 173 | |
| 174 | |
| 175 | # ADD CHANGES TO GIT |
| 176 | |
| 177 | git add \ |
| 178 | .gitignore \ |
| 179 | .kitchen*yml \ |
| 180 | INTEGRATION.rst |
| 181 | |
| 182 | |
| 183 | |
| 184 | # UPDATE README |
| 185 | |
| 186 | # skip if already updated |
| 187 | grep -Eoq 'Development and testing' README.* && exit 0 |
| 188 | |
| 189 | KITCHEN_LIST=$(kitchen list|tail -n+2) |
| 190 | cat >> README.* <<-\EOF |
| 191 | |
| 192 | Development and testing |
| 193 | ======================= |
| 194 | |
| 195 | Development and test workflow with `Test Kitchen <http://kitchen.ci>`_ and |
| 196 | `kitchen-salt <https://github.com/simonmcc/kitchen-salt>`_ provisioner plugin. |
| 197 | |
| 198 | Test Kitchen is a test harness tool to execute your configured code on one or more platforms in isolation. |
| 199 | There is a ``.kitchen.yml`` in main directory that defines *platforms* to be tested and *suites* to execute on them. |
| 200 | |
| 201 | Kitchen CI can spin instances locally or remote, based on used *driver*. |
| 202 | For local development ``.kitchen.yml`` defines a `vagrant <https://github.com/test-kitchen/kitchen-vagrant>`_ or |
| 203 | `docker <https://github.com/test-kitchen/kitchen-docker>`_ driver. |
| 204 | |
| 205 | To use backend drivers or implement your CI follow the section `INTEGRATION.rst#Continuous Integration`__. |
| 206 | |
| 207 | A listing of scenarios to be executed: |
| 208 | |
| 209 | .. code-block:: shell |
| 210 | |
| 211 | $ kitchen list |
| 212 | |
| 213 | Instance Driver Provisioner Verifier Transport Last Action |
| 214 | |
| 215 | EOF |
| 216 | |
| 217 | echo "$KITCHEN_LIST" | sed 's/^/ /' >> README.* |
| 218 | |
| 219 | cat >> README.* <<-\EOF |
| 220 | |
| 221 | The `Busser <https://github.com/test-kitchen/busser>`_ *Verifier* is used to setup and run tests |
| 222 | implementated in `<repo>/test/integration`. It installs the particular driver to tested instance |
| 223 | (`Serverspec <https://github.com/neillturner/kitchen-verifier-serverspec>`_, |
| 224 | `InSpec <https://github.com/chef/kitchen-inspec>`_, Shell, Bats, ...) prior the verification is executed. |
| 225 | |
| 226 | |
| 227 | Usage: |
| 228 | |
| 229 | .. code-block:: shell |
| 230 | |
| 231 | # manually |
| 232 | kitchen [test || [create|converge|verify|exec|login|destroy|...]] -t tests/integration |
| 233 | |
| 234 | # or with provided Makefile within CI pipeline |
| 235 | make kitchen |
| 236 | |
| 237 | EOF |
| 238 | |
| 239 | git add README.* |
| 240 | git status |
| 241 | |
| 242 | echo "Note: Dont forget to add kitchen targets to 'Makefile'. |