Building a CPI
This topic describes how to build a CPI.
CPIs are distributed as regular releases, typically with a release job called
cpi and a few packages that provide compilation/runtime environment for that job if necessary (e.g. bosh-aws-cpi-release includes Ruby and bosh-warden-cpi-release includes golang). To qualify to be a CPI release, it must include a release job that has
bosh create-env command and the Director expect to be configured with a CPI release to function properly. In the case of
bosh create-env command, specified CPI release is unpacked and installed on the machine running the command. For the Director, CPI release job is colocated on the same VM, so that the director release job can access it.
When building a CPI release, the primary requirement is that it provides a
bin/cpi executable which implements a simple RPC API through
STDOUT. The RPC API page provides an in-depth look at the protocol and required methods.
If you are getting started with a new CPI, you may be interested in using one of the following languages. These releases take advantage of some existing libraries that you may find useful in your own implementation.
bosh_cpi gem provides a
Bosh::Cpi::Cli class which handles the deserialization and serialization of the RPC calls. You can see examples of this in the following CPIs:
- Amazon Web Services CPI Release
- Microsoft Azure CPI Release
- OpenStack CPI Release
- VMware vSphere CPI Release
- VMware vCloud CPI Release
There are a few CPI releases written in Go, as well:
There are two test suites each CPI is expected to pass before it's considered to be production-ready:
- its own CPI Lifecycle Tests which should provide integration level coverage for each CPI method
- shared BOSH Acceptance Tests (BATS) (provided by the BOSH team) which verify high level Director behavior with the CPI activated
The CPI is expected to handle multiple method calls concurrently (and in parallel) with a promise that arguments represent different IaaS resources. For example, multiple
create_vm CPI method calls may be issued that all use the same stemcell cloud ID; however,
attach_disk CPI method will never be called with the same VM cloud ID concurrently.
Since each CPI method call is a separate OS process, simple locking techniques (Ruby's
Mutex.new for example) will not work.
Most CPIs have to deal with IaaS APIs that rate limit (e.g. OpenStack, AWS). Currently it is the responsibility of the CPI to handle rate-limiting errors, properly catch them, wait and retry actions that were interrupted. Given that there is no timeout around how long a CPI method can run, it's all right to wait as long as necessary to resume making API calls. Though it's suggested to log such information.
It usually useful to get a detailed log of CPI requests and responses from the callee. To get a full debug log from
bosh create-env command set
BOSH_LOG_LEVEL=debug environment variable.
When working with the Director you can find similar debug logs via
bosh task X --debug command.