Kitchen::Vmpool
Ever wished you didn't have to wait for test-kitchen to create a test node? With kitchen-vmpool you can create your test nodes ahead of time and simply populate the pool with the list of hostnames. During the create step test kitchen will select a member of the test pool and you will instantly have a system to work with.
Kitchen-vmpool allows external scripts or programs to populate the pool so it is not tied to any single vm/container technology. Additionaly, kitchen-vmpool contains a pluggable storage backend so that you can store the pool information in just about anything.
Installation
gem 'kitchen-vmpool'
And then execute:
$ bundle
Or install it yourself as:
$ gem install kitchen-vmpool
Usage
To use setup the kitchen driver to use the vmpool store and configure one of the stores if required.
Gitlab Commit Store Example
If you have no central place to store files the gitlab_commit store may be an option for you. If you have a simple setup thus may suffice. If you plan to expand your usage of test kitchen to include multiple parallel test runs, you may run into race conditions due to the lack of a central queue to handle reads and writes. Perfect for simple setups. Later on you can move to a different state store.
driver:
name: vmpool
reuse_instances: false
state_store: gitlab_commit
store_options:
pool_file: 'vmpool'
project_id: 329302
platforms:
- name: rhel6
driver:
pool_name: base_rhel6_pool
- name: windows10
driver:
pool_name: windows10_pool
Gitlab Snippet Store Example
I don't recommend using the snippet store because gitlab's permission's model only allows a single user to make changes. Therefore this is a bad central place to keep things if only a single user can update. Use this as an example to create your own store providers.
driver:
name: vmpool
reuse_instances: false
state_store: gitlab_snippet
store_options:
pool_file: 'vmpool'
project_id: 329302
snippet_id: 49
platforms:
- name: rhel6
driver:
pool_name: base_rhel6_pool
- name: windows10
driver:
pool_name: windows10_pool
Plain old file store
Probably the easiest to setup, but is useful only for a single person on the same system.
driver:
name: vmpool
reuse_instances: false
state_store: file
store_options:
pool_file: 'vmpool'
platforms:
- name: rhel6
driver:
pool_name: base_rhel6_pool
- name: windows10
driver:
pool_name: windows10_pool
Pool data structure
The basic structure of the pool data can be found below. This is the current format that each state store will follow.
base_rhel6_pool:
payload_file: base_rhel6_payload.json
size: 1
pool_instances: []
requests: []
used_instances: []
windows10_pool:
payload_file: windows10_payload.json
size: 1
pool_instances: []
requests: []
used_instances: []
The payload_file key is not required and was used for other purposes outside of kitchen-vmpool in order to create the instances. It can be expected that some users will throw extra metadata in these pools for their own purposes. So care must be taken to not wipe out this data when creating a store.
Puppet's VMpooler
Consider the VMpooler state store to be the ultimate backend for kitchen-vmpool. While vmpool doesn't currently support vmpooler it is on the roadmap to support.
https://github.com/puppetlabs/vmpooler
Once the vmpooler state store is implemented this kitchen plugin might be pretty popular.
Development
This plugin was intended to support multiple ways to populate the pool and multiple ways to store the state of those pools. Therefore we leave it up to the user to create the pool instances while kitchen's job is only to interface with the pool information. Pool members need to be created outside of kitchen-vmpool. Additionally pool member information must also be updated outside of kitchen-vmpool.
Puppet's vmpooler will handle the maintenance of the pool state which is probably what you want.
Creating a State Store
In order to create a new state store you must do the following:
- inherit from the BaseStore or a subclass of the BaseStore
Implement the following methods:
- initialize(options = {})
- take_pool_member
- mark_unused
All other methods used with your store must be private
You must be careful to overwrite the entire pool data. It is expected that some users will put other metadata in the pool file for other purposes. So when you write your data please ensure you merge with the previous data first.
Example:
module Kitchen
module Driver
module VmpoolStores
class FileBaseStore < BaseStore
# @return [String] - a random host from the list of systems
# mark them used so nobody else can use it
def take_pool_member(pool_name)
member = pool_hosts(pool_name).sample
raise Kitchen::Driver::PoolMemberNotFound.new("No pool members exist for #{pool_name}, please create some pool members") unless member
mark_used(member, pool_name)
return member
end
# @param name [String] - the hostname to mark not used
# @return Array[String] - list of unused instances
def mark_unused(name, pool_name, reuse = false)
if reuse
used_hosts(pool_name).delete(name)
pool_hosts(pool_name) << name unless pool_hosts(pool_name).include?(name)
end
save
pool_hosts(pool_name)
end
end
end
end
end
Adding Configuration for your store
You can pass configuration to your store by setting the store_options in the driver section. This is a simple hash
that allows the user to pass in required settings if your store requires configuration. It is up to you
use these options since not every store will require configuration.
Development Setup
After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/logicminds/kitchen-vmpool. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the Kitchen::Vmpool project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.