Building a CPI
This topic describes how to build a CPI.
Distribution¶
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 bin/cpi
executable.
Both 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.
Implementation¶
When building a CPI release, the primary requirement is that it provides a bin/cpi
executable which implements a simple RPC API through STDIN
/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.
Ruby¶
The 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
Go¶
There are a few CPI releases written in Go, as well:
Testing¶
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
Concurrency¶
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.
Note
Since each CPI method call is a separate OS process, simple locking techniques
(Ruby's Mutex.new
for example) will not work.
Rate Limiting¶
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.
Debugging¶
It is 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.
Migrating from V1 to V2 of the CPI API contract¶
The CPI library can be safely upgraded to V2, as all the method calls in V1 are maintained. To take advantage of the new features, please refer to the V1 to V2 migration guide