Supporting your cloud or platform¶
The upstream cloud-init project regularly accepts code contributions for new platforms that wish to support cloud-init.
Ways to add platform support¶
To add cloud-init support for a new platform, there are two possible approaches:
Provide platform compatibility with one of the existing datasource definitions, such as nocloud via DatasourceNoCloud.py. Several platforms, including Libvirt and Proxmox use this approach.
Add a new datasource definition to upstream cloud-init. This provides tighter integration, a better debugging experience, and more control and flexibility of cloud-init’s interaction with the datasource. This option is more sensible for clouds that have a unique architecture.
Platform requirements¶
There are some technical and logistical prerequisites that must be met for cloud-init support.
Technical requirements¶
A cloud needs to be able to identify itself to cloud-init at runtime, and that the cloud be able to provide configuration to the instance.
A mechanism for self-identification¶
Each cloud platform must positively identify itself to the guest. This allows
the guest to make educated decisions based on the platform on which it is
running. On the x86 and arm64 architectures, many clouds identify themselves
through DMI data. For example, Oracle’s public cloud provides the string
'OracleCloud.com'
in the DMI chassis-asset field.
Cloud-init
-enabled images produce a log file with details about the
platform. Reading through this log in /run/cloud-init/ds-identify.log
may provide the information needed to uniquely identify the platform.
If the log is not present, one can generate the log by running ds-identify
manually.
The mechanism used to identify the platform will be required for
ds-identify
and the datasource module sections below.
A mechanism for cloud-init to retrieve configuration¶
There are different methods that cloud-init can use to retrieve cloud-configuration for configuring the instance. The most common method is a webserver providing configuration over a link-local network.
Logistical requirements¶
As with any open source project, multiple logistal requirements exist.
Testing access¶
A platform that isn’t available for testing cannot be independently validated. You will need to provide some means for community members and upstream developers to test and verify this platform. Code that cannot be used cannot be supported.
Maintainer support¶
A point of contact is required who can answer questions and occasionally provide testing or maintenance support. Maintainership is relatively informal, but there is an expectation that from time to time upstream may need to contact a the maintainer with inquiries. Datasources that appear to be unmaintained and/or unused may be considered for eventual removal.
Adding cloud-init support¶
There are multiple ways to provide user data, metadata, and
vendor data, and each cloud solution prefers its own way. A datasource
abstract base class defines a single interface to interact with the different
clouds. Each cloud implementation must inherit from this base class to use this
shared functionality and interface. See cloud-init/sources/__init__.py
to see this class.
If you are interested in adding a new datasource for your cloud platform you will need to do all of the following:
Add datasource module cloudinit/sources/DataSource<CloudPlatform>.py¶
We suggest you start by copying one of the simpler datasources
such as DataSourceHetzner
.
Re-run datasource detection¶
While developing a new datasource it may be helpful to manually run datasource detection without rebooting the system.
To re-run datasource detection, you must first force ds-identify
to
re-run, then clean up any logs, and finally, re-run cloud-init
:
sudo DI_LOG=stderr /usr/lib/cloud-init/ds-identify --force
sudo cloud-init clean --logs
sudo cloud-init init --local
sudo cloud-init init
Add tests for datasource module¶
Add a new file with some tests for the module to
cloudinit/sources/test_<yourplatform>.py
. For example, see
cloudinit/sources/tests/test_oracle.py
Update ds-identify
¶
In systemd
systems, ds-identify
is used to detect which datasource
should be enabled, or if cloud-init
should run at all. You’ll need to
make changes to tools/ds-identify
.
Add tests for ds-identify
¶
Add relevant tests in a new class to
tests/unittests/test_ds_identify.py
. You can use TestOracle
as
an example.
Add your datasource name to the built-in list of datasources¶
Add your datasource module name to the end of the datasource_list
entry in cloudinit/settings.py
.
Add your cloud platform to apport collection prompts¶
Update the list of cloud platforms in cloudinit/apport.py
. This list
will be provided to the user who invokes ubuntu-bug cloud-init.
Enable datasource by default in Ubuntu packaging branches¶
Ubuntu packaging branches contain a template file,
config/cloud.cfg.tmpl
, which ultimately sets the default
datasource_list
that is installed by distros that use the upstream
packaging configuration.
Add documentation for your datasource¶
You should update the following docs:
1. Add a new file in doc/rtd/reference/datasources/<cloudplatform>.rst
2. Reference <cloudplatform>.rst in doc/rtd/reference/datasources.rst
3. Add an alphebetized dsname entry in representing your datasource
doc/rtd/reference/datasource_dsname_map.rst
Benefits of including your datasource in upstream cloud-init¶
Datasources included in upstream cloud-init benefit from ongoing maintenance, compatibility with the rest of the codebase, and security fixes by the upstream development team.
If this is not possible, one can add custom out-of-tree datasources to cloud-init.