Skip to content

Commit

Permalink
fixup: Split predeploy testing code into 'run cloud-init locally' and…
Browse files Browse the repository at this point in the history
… 'rerun cloud-init'
  • Loading branch information
holmanb committed Nov 16, 2023
1 parent dadfd1f commit 09dbdd8
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 21 deletions.
3 changes: 2 additions & 1 deletion doc/rtd/howto/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ How do I...?
.. toctree::
:maxdepth: 1

Test cloud-init locally before deploying <predeploy_testing.rst>
Run cloud-init locally before deploying <run_cloud_init_locally.rst>
Rerun cloud-init <rerun_cloud_init.rst>
Change how often a module runs <module_run_frequency.rst>
Validate my user data <check_user_data.rst>
Debug cloud-init <debugging.rst>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,12 @@
.. _predeploy_testing:
.. _rerun_cloud_init:

How to test ``cloud-init`` locally before deploying
***************************************************
How to rerun ``cloud-init``
***************************

How to run cloud-init locally
=============================
It's very likely that you will want to test ``cloud-init`` locally before
deploying it to the cloud. Fortunately, there are several different virtual
machine (VM) and container tools that are ideal for this sort of local
testing.
.. _fully_rerun_cloud_init:

To run cloud-init locally, head over to the
:ref:`tutorials page<tutorial_index>` page, which will show you how to run
cloud-init locally. Once you know how to run cloud-init locally, you may wish
to "rerun" cloud-init while developing your cloud config for faster
development.

.. _how_to_rerun_cloud-init:

How to re-run cloud-init
========================
How to fully re-run cloud-init
==============================

Most cloud-init configuration is only applied to the system once. This means
that simply rebooting the system will only re-run a subset of cloud-init.
Expand All @@ -31,6 +18,7 @@ Cloud-init provides two different options for rerunning cloud-init for debugging

Option #1: Remove the logs and cache then reboot
************************************************

This method will reboot the system as if cloud-init never ran. This
command does not remove all cloud-init artifacts from previous runs of
cloud-init, but it will clean enough artifacts to allow cloud-init to
Expand All @@ -42,6 +30,7 @@ think that it hasn't ran yet and re-run after a reboot.
Option #2: Run a single cloud-init module
*****************************************

If you are using :ref:`user data cloud-config<user_data_formats-cloud_config>`
format, you might wish to rerun just a single configuration module.
Cloud-init provides the ability to run a single module in isolation and
Expand All @@ -63,16 +52,17 @@ Example output:
Generating public/private ed25519 key pair
...
.. note::
Each cloud-config module has a module ``FREQUENCY`` configured: ``PER_INSTANCE``, ``PER_BOOT``, ``PER_ONCE`` or ``PER_ALWAYS``. When a module is run by cloud-init, it stores a semaphore file in :file:`/var/lib/cloud/instance/sem/config_<module_name>.<frequency>` which marks when the module last successfully ran. Presence of this semaphore file prevents a module from running again if it has already been run. To ensure that a module is run again, the desired frequency can be overridden via the command line:

Inspect :file:`cloud-init.log` for output of what operations were performed as
a result.

.. _partially_rerun_cloud_init:

How to partially re-run cloud-init
==================================

If the behavior you are testing runs on every boot, there are a couple
of ways to test this behavior.

Expand Down
133 changes: 133 additions & 0 deletions doc/rtd/howto/run_cloud_init_locally.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
.. _run_cloud_init_locally:

How to run ``cloud-init`` locally
*********************************

It's very likely that you will want to test ``cloud-init`` locally before
deploying it to the cloud. Fortunately, there are several different virtual
machine (VM) and container tools that are ideal for this sort of local
testing.

QEMU
====
Qemu is a general purpose computer hardware emulator that is capable of
running virtual machines with hardware acceleration while emulating the host's
instruction set on native architectures (via kvm), as well as emulating
instruction sets that are different from the host that you are running on.

The ``NoCloud`` datasouce allows users to provide their own user data,
metadata, or network configuration directly to an instance without running a
network service. This is helpful for launching local cloud images with QEMU.

The following is an example of creating the local disk using the
:command:`genisoimage` command:

.. code-block:: shell-session
$ touch network-config
$ touch meta-data
$ cat >user-data <<EOF
#cloud-config
password: password
chpasswd:
expire: False
ssh_pwauth: True
ssh_authorized_keys:
- ssh-rsa AAAA...UlIsqdaO+w==
EOF
.. code-block:: shell-session
genisoimage \
-output seed.img \
-volid cidata -rational-rock -joliet \
user-data meta-data network-config
See the :ref:`network_config_v2` page for details on the format and config of
network configuration. To learn more about the possible values for metadata,
check out the :ref:`datasource_nocloud` page.

The resulting :file:`seed.img` can then be passed along to a cloud image
containing ``cloud-init``. Below is an example of passing the :file:`seed.img`
with QEMU:

.. code-block:: shell-session
$ qemu-system-x86_64 -m 1024 -net nic -net user \
-hda ubuntu-20.04-server-cloudimg-amd64.img \
-hdb seed.img
The now-booted image will allow for login using the password provided above.

For additional configuration, users can provide much more detailed
configuration, including network configuration and metadata:

LXD
===

`LXD`_ offers a streamlined user experience for using Linux system containers.
With LXD.

The following command initialises a container with user data:

.. code-block:: shell-session
$ lxc init ubuntu-daily:bionic test-container
$ lxc config set test-container user.user-data - < userdata.yaml
$ lxc start test-container
To avoid the extra commands this can also be done at launch:

.. code-block:: shell-session
$ lxc launch ubuntu-daily:jammy test-container --config=user.user-data="$(cat userdata.yaml)"
Finally, a profile can be set up with the specific data if you need to
launch this multiple times:

.. code-block:: shell-session
$ lxc profile create dev-user-data
$ lxc profile set dev-user-data user.user-data - < cloud-init-config.yaml
$ lxc launch ubuntu-daily:bionic test-container -p default -p dev-user-data
The above examples all show how to pass user data. To pass other types of
configuration data use the config option specified below:

+----------------+---------------------------+
| Data | Config option |
+================+===========================+
| user data | cloud-init.user-data |
+----------------+---------------------------+
| vendor data | cloud-init.vendor-data |
+----------------+---------------------------+
| network config | cloud-init.network-config |
+----------------+---------------------------+

See the LXD `Instance Configuration`_ docs for more info about configuration
values or the LXD `Custom Network Configuration`_ document for more about
custom network config.

Multipass
=========
`Multipass`_ is a cross-platform tool for launching Ubuntu VMs across Linux,
Windows, and macOS.

When a user launches a Multipass VM, user data can be passed by adding the
``--cloud-init`` flag and the appropriate YAML file containing the user data:

.. code-block:: shell-session
$ multipass launch bionic --name test-vm --cloud-init userdata.yaml
Multipass will validate the user-data cloud-config file before attempting to
start the VM. This breaks all cloud-init configuration formats except user data
cloud-config.

.. _Multipass: https://multipass.run/
.. _LXD: https://ubuntu.com/lxd
.. _QEMU: https://www.qemu.org/
.. _Instance Configuration: https://documentation.ubuntu.com/lxd/en/latest/instances/
.. _Custom Network Configuration: https://documentation.ubuntu.com/lxd/en/latest/cloud-init/
.. _cloud-utils: https://github.com/canonical/cloud-utils/

0 comments on commit 09dbdd8

Please sign in to comment.