summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorzdc <zdc@users.noreply.github.com>2020-12-25 18:57:19 +0200
committerGitHub <noreply@github.com>2020-12-25 18:57:19 +0200
commit27c317f83d8e393254b6766b34fdf8d29148ea8f (patch)
treeea824de28fa639ba6ba8b212efaf53b5df2e90d9 /doc
parent66dc53b1b3f8786f3bbb25e914c1dc8161af0494 (diff)
parentc6bcb8df28daa234686a563549681082eb3283a1 (diff)
downloadvyos-cloud-init-27c317f83d8e393254b6766b34fdf8d29148ea8f.tar.gz
vyos-cloud-init-27c317f83d8e393254b6766b34fdf8d29148ea8f.zip
Merge pull request #28 from zdc/T2117-equuleus-20.4
T2117: Cloud-init updated to 20.4
Diffstat (limited to 'doc')
-rw-r--r--doc/examples/cloud-config-chef.txt3
-rw-r--r--doc/examples/cloud-config-power-state.txt2
-rw-r--r--doc/examples/cloud-config-user-groups.txt7
-rw-r--r--doc/examples/cloud-config.txt4
-rw-r--r--doc/rtd/index.rst3
-rw-r--r--doc/rtd/topics/boot.rst86
-rw-r--r--doc/rtd/topics/cloud_tests.rst (renamed from doc/rtd/topics/tests.rst)22
-rw-r--r--doc/rtd/topics/datasources/azure.rst6
-rw-r--r--doc/rtd/topics/datasources/opennebula.rst6
-rw-r--r--doc/rtd/topics/faq.rst68
-rw-r--r--doc/rtd/topics/instancedata.rst16
-rw-r--r--doc/rtd/topics/integration_tests.rst81
-rw-r--r--doc/rtd/topics/network-config-format-v1.rst38
-rw-r--r--doc/rtd/topics/network-config-format-v2.rst13
14 files changed, 320 insertions, 35 deletions
diff --git a/doc/examples/cloud-config-chef.txt b/doc/examples/cloud-config-chef.txt
index bb4b058c..8cebfd80 100644
--- a/doc/examples/cloud-config-chef.txt
+++ b/doc/examples/cloud-config-chef.txt
@@ -13,7 +13,8 @@
# Key from https://packages.chef.io/chef.asc
apt:
sources:
- source1: "deb http://packages.chef.io/repos/apt/stable $RELEASE main"
+ source1:
+ source: "deb http://packages.chef.io/repos/apt/stable $RELEASE main"
key: |
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.12 (Darwin)
diff --git a/doc/examples/cloud-config-power-state.txt b/doc/examples/cloud-config-power-state.txt
index 9cd56814..002707ec 100644
--- a/doc/examples/cloud-config-power-state.txt
+++ b/doc/examples/cloud-config-power-state.txt
@@ -18,7 +18,7 @@
# when 'timeout' seconds have elapsed.
#
# delay: form accepted by shutdown. default is 'now'. other format
-# accepted is +m (m in minutes)
+# accepted is '+m' (m in minutes)
# mode: required. must be one of 'poweroff', 'halt', 'reboot'
# message: provided as the message argument to 'shutdown'. default is none.
# timeout: the amount of time to give the cloud-init process to finish
diff --git a/doc/examples/cloud-config-user-groups.txt b/doc/examples/cloud-config-user-groups.txt
index b593cdd1..4a5a7e20 100644
--- a/doc/examples/cloud-config-user-groups.txt
+++ b/doc/examples/cloud-config-user-groups.txt
@@ -19,7 +19,7 @@ users:
primary_group: foobar
groups: users
selinux_user: staff_u
- expiredate: 2012-09-01
+ expiredate: '2012-09-01'
ssh_import_id: foobar
lock_passwd: false
passwd: $6$j212wezy$7H/1LT4f9/N3wpgNunhsIqtMj62OKiS3nyNwuizouQc3u7MbYCarYeAHWYPYb2FT.lbioDm2RrkJPb9BZMN1O/
@@ -34,7 +34,7 @@ users:
- <ssh pub key 2>
- name: cloudy
gecos: Magic Cloud App Daemon User
- inactive: true
+ inactive: '5'
system: true
- name: fizzbuzz
sudo: False
@@ -47,6 +47,7 @@ users:
# Valid Values:
# name: The user's login name
+# expiredate: Date on which the user's account will be disabled.
# gecos: The user name's real name, i.e. "Bob B. Smith"
# homedir: Optional. Set to the local path you want to use. Defaults to
# /home/<username>
@@ -57,7 +58,7 @@ users:
# "staff_u". When this is omitted the system will select the default
# SELinux user.
# lock_passwd: Defaults to true. Lock the password to disable password login
-# inactive: Create the user as inactive
+# inactive: Number of days after password expires until account is disabled
# passwd: The hash -- not the password itself -- of the password you want
# to use for this user. You can generate a safe hash via:
# mkpasswd --method=SHA-512 --rounds=4096
diff --git a/doc/examples/cloud-config.txt b/doc/examples/cloud-config.txt
index f3ae5e68..de9a0f87 100644
--- a/doc/examples/cloud-config.txt
+++ b/doc/examples/cloud-config.txt
@@ -518,10 +518,10 @@ manual_cache_clean: False
# syslog being taken down while cloud-init is running.
#
# delay: form accepted by shutdown. default is 'now'. other format
-# accepted is +m (m in minutes)
+# accepted is '+m' (m in minutes)
# mode: required. must be one of 'poweroff', 'halt', 'reboot'
# message: provided as the message argument to 'shutdown'. default is none.
power_state:
- delay: 30
+ delay: '+30'
mode: poweroff
message: Bye Bye
diff --git a/doc/rtd/index.rst b/doc/rtd/index.rst
index 0015e35a..ddcb0b31 100644
--- a/doc/rtd/index.rst
+++ b/doc/rtd/index.rst
@@ -75,6 +75,7 @@ Having trouble? We would like to help!
topics/dir_layout.rst
topics/analyze.rst
topics/docs.rst
- topics/tests.rst
+ topics/integration_tests.rst
+ topics/cloud_tests.rst
.. vi: textwidth=79
diff --git a/doc/rtd/topics/boot.rst b/doc/rtd/topics/boot.rst
index 4e79c958..a5282e35 100644
--- a/doc/rtd/topics/boot.rst
+++ b/doc/rtd/topics/boot.rst
@@ -157,4 +157,90 @@ finished, the ``cloud-init status`` subcommand can help block external
scripts until cloud-init is done without having to write your own systemd
units dependency chains. See :ref:`cli_status` for more info.
+First Boot Determination
+************************
+
+cloud-init has to determine whether or not the current boot is the first boot
+of a new instance or not, so that it applies the appropriate configuration. On
+an instance's first boot, it should run all "per-instance" configuration,
+whereas on a subsequent boot it should run only "per-boot" configuration. This
+section describes how cloud-init performs this determination, as well as why it
+is necessary.
+
+When it runs, cloud-init stores a cache of its internal state for use across
+stages and boots.
+
+If this cache is present, then cloud-init has run on this system before.
+[#not-present]_ There are two cases where this could occur. Most commonly,
+the instance has been rebooted, and this is a second/subsequent boot.
+Alternatively, the filesystem has been attached to a *new* instance, and this
+is an instance's first boot. The most obvious case where this happens is when
+an instance is launched from an image captured from a launched instance.
+
+By default, cloud-init attempts to determine which case it is running in by
+checking the instance ID in the cache against the instance ID it determines at
+runtime. If they do not match, then this is an instance's first boot;
+otherwise, it's a subsequent boot. Internally, cloud-init refers to this
+behavior as ``check``.
+
+This behavior is required for images captured from launched instances to
+behave correctly, and so is the default which generic cloud images ship with.
+However, there are cases where it can cause problems. [#problems]_ For these
+cases, cloud-init has support for modifying its behavior to trust the instance
+ID that is present in the system unconditionally. This means that cloud-init
+will never detect a new instance when the cache is present, and it follows that
+the only way to cause cloud-init to detect a new instance (and therefore its
+first boot) is to manually remove cloud-init's cache. Internally, this
+behavior is referred to as ``trust``.
+
+To configure which of these behaviors to use, cloud-init exposes the
+``manual_cache_clean`` configuration option. When ``false`` (the default),
+cloud-init will ``check`` and clean the cache if the instance IDs do not match
+(this is the default, as discussed above). When ``true``, cloud-init will
+``trust`` the existing cache (and therefore not clean it).
+
+Manual Cache Cleaning
+=====================
+
+cloud-init ships a command for manually cleaning the cache: ``cloud-init
+clean``. See :ref:`cli_clean`'s documentation for further details.
+
+Reverting ``manual_cache_clean`` Setting
+========================================
+
+Currently there is no support for switching an instance that is launched with
+``manual_cache_clean: true`` from ``trust`` behavior to ``check`` behavior,
+other than manually cleaning the cache.
+
+.. warning:: If you want to capture an instance that is currently in ``trust``
+ mode as an image for launching other instances, you **must** manually clean
+ the cache. If you do not do so, then instances launched from the captured
+ image will all detect their first boot as a subsequent boot of the captured
+ instance, and will not apply any per-instance configuration.
+
+ This is a functional issue, but also a potential security one: cloud-init is
+ responsible for rotating SSH host keys on first boot, and this will not
+ happen on these instances.
+
+.. [#not-present] It follows that if this cache is not present, cloud-init has
+ not run on this system before, so this is unambiguously this instance's
+ first boot.
+
+.. [#problems] A couple of ways in which this strict reliance on the presence
+ of a datasource has been observed to cause problems:
+
+ * If a cloud's metadata service is flaky and cloud-init cannot obtain the
+ instance ID locally on that platform, cloud-init's instance ID
+ determination will sometimes fail to determine the current instance ID,
+ which makes it impossible to determine if this is an instance's first or
+ subsequent boot (`#1885527`_).
+ * If cloud-init is used to provision a physical appliance or device and an
+ attacker can present a datasource to the device with a different instance
+ ID, then cloud-init's default behavior will detect this as an instance's
+ first boot and reset the device using the attacker's configuration
+ (this has been observed with the NoCloud datasource in `#1879530`_).
+
+.. _#1885527: https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/1885527
+.. _#1879530: https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/1879530
+
.. vi: textwidth=79
diff --git a/doc/rtd/topics/tests.rst b/doc/rtd/topics/cloud_tests.rst
index f03b5969..0fbb1301 100644
--- a/doc/rtd/topics/tests.rst
+++ b/doc/rtd/topics/cloud_tests.rst
@@ -1,6 +1,9 @@
-*******************
-Integration Testing
-*******************
+************************
+Cloud tests (Deprecated)
+************************
+
+Cloud tests are longer be maintained. For writing integration
+tests, see the :ref:`integration_tests` page.
Overview
========
@@ -148,17 +151,20 @@ cloud-init located in a different directory, use the option ``--cloud-init
Bddeb
-----
-The ``bddeb`` command can be used to generate a deb file. This is used by
-the tree_run and tree_collect commands to build a deb of the current
-working tree. It can also be used a user to generate a deb for use in other
-situations and avoid needing to have all the build and test dependencies
-installed locally.
+The ``bddeb`` command can be used to generate a deb file. This is used by the
+tree_run and tree_collect commands to build a deb of the current working tree
+using the packaging template contained in the ``packages/debian/`` directory.
+It can also be used to generate a deb for use in other situations and avoid
+needing to have all the build and test dependencies installed locally.
* ``--bddeb-args``: arguments to pass through to bddeb
* ``--build-os``: distribution to use as build system (default is xenial)
* ``--build-platform``: platform to use for build system (default is lxd)
* ``--cloud-init``: path to base of cloud-init tree (default is '.')
* ``--deb``: path to write output deb to (default is '.')
+* ``--packaging-branch``: import the ``debian/`` packaging directory
+ from the specified branch (default: ``ubuntu/devel``) instead of using
+ the packaging template.
Setup Image
-----------
diff --git a/doc/rtd/topics/datasources/azure.rst b/doc/rtd/topics/datasources/azure.rst
index fdb919a5..e04c3a33 100644
--- a/doc/rtd/topics/datasources/azure.rst
+++ b/doc/rtd/topics/datasources/azure.rst
@@ -68,6 +68,12 @@ configuration information to the instance. Cloud-init uses the IMDS for:
- network configuration for the instance which is applied per boot
- a preprovisioing gate which blocks instance configuration until Azure fabric
is ready to provision
+- retrieving SSH public keys. Cloud-init will first try to utilize SSH keys
+ returned from IMDS, and if they are not provided from IMDS then it will
+ fallback to using the OVF file provided from the CD-ROM. There is a large
+ performance benefit to using IMDS for SSH key retrieval, but in order to
+ support environments where IMDS is not available then we must continue to
+ all for keys from OVF
Configuration
diff --git a/doc/rtd/topics/datasources/opennebula.rst b/doc/rtd/topics/datasources/opennebula.rst
index 8e7c2558..350a3e93 100644
--- a/doc/rtd/topics/datasources/opennebula.rst
+++ b/doc/rtd/topics/datasources/opennebula.rst
@@ -122,13 +122,13 @@ OpenNebula datasource only in 'net' mode.
Example VM's context section
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-::
+.. code-block:: sh
CONTEXT=[
- PUBLIC_IP="$NIC[IP]",
SSH_KEY="$USER[SSH_KEY]
$USER[SSH_KEY1]
- $USER[SSH_KEY2] ",
+ $USER[SSH_KEY2]",
+ PUBLIC_IP="$NIC[IP]",
USER_DATA="#cloud-config
# see https://help.ubuntu.com/community/CloudInit
diff --git a/doc/rtd/topics/faq.rst b/doc/rtd/topics/faq.rst
index aa1be142..27fabf15 100644
--- a/doc/rtd/topics/faq.rst
+++ b/doc/rtd/topics/faq.rst
@@ -121,6 +121,12 @@ cloud-init:
$ sudo cloud-init init --local
$ sudo cloud-init init
+.. warning::
+
+ These commands will re-run cloud-init as if this were first boot of a
+ system: this will, at the very least, cycle SSH host keys and may do
+ substantially more. Do not run these commands on production systems.
+
How can I debug my user data?
=============================
@@ -135,12 +141,12 @@ that can validate your user data offline.
.. _validate-yaml.py: https://github.com/canonical/cloud-init/blob/master/tools/validate-yaml.py
-Another option is to run the following on an instance when debugging:
+Another option is to run the following on an instance to debug userdata
+provided to the system:
.. code-block:: shell-session
- $ sudo cloud-init query userdata > user-data.yaml
- $ cloud-init devel schema -c user-data.yaml --annotate
+ $ cloud-init devel schema --system --annotate
As launching instances in the cloud can cost money and take a bit longer,
sometimes it is easier to launch instances locally using Multipass or LXD:
@@ -226,12 +232,65 @@ custom network config.
.. _Instance Configuration: https://linuxcontainers.org/lxd/docs/master/instances
.. _Custom Network Configuration: https://linuxcontainers.org/lxd/docs/master/cloud-init
+cloud-localds
+-------------
+
+The `cloud-localds` command from the `cloud-utils`_ package generates a disk
+with user supplied data. 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 for example.
+
+The following is an example of creating the local disk using the cloud-localds
+command:
+
+.. code-block:: shell-session
+
+ $ cat >user-data <<EOF
+ #cloud-config
+ password: password
+ chpasswd:
+ expire: False
+ ssh_pwauth: True
+ ssh_authorized_keys:
+ - ssh-rsa AAAA...UlIsqdaO+w==
+ EOF
+ $ cloud-localds seed.img user-data
+
+The resulting seed.img can then get passed along to a cloud image containing
+cloud-init. Below is an example of passing the 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:
+
+.. code-block:: shell-session
+
+ $ cloud-localds --network-config=network-config-v2.yaml \
+ seed.img userdata.yaml metadata.yaml
+
+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:`nocloud` page.
+
+.. _cloud-utils: https://github.com/canonical/cloud-utils/
+
Where can I learn more?
========================================
Below are some videos, blog posts, and white papers about cloud-init from a
variety of sources.
+- `cloud-init - The Good Parts`_
+- `cloud-init Summit 2019`_
+- `Utilising cloud-init on Microsoft Azure (Whitepaper)`_
- `Cloud Instance Initialization with cloud-init (Whitepaper)`_
- `cloud-init Summit 2018`_
- `cloud-init - The cross-cloud Magic Sauce (PDF)`_
@@ -242,6 +301,9 @@ variety of sources.
- `The beauty of cloud-init`_
- `Introduction to cloud-init`_
+.. _cloud-init - The Good Parts: https://www.youtube.com/watch?v=2_m6EUo6VOI
+.. _cloud-init Summit 2019: https://powersj.io/post/cloud-init-summit19/
+.. _Utilising cloud-init on Microsoft Azure (Whitepaper): https://ubuntu.com/engage/azure-cloud-init-whitepaper
.. _Cloud Instance Initialization with cloud-init (Whitepaper): https://ubuntu.com/blog/cloud-instance-initialisation-with-cloud-init
.. _cloud-init Summit 2018: https://powersj.io/post/cloud-init-summit18/
.. _cloud-init - The cross-cloud Magic Sauce (PDF): https://events.linuxfoundation.org/wp-content/uploads/2017/12/cloud-init-The-cross-cloud-Magic-Sauce-Scott-Moser-Chad-Smith-Canonical.pdf
diff --git a/doc/rtd/topics/instancedata.rst b/doc/rtd/topics/instancedata.rst
index 255245a4..1850982c 100644
--- a/doc/rtd/topics/instancedata.rst
+++ b/doc/rtd/topics/instancedata.rst
@@ -592,6 +592,22 @@ see only redacted values.
% cloud-init query --format 'cloud: {{ v1.cloud_name }} myregion: {{
% v1.region }}'
+ # Locally test that your template userdata provided to the vm was rendered as
+ # intended.
+ % cloud-init query --format "$(sudo cloud-init query userdata)"
+
+ # The --format command renders jinja templates, this can also be used
+ # to develop and test jinja template constructs
+ % cat > test-templating.yaml <<EOF
+ {% for val in ds.meta_data.keys() %}
+ - {{ val }}
+ {% endfor %}
+ EOF
+ % cloud-init query --format="$( cat test-templating.yaml )"
+ - instance_id
+ - dsmode
+ - local_hostname
+
.. note::
To save time designing a user-data template for a specific cloud's
instance-data.json, use the 'render' cloud-init command on an
diff --git a/doc/rtd/topics/integration_tests.rst b/doc/rtd/topics/integration_tests.rst
new file mode 100644
index 00000000..aeda326c
--- /dev/null
+++ b/doc/rtd/topics/integration_tests.rst
@@ -0,0 +1,81 @@
+.. _integration_tests:
+
+*******************
+Integration Testing
+*******************
+
+Overview
+=========
+
+Integration tests are written using pytest and are located at
+``tests/integration_tests``. General design principles
+laid out in :ref:`unit_testing` should be followed for integration tests.
+
+Setup is accomplished via a set of fixtures located in
+``tests/integration_tests/conftest.py``.
+
+Image Setup
+===========
+
+Image setup occurs once when a test session begins and is implemented
+via fixture. Image setup roughly follows these steps:
+
+* Launch an instance on the specified test platform
+* Install the version of cloud-init under test
+* Run ``cloud-init clean`` on the instance so subsequent boots
+ resemble out of the box behavior
+* Take a snapshot of the instance to be used as a new image from
+ which new instances can be launched
+
+Test Setup
+==============
+Test setup occurs between image setup and test execution. Test setup
+is implemented via one of the ``client`` fixtures. When a client fixture
+is used, a test instance from which to run tests is launched prior to
+test execution and torn down after.
+
+Test Definition
+===============
+Tests are defined like any other pytest test. The ``user_data``
+mark can be used to supply the cloud-config user data. Platform specific
+marks can be used to limit tests to particular platforms. The
+client fixture can be used to interact with the launched
+test instance.
+
+A basic example:
+
+.. code-block:: python
+
+ USER_DATA = """#cloud-config
+ bootcmd:
+ - echo 'hello config!' > /tmp/user_data.txt"""
+
+
+ class TestSimple:
+ @pytest.mark.user_data(USER_DATA)
+ @pytest.mark.ec2
+ def test_simple(self, client):
+ print(client.exec('cloud-init -v'))
+
+Test Execution
+==============
+Test execution happens via pytest. To run all integration tests,
+you would run:
+
+.. code-block:: bash
+
+ pytest tests/integration_tests/
+
+
+Configuration
+=============
+
+All possible configuration values are defined in
+``tests/integration_tests/integration_settings.py``. Defaults can be
+overridden by supplying values in ``tests/integration_tests/user_settings.py``
+or by providing an environment variable of the same name prepended with
+``CLOUD_INIT_``. For example, to set the ``PLATFORM`` setting:
+
+.. code-block:: bash
+
+ CLOUD_INIT_PLATFORM='ec2' pytest tests/integration_tests/
diff --git a/doc/rtd/topics/network-config-format-v1.rst b/doc/rtd/topics/network-config-format-v1.rst
index 9723d689..92e81897 100644
--- a/doc/rtd/topics/network-config-format-v1.rst
+++ b/doc/rtd/topics/network-config-format-v1.rst
@@ -64,6 +64,14 @@ structure.
The MAC Address is a device unique identifier that most Ethernet-based network
devices possess. Specifying a MAC Address is optional.
+.. note::
+
+ MAC addresses must be strings. As MAC addresses which consist of only the
+ digits 0-9 (i.e. no hex a-f) can be interpreted as a base 60 integer per
+ the `YAML 1.1 spec`_ it is best practice to quote all MAC addresses to ensure
+ they are parsed as strings regardless of value.
+
+.. _YAML 1.1 spec: https://yaml.org/type/int.html
.. note::
@@ -91,7 +99,7 @@ packet- or frame-based network. Specifying ``mtu`` is optional.
# Simple network adapter
- type: physical
name: interface0
- mac_address: 00:11:22:33:44:55
+ mac_address: '00:11:22:33:44:55'
# Second nic with Jumbo frames
- type: physical
name: jumbo0
@@ -124,6 +132,14 @@ bond interfaces. Specifying a MAC Address is optional. If ``mac_address`` is
not present, then the bond will use one of the MAC Address values from one of
the bond interfaces.
+.. note::
+
+ MAC addresses must be strings. As MAC addresses which consist of only the
+ digits 0-9 (i.e. no hex a-f) can be interpreted as a base 60 integer per
+ the `YAML 1.1 spec`_ it is best practice to quote all MAC addresses to ensure
+ they are parsed as strings regardless of value.
+
+.. _YAML 1.1 spec: https://yaml.org/type/int.html
**bond_interfaces**: *<List of network device names>*
@@ -194,7 +210,7 @@ Valid ``params`` keys are:
# Simple network adapter
- type: physical
name: interface0
- mac_address: 00:11:22:33:44:55
+ mac_address: '00:11:22:33:44:55'
# 10G pair
- type: physical
name: gbe0
@@ -246,7 +262,7 @@ Valid keys are:
# Simple network adapter
- type: physical
name: interface0
- mac_address: 00:11:22:33:44:55
+ mac_address: '00:11:22:33:44:55'
# Second nic with Jumbo frames
- type: physical
name: jumbo0
@@ -303,7 +319,7 @@ packet- or frame-based network. Specifying ``mtu`` is optional.
# Physical interfaces.
- type: physical
name: eth0
- mac_address: "c0:d6:9f:2c:e8:80"
+ mac_address: c0:d6:9f:2c:e8:80
# VLAN interface.
- type: vlan
name: eth0.101
@@ -327,12 +343,12 @@ the following keys:
config:
- type: physical
name: interface0
- mac_address: 00:11:22:33:44:55
+ mac_address: '00:11:22:33:44:55'
subnets:
- type: static
address: 192.168.23.14/27
gateway: 192.168.23.1
- - type: nameserver:
+ - type: nameserver
address:
- 192.168.23.2
- 8.8.8.8
@@ -358,7 +374,7 @@ has the following keys:
config:
- type: physical
name: interface0
- mac_address: 00:11:22:33:44:55
+ mac_address: '00:11:22:33:44:55'
subnets:
- type: static
address: 192.168.23.14/24
@@ -410,7 +426,7 @@ the subnet dictionary.
config:
- type: physical
name: interface0
- mac_address: 00:11:22:33:44:55
+ mac_address: '00:11:22:33:44:55'
subnets:
- type: dhcp
@@ -422,7 +438,7 @@ the subnet dictionary.
config:
- type: physical
name: interface0
- mac_address: 00:11:22:33:44:55
+ mac_address: '00:11:22:33:44:55'
subnets:
- type: static
address: 192.168.23.14/27
@@ -443,7 +459,7 @@ using the static subnet configuration.
config:
- type: physical
name: interface0
- mac_address: 00:11:22:33:44:55
+ mac_address: '00:11:22:33:44:55'
subnets:
- type: dhcp
- type: static
@@ -462,7 +478,7 @@ using the static subnet configuration.
config:
- type: physical
name: interface0
- mac_address: 00:11:22:33:44:55
+ mac_address: '00:11:22:33:44:55'
subnets:
- type: dhcp
- type: static
diff --git a/doc/rtd/topics/network-config-format-v2.rst b/doc/rtd/topics/network-config-format-v2.rst
index c93e29be..aa17bef5 100644
--- a/doc/rtd/topics/network-config-format-v2.rst
+++ b/doc/rtd/topics/network-config-format-v2.rst
@@ -94,7 +94,16 @@ NetworkManager does not.
**macaddress**: *<(scalar)>*
-Device's MAC address in the form "XX:XX:XX:XX:XX:XX". Globs are not allowed.
+Device's MAC address in the form XX:XX:XX:XX:XX:XX. Globs are not allowed.
+
+.. note::
+
+ MAC addresses must be strings. As MAC addresses which consist of only the
+ digits 0-9 (i.e. no hex a-f) can be interpreted as a base 60 integer per
+ the `YAML 1.1 spec`_ it is best practice to quote all MAC addresses to ensure
+ they are parsed as strings regardless of value.
+
+.. _YAML 1.1 spec: https://yaml.org/type/int.html
**driver**: *<(scalar)>*
@@ -458,7 +467,7 @@ This is a complex example which shows most available features: ::
# opaque ID for physical interfaces, only referred to by other stanzas
id0:
match:
- macaddress: 00:11:22:33:44:55
+ macaddress: '00:11:22:33:44:55'
wakeonlan: true
dhcp4: true
addresses: