From 99faf3ece1badc566e7e75e769ff374250196197 Mon Sep 17 00:00:00 2001 From: Ryan Harper Date: Wed, 29 Mar 2017 22:03:04 -0500 Subject: doc: document network configuration defaults policy and formats. Add documentation for cloud-init networking configuration formats, default behavior, policy and other specific details about how network config is consumed and utilized. --- doc/rtd/index.rst | 1 + doc/rtd/topics/datasources/altcloud.rst | 2 + doc/rtd/topics/datasources/azure.rst | 2 + doc/rtd/topics/datasources/cloudsigma.rst | 2 + doc/rtd/topics/datasources/cloudstack.rst | 2 + doc/rtd/topics/datasources/configdrive.rst | 2 + doc/rtd/topics/datasources/digitalocean.rst | 2 + doc/rtd/topics/datasources/ec2.rst | 2 + doc/rtd/topics/datasources/fallback.rst | 2 + doc/rtd/topics/datasources/maas.rst | 2 + doc/rtd/topics/datasources/nocloud.rst | 39 ++ doc/rtd/topics/datasources/opennebula.rst | 2 + doc/rtd/topics/datasources/openstack.rst | 2 + doc/rtd/topics/datasources/ovf.rst | 2 + doc/rtd/topics/datasources/smartos.rst | 2 + doc/rtd/topics/network-config-format-eni.rst | 20 + doc/rtd/topics/network-config-format-v1.rst | 563 +++++++++++++++++++++++++++ doc/rtd/topics/network-config-format-v2.rst | 503 ++++++++++++++++++++++++ doc/rtd/topics/network-config.rst | 254 ++++++++++++ 19 files changed, 1406 insertions(+) create mode 100644 doc/rtd/topics/network-config-format-eni.rst create mode 100644 doc/rtd/topics/network-config-format-v1.rst create mode 100644 doc/rtd/topics/network-config-format-v2.rst create mode 100644 doc/rtd/topics/network-config.rst (limited to 'doc') diff --git a/doc/rtd/index.rst b/doc/rtd/index.rst index 8f163b6a..a691103e 100644 --- a/doc/rtd/index.rst +++ b/doc/rtd/index.rst @@ -38,6 +38,7 @@ initialization of a cloud instance. topics/logging.rst topics/modules.rst topics/merging.rst + topics/network-config.rst topics/vendordata.rst topics/moreinfo.rst topics/hacking.rst diff --git a/doc/rtd/topics/datasources/altcloud.rst b/doc/rtd/topics/datasources/altcloud.rst index 202b0a4a..eeb197f2 100644 --- a/doc/rtd/topics/datasources/altcloud.rst +++ b/doc/rtd/topics/datasources/altcloud.rst @@ -1,3 +1,5 @@ +.. _datasource_alt_cloud: + Alt Cloud ========= diff --git a/doc/rtd/topics/datasources/azure.rst b/doc/rtd/topics/datasources/azure.rst index 18d7c506..4a3735b5 100644 --- a/doc/rtd/topics/datasources/azure.rst +++ b/doc/rtd/topics/datasources/azure.rst @@ -1,3 +1,5 @@ +.. _datasource_azure: + Azure ===== diff --git a/doc/rtd/topics/datasources/cloudsigma.rst b/doc/rtd/topics/datasources/cloudsigma.rst index 54963f61..86b834c8 100644 --- a/doc/rtd/topics/datasources/cloudsigma.rst +++ b/doc/rtd/topics/datasources/cloudsigma.rst @@ -1,3 +1,5 @@ +.. _datasource_cloudsigma: + CloudSigma ========== diff --git a/doc/rtd/topics/datasources/cloudstack.rst b/doc/rtd/topics/datasources/cloudstack.rst index 04603d9c..225093a1 100644 --- a/doc/rtd/topics/datasources/cloudstack.rst +++ b/doc/rtd/topics/datasources/cloudstack.rst @@ -1,3 +1,5 @@ +.. _datasource_cloudstack: + CloudStack ========== diff --git a/doc/rtd/topics/datasources/configdrive.rst b/doc/rtd/topics/datasources/configdrive.rst index 11dd52ab..f1a488a2 100644 --- a/doc/rtd/topics/datasources/configdrive.rst +++ b/doc/rtd/topics/datasources/configdrive.rst @@ -1,3 +1,5 @@ +.. _datasource_config_drive: + Config Drive ============ diff --git a/doc/rtd/topics/datasources/digitalocean.rst b/doc/rtd/topics/datasources/digitalocean.rst index c6f5bc74..938ede89 100644 --- a/doc/rtd/topics/datasources/digitalocean.rst +++ b/doc/rtd/topics/datasources/digitalocean.rst @@ -1,3 +1,5 @@ +.. _datasource_digital_ocean: + Digital Ocean ============= diff --git a/doc/rtd/topics/datasources/ec2.rst b/doc/rtd/topics/datasources/ec2.rst index 4810c984..3bc66e17 100644 --- a/doc/rtd/topics/datasources/ec2.rst +++ b/doc/rtd/topics/datasources/ec2.rst @@ -1,3 +1,5 @@ +.. _datasource_ec2: + Amazon EC2 ========== diff --git a/doc/rtd/topics/datasources/fallback.rst b/doc/rtd/topics/datasources/fallback.rst index 1eb01dd0..2b133fcd 100644 --- a/doc/rtd/topics/datasources/fallback.rst +++ b/doc/rtd/topics/datasources/fallback.rst @@ -1,3 +1,5 @@ +.. _datasource_fallback: + Fallback/None ============= diff --git a/doc/rtd/topics/datasources/maas.rst b/doc/rtd/topics/datasources/maas.rst index f495dd4b..85c853e9 100644 --- a/doc/rtd/topics/datasources/maas.rst +++ b/doc/rtd/topics/datasources/maas.rst @@ -1,3 +1,5 @@ +.. _datasource_maas: + MAAS ==== diff --git a/doc/rtd/topics/datasources/nocloud.rst b/doc/rtd/topics/datasources/nocloud.rst index b9ab5f11..0159e853 100644 --- a/doc/rtd/topics/datasources/nocloud.rst +++ b/doc/rtd/topics/datasources/nocloud.rst @@ -1,3 +1,5 @@ +.. _datasource_nocloud: + NoCloud ======= @@ -70,6 +72,43 @@ Example metadata: gateway 192.168.1.254 hostname: myhost + +Network configuration can also be provided to cloud-init in either +:ref:`network_config_v1` or :ref:`network_config_v2` by providing that +yaml formatted data in a file named ``network-config``. If found, +this file will override a ``network-interfaces`` file. + +See an example below. Note specifically that this file does not +have a top level ``network`` key as it it is already assumed to +be network configuration based on the filename. + +.. code:: yaml + + version: 1 + config: + - type: physical + name: interface0 + mac_address: "52:54:00:12:34:00" + subnets: + - type: static + address: 192.168.1.10 + netmask: 255.255.255.0 + gateway: 192.168.1.254 + + +.. code:: yaml + + version: 2 + ethernets: + interface0: + match: + mac_address: "52:54:00:12:34:00" + set-name: interface0 + addresses: + - 192.168.1.10/255.255.255.0 + gateway4: 192.168.1.254 + + .. _iso9660: https://en.wikipedia.org/wiki/ISO_9660 .. _vfat: https://en.wikipedia.org/wiki/File_Allocation_Table .. vi: textwidth=78 diff --git a/doc/rtd/topics/datasources/opennebula.rst b/doc/rtd/topics/datasources/opennebula.rst index 1b90a9c7..7c0367c4 100644 --- a/doc/rtd/topics/datasources/opennebula.rst +++ b/doc/rtd/topics/datasources/opennebula.rst @@ -1,3 +1,5 @@ +.. _datasource_opennebula: + OpenNebula ========== diff --git a/doc/rtd/topics/datasources/openstack.rst b/doc/rtd/topics/datasources/openstack.rst index 164b0e0c..607b70f3 100644 --- a/doc/rtd/topics/datasources/openstack.rst +++ b/doc/rtd/topics/datasources/openstack.rst @@ -1,3 +1,5 @@ +.. _datasource_openstack: + OpenStack ========= diff --git a/doc/rtd/topics/datasources/ovf.rst b/doc/rtd/topics/datasources/ovf.rst index a0770332..c312617f 100644 --- a/doc/rtd/topics/datasources/ovf.rst +++ b/doc/rtd/topics/datasources/ovf.rst @@ -1,3 +1,5 @@ +.. _datasource_ovf: + OVF === diff --git a/doc/rtd/topics/datasources/smartos.rst b/doc/rtd/topics/datasources/smartos.rst index a1e1542b..cb9a128e 100644 --- a/doc/rtd/topics/datasources/smartos.rst +++ b/doc/rtd/topics/datasources/smartos.rst @@ -1,3 +1,5 @@ +.. _datasource_smartos: + SmartOS Datasource ================== diff --git a/doc/rtd/topics/network-config-format-eni.rst b/doc/rtd/topics/network-config-format-eni.rst new file mode 100644 index 00000000..b0904952 --- /dev/null +++ b/doc/rtd/topics/network-config-format-eni.rst @@ -0,0 +1,20 @@ +.. _network_config_eni: + +Network Configuration ENI (Legacy) +---------------------------------- + +`Cloud-init`_ supports reading and writing network config in the ``ENI`` +format which is consumed by the ``ifupdown`` tool to parse and apply network +configuration. + +As an input format this is **legacy**. In cases where ENI format is available +and another format is also available, it will prefer to use the other format. +This can happen in either :ref:`datasource_nocloud` or +:ref:`datasource_openstack` datasources. + +Please reference existing `documentation`_ for the +``/etc/network/interfaces(5)`` format. + +.. _Cloud-init: https://launchpad.net/cloud-init +.. _documentation: http://manpages.ubuntu.com/manpages/trusty/en/man5/interfaces.5.html +.. vi: textwidth=78 diff --git a/doc/rtd/topics/network-config-format-v1.rst b/doc/rtd/topics/network-config-format-v1.rst new file mode 100644 index 00000000..36326b59 --- /dev/null +++ b/doc/rtd/topics/network-config-format-v1.rst @@ -0,0 +1,563 @@ +.. _network_config_v1: + +Networking Config Version 1 +=========================== + +This network configuration format lets users customize their instance's +networking interfaces by assigning subnet configuration, virtual device +creation (bonds, bridges, vlans) routes and DNS configuration. + +Required elements of a Network Config Version 1 are ``config`` and +``version``. + +Cloud-init will read this format from system config. +For example the following could be present in +``/etc/cloud/cloud.cfg.d/custom-networking.cfg``: + +.. code-block:: yaml + + network: + version: 1 + config: + - type: physical + name: eth0 + subnets: + - type: dhcp + +The :ref:`datasource_nocloud` datasource can also provide cloud-init +networking configuration in this Format. + +Configuration Types +------------------- +Within the network ``config`` portion, users include a list of configuration +types. The current list of support ``type`` values are as follows: + +- Physical (``physical``) +- Bond (``bond``) +- Bridge (``bridge``) +- VLAN (``vlan``) +- Nameserver (``nameserver``) +- Route (``route``) + +Physical, Bond, Bridge and VLAN types may also include IP configuration under +the key ``subnets``. + +- Subnet/IP (``subnets``) + + +Physical +~~~~~~~~ +The ``physical`` type configuration represents a "physical" network device, +typically Ethernet-based. At least one of of these entries is required for +external network connectivity. Type ``physical`` requires only one key: +``name``. A ``physical`` device may contain some or all of the following +keys: + +**name**: ** + +A devices name must be less than 15 characters. Names exceeding the maximum +will be truncated. This is a limitation of the Linux kernel network-device +structure. + +**mac_address**: ** + +The MAC Address is a device unique identifier that most Ethernet-based network +devices possess. Specifying a MAC Address is optional. + + +.. note:: + + Cloud-init will handle the persistent mapping between a + device's ``name`` and the ``mac_address``. + +**mtu**: ** + +The MTU key represents a device's Maximum Transmission Unit, the largest size +packet or frame, specified in octets (eight-bit bytes), that can be sent in a +packet- or frame-based network. Specifying ``mtu`` is optional. + +.. note:: + + The possible supported values of a device's MTU is not available at + configuration time. It's possible to specify a value too large or to + small for a device and may be ignored by the device. + + +**Physical Example**:: + + network: + version: 1 + config: + # Simple network adapter + - type: physical + name: interface0 + mac_address: 00:11:22:33:44:55 + # Second nic with Jumbo frames + - type: physical + name: jumbo0 + mac_address: aa:11:22:33:44:55 + mtu: 9000 + # 10G pair + - type: physical + name: gbe0 + mac_address: cd:11:22:33:44:00 + - type: physical + name: gbe1 + mac_address: cd:11:22:33:44:02 + +Bond +~~~~ +A ``bond`` type will configure a Linux software Bond with one or more network +devices. A ``bond`` type requires the following keys: + +**name**: ** + +A devices name must be less than 15 characters. Names exceeding the maximum +will be truncated. This is a limitation of the Linux kernel network-device +structure. + +**mac_address**: ** + +When specifying MAC Address on a bond this value will be assigned to the bond +device and may be different than the MAC address of any of the underlying +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. + + +**bond_interfaces**: ** + +The ``bond_interfaces`` key accepts a list of network device ``name`` values +from the configuration. This list may be empty. + +**params**: ** + +The ``params`` key in a bond holds a dictionary of bonding parameters. +This dictionary may be empty. For more details on what the various bonding +parameters mean please read the Linux Kernel Bonding.txt. + +Valid ``params`` keys are: + + - ``active_slave``: Set bond attribute + - ``ad_actor_key``: Set bond attribute + - ``ad_actor_sys_prio``: Set bond attribute + - ``ad_actor_system``: Set bond attribute + - ``ad_aggregator``: Set bond attribute + - ``ad_num_ports``: Set bond attribute + - ``ad_partner_key``: Set bond attribute + - ``ad_partner_mac``: Set bond attribute + - ``ad_select``: Set bond attribute + - ``ad_user_port_key``: Set bond attribute + - ``all_slaves_active``: Set bond attribute + - ``arp_all_targets``: Set bond attribute + - ``arp_interval``: Set bond attribute + - ``arp_ip_target``: Set bond attribute + - ``arp_validate``: Set bond attribute + - ``downdelay``: Set bond attribute + - ``fail_over_mac``: Set bond attribute + - ``lacp_rate``: Set bond attribute + - ``lp_interval``: Set bond attribute + - ``miimon``: Set bond attribute + - ``mii_status``: Set bond attribute + - ``min_links``: Set bond attribute + - ``mode``: Set bond attribute + - ``num_grat_arp``: Set bond attribute + - ``num_unsol_na``: Set bond attribute + - ``packets_per_slave``: Set bond attribute + - ``primary``: Set bond attribute + - ``primary_reselect``: Set bond attribute + - ``queue_id``: Set bond attribute + - ``resend_igmp``: Set bond attribute + - ``slaves``: Set bond attribute + - ``tlb_dynamic_lb``: Set bond attribute + - ``updelay``: Set bond attribute + - ``use_carrier``: Set bond attribute + - ``xmit_hash_policy``: Set bond attribute + +**Bond Example**:: + + network: + version: 1 + config: + # Simple network adapter + - type: physical + name: interface0 + mac_address: 00:11:22:33:44:55 + # 10G pair + - type: physical + name: gbe0 + mac_address: cd:11:22:33:44:00 + - type: physical + name: gbe1 + mac_address: cd:11:22:33:44:02 + - type: bond + name: bond0 + bond_interfaces: + - gbe0 + - gbe1 + params: + bond-mode: active-backup + +Bridge +~~~~~~ +Type ``bridge`` requires the following keys: + +- ``name``: Set the name of the bridge. +- ``bridge_interfaces``: Specify the ports of a bridge via their ``name``. + This list may be empty. +- ``params``: A list of bridge params. For more details, please read the + bridge-utils-interfaces manpage. + +Valid keys are: + + - ``bridge_ageing``: Set the bridge's ageing value. + - ``bridge_bridgeprio``: Set the bridge device network priority. + - ``bridge_fd``: Set the bridge's forward delay. + - ``bridge_hello``: Set the bridge's hello value. + - ``bridge_hw``: Set the bridge's MAC address. + - ``bridge_maxage``: Set the bridge's maxage value. + - ``bridge_maxwait``: Set how long network scripts should wait for the + bridge to be up. + - ``bridge_pathcost``: Set the cost of a specific port on the bridge. + - ``bridge_portprio``: Set the priority of a specific port on the bridge. + - ``bridge_ports``: List of devices that are part of the bridge. + - ``bridge_stp``: Set spanning tree protocol on or off. + - ``bridge_waitport``: Set amount of time in seconds to wait on specific + ports to become available. + + +**Bridge Example**:: + + network: + version: 1 + config: + # Simple network adapter + - type: physical + name: interface0 + mac_address: 00:11:22:33:44:55 + # Second nic with Jumbo frames + - type: physical + name: jumbo0 + mac_address: aa:11:22:33:44:55 + mtu: 9000 + - type: bridge + name: br0 + bridge_interfaces: + - jumbo0 + params: + bridge_ageing: 250 + bridge_bridgeprio: 22 + bridge_fd: 1 + bridge_hello: 1 + bridge_maxage: 10 + bridge_maxwait: 0 + bridge_pathcost: + - jumbo0 75 + bridge_pathprio: + - jumbo0 28 + bridge_stp: 'off' + bridge_maxwait: + - jumbo0 0 + + +VLAN +~~~~ +Type ``vlan`` requires the following keys: + +- ``name``: Set the name of the VLAN +- ``vlan_link``: Specify the underlying link via its ``name``. +- ``vlan_id``: Specify the VLAN numeric id. + +**VLAN Example**:: + + network: + version: 1 + config: + # Physical interfaces. + - type: physical + name: eth0 + mac_address: "c0:d6:9f:2c:e8:80" + # VLAN interface. + - type: vlan + name: eth0.101 + vlan_link: eth0 + vlan_id: 101 + mtu: 1500 + +Nameserver +~~~~~~~~~~ + +Users can specify a ``nameserver`` type. Nameserver dictionaries include +the following keys: + +- ``address``: List of IPv4 or IPv6 address of nameservers. +- ``search``: List of of hostnames to include in the resolv.conf search path. + +**Nameserver Example**:: + + network: + version: 1 + config: + - type: physical + name: interface0 + mac_address: 00:11:22:33:44:55 + subnets: + - type: static + address: 192.168.23.14/27 + gateway: 192.168.23.1 + - type: nameserver: + address: + - 192.168.23.2 + - 8.8.8.8 + search: + - exemplary + + + +Route +~~~~~ + +Users can include static routing information as well. A ``route`` dictionary +has the following keys: + +- ``destination``: IPv4 network address with CIDR netmask notation. +- ``gateway``: IPv4 gateway address with CIDR netmask notation. +- ``metric``: Integer which sets the network metric value for this route. + +**Route Example**:: + + network: + version: 1 + config: + - type: physical + name: interface0 + mac_address: 00:11:22:33:44:55 + subnets: + - type: static + address: 192.168.23.14/24 + gateway: 192.168.23.1 + - type: route + destination: 192.168.24.0/24 + gateway: 192.168.24.1 + metric: 3 + +Subnet/IP +~~~~~~~~~ + +For any network device (one of the Config Types) users can define a list of +``subnets`` which contain ip configuration dictionaries. Multiple subnet +entries will create interface alias allowing a single interface to use +different ip configurations. + +Valid keys for for ``subnets`` include the following: + +- ``type``: Specify the subnet type. +- ``control``: Specify manual, auto or hotplug. Indicates how the interface + will be handled during boot. +- ``address``: IPv4 or IPv6 address. It may include CIDR netmask notation. +- ``netmask``: IPv4 subnet mask in dotted format or CIDR notation. +- ``gateway``: IPv4 address of the default gateway for this subnet. +- ``dns_nameserver``: Specify a list of IPv4 dns server IPs to end up in + resolv.conf. +- ``dns_search``: Specify a list of search paths to be included in + resolv.conf. +- ``routes``: Specify a list of routes for a given interface + + +Subnet types are one of the following: + +- ``dhcp4``: Configure this interface with IPv4 dhcp. +- ``dhcp``: Alias for ``dhcp4`` +- ``dhcp6``: Configure this interface with IPv6 dhcp. +- ``static``: Configure this interface with a static IPv4. +- ``static6``: Configure this interface with a static IPv6 . + +When making use of ``dhcp`` types, no additional configuration is needed in +the subnet dictionary. + + +**Subnet DHCP Example**:: + + network: + version: 1 + config: + - type: physical + name: interface0 + mac_address: 00:11:22:33:44:55 + subnets: + - type: dhcp + + +**Subnet Static Example**:: + + network: + version: 1 + config: + - type: physical + name: interface0 + mac_address: 00:11:22:33:44:55 + subnets: + - type: static + address: 192.168.23.14/27 + gateway: 192.168.23.1 + dns_nameservers: + - 192.168.23.2 + - 8.8.8.8 + dns_search: + - exemplary.maas + +The following will result in an ``interface0`` using DHCP and ``interface0:1`` +using the static subnet configuration. + +**Multiple subnet Example**:: + + network: + version: 1 + config: + - type: physical + name: interface0 + mac_address: 00:11:22:33:44:55 + subnets: + - type: dhcp + - type: static + address: 192.168.23.14/27 + gateway: 192.168.23.1 + dns_nameservers: + - 192.168.23.2 + - 8.8.8.8 + dns_search: + - exemplary + +**Subnet with routes Example**:: + + network: + version: 1 + config: + - type: physical + name: interface0 + mac_address: 00:11:22:33:44:55 + subnets: + - type: dhcp + - type: static + address: 10.184.225.122 + netmask: 255.255.255.252 + routes: + - gateway: 10.184.225.121 + netmask: 255.240.0.0 + network: 10.176.0.0 + - gateway: 10.184.225.121 + netmask: 255.240.0.0 + network: 10.208.0.0 + + +Multi-layered configurations +---------------------------- + +Complex networking sometimes uses layers of configuration. The syntax allows +users to build those layers one at a time. All of the virtual network devices +supported allow specifying an underlying device by their ``name`` value. + +**Bonded VLAN Example**:: + + network: + version: 1 + config: + # 10G pair + - type: physical + name: gbe0 + mac_address: cd:11:22:33:44:00 + - type: physical + name: gbe1 + mac_address: cd:11:22:33:44:02 + # Bond. + - type: bond + name: bond0 + bond_interfaces: + - gbe0 + - gbe1 + params: + bond-mode: 802.3ad + bond-lacp-rate: fast + # A Bond VLAN. + - type: vlan + name: bond0.200 + vlan_link: bond0 + vlan_id: 200 + subnets: + - type: dhcp4 + +More Examples +------------- +Some more examples to explore the various options available. + +**Multiple VLAN example**:: + + network: + version: 1 + config: + - id: eth0 + mac_address: d4:be:d9:a8:49:13 + mtu: 1500 + name: eth0 + subnets: + - address: 10.245.168.16/21 + dns_nameservers: + - 10.245.168.2 + gateway: 10.245.168.1 + type: static + type: physical + - id: eth1 + mac_address: d4:be:d9:a8:49:15 + mtu: 1500 + name: eth1 + subnets: + - address: 10.245.188.2/24 + dns_nameservers: [] + type: static + type: physical + - id: eth1.2667 + mtu: 1500 + name: eth1.2667 + subnets: + - address: 10.245.184.2/24 + dns_nameservers: [] + type: static + type: vlan + vlan_id: 2667 + vlan_link: eth1 + - id: eth1.2668 + mtu: 1500 + name: eth1.2668 + subnets: + - address: 10.245.185.1/24 + dns_nameservers: [] + type: static + type: vlan + vlan_id: 2668 + vlan_link: eth1 + - id: eth1.2669 + mtu: 1500 + name: eth1.2669 + subnets: + - address: 10.245.186.1/24 + dns_nameservers: [] + type: static + type: vlan + vlan_id: 2669 + vlan_link: eth1 + - id: eth1.2670 + mtu: 1500 + name: eth1.2670 + subnets: + - address: 10.245.187.2/24 + dns_nameservers: [] + type: static + type: vlan + vlan_id: 2670 + vlan_link: eth1 + - address: 10.245.168.2 + search: + - dellstack + type: nameserver + +.. vi: textwidth=78 diff --git a/doc/rtd/topics/network-config-format-v2.rst b/doc/rtd/topics/network-config-format-v2.rst new file mode 100644 index 00000000..335d236a --- /dev/null +++ b/doc/rtd/topics/network-config-format-v2.rst @@ -0,0 +1,503 @@ +.. _network_config_v2: + +Networking Config Version 2 +=========================== + +Cloud-init's support for Version 2 network config is a subset of the +version 2 format defined for the `netplan`_ tool. Cloud-init supports +both reading and writing of Version 2; the latter support requires a +distro with `netplan`_ present. + +The ``network`` key has at least two required elements. First +it must include ``version: 2`` and one or more of possible device +``types``.. + +Cloud-init will read this format from system config. +For example the following could be present in +``/etc/cloud/cloud.cfg.d/custom-networking.cfg``: + + network: + version: 2 + ethernets: [] + +It may also be provided in other locations including the +:ref:`datasource_nocloud`, see :ref:`default_behavior` for other places. + +Supported device ``types`` values are as follows: + +- Ethernets (``ethernets``) +- Bonds (``bonds``) +- Bridges (``bridges``) +- VLANs (``vlans``) + +Each type block contains device definitions as a map where the keys (called +"configuration IDs"). Each entry under the ``types`` may include IP and/or +device configuration. + +Cloud-init does not current support ``wifis`` type that is present in native +`netplan`_. + + +Device configuration IDs +------------------------ + +The key names below the per-device-type definition maps (like ``ethernets:``) +are called "ID"s. They must be unique throughout the entire set of +configuration files. Their primary purpose is to serve as anchor names for +composite devices, for example to enumerate the members of a bridge that is +currently being defined. + +There are two physically/structurally different classes of device definitions, +and the ID field has a different interpretation for each: + +Physical devices + +: (Examples: ethernet, wifi) These can dynamically come and go between + reboots and even during runtime (hotplugging). In the generic case, they + can be selected by ``match:`` rules on desired properties, such as name/name + pattern, MAC address, driver, or device paths. In general these will match + any number of devices (unless they refer to properties which are unique + such as the full path or MAC address), so without further knowledge about + the hardware these will always be considered as a group. + + It is valid to specify no match rules at all, in which case the ID field is + simply the interface name to be matched. This is mostly useful if you want + to keep simple cases simple, and it's how network device configuration has + been done for a long time. + + If there are ``match``: rules, then the ID field is a purely opaque name + which is only being used for references from definitions of compound + devices in the config. + +Virtual devices + +: (Examples: veth, bridge, bond) These are fully under the control of the + config file(s) and the network stack. I. e. these devices are being created + instead of matched. Thus ``match:`` and ``set-name:`` are not applicable for + these, and the ID field is the name of the created virtual device. + +Common properties for physical device types +------------------------------------------- + +**match**: *<(mapping)>* + +This selects a subset of available physical devices by various hardware +properties. The following configuration will then apply to all matching +devices, as soon as they appear. *All* specified properties must match. +The following properties for creating matches are supported: + +**name**: *<(scalar)>* + +Current interface name. Globs are supported, and the primary use case +for matching on names, as selecting one fixed name can be more easily +achieved with having no ``match:`` at all and just using the ID (see +above). Note that currently only networkd supports globbing, +NetworkManager does not. + +**macaddress**: *<(scalar)>* + +Device's MAC address in the form "XX:XX:XX:XX:XX:XX". Globs are not allowed. + +**driver**: *<(scalar)>* + +Kernel driver name, corresponding to the ``DRIVER`` udev property. Globs are +supported. Matching on driver is *only* supported with networkd. + +**Examples**:: + + # all cards on second PCI bus + match: + name: enp2* + + # fixed MAC address + match: + macaddress: 11:22:33:AA:BB:FF + + # first card of driver ``ixgbe`` + match: + driver: ixgbe + name: en*s0 + +**set-name**: *<(scalar)>* + +When matching on unique properties such as path or MAC, or with additional +assumptions such as "there will only ever be one wifi device", +match rules can be written so that they only match one device. Then this +property can be used to give that device a more specific/desirable/nicer +name than the default from udev’s ifnames. Any additional device that +satisfies the match rules will then fail to get renamed and keep the +original kernel name (and dmesg will show an error). + +**wakeonlan**: *<(bool)>* + +Enable wake on LAN. Off by default. + + +Common properties for all device types +-------------------------------------- + +**renderer**: *<(scalar)>* + +Use the given networking backend for this definition. Currently supported are +``networkd`` and ``NetworkManager``. This property can be specified globally +in ``networks:``, for a device type (in e. g. ``ethernets:``) or +for a particular device definition. Default is ``networkd``. + +.. note:: + + Cloud-init only supports networkd backend if rendering version2 config + to the instance. + +**dhcp4**: *<(bool)>* + +Enable DHCP for IPv4. Off by default. + +**dhcp6**: *<(bool)>* + +Enable DHCP for IPv6. Off by default. + +**addresses**: *<(sequence of scalars)>* + +Add static addresses to the interface in addition to the ones received +through DHCP or RA. Each sequence entry is in CIDR notation, i. e. of the +form ``addr/prefixlen`` . ``addr`` is an IPv4 or IPv6 address as recognized +by ``inet_pton``(3) and ``prefixlen`` the number of bits of the subnet. + +Example: ``addresses: [192.168.14.2/24, 2001:1::1/64]`` + +**gateway4**: or **gateway6**: *<(scalar)>* + +Set default gateway for IPv4/6, for manual address configuration. This +requires setting ``addresses`` too. Gateway IPs must be in a form +recognized by ``inet_pton(3)`` + +Example for IPv4: ``gateway4: 172.16.0.1`` +Example for IPv6: ``gateway6: 2001:4::1`` + +**nameservers**: *<(mapping)>* + +Set DNS servers and search domains, for manual address configuration. There +are two supported fields: ``addresses:`` is a list of IPv4 or IPv6 addresses +similar to ``gateway*``, and ``search:`` is a list of search domains. + +Example: :: + + nameservers: + search: [lab, home] + addresses: [8.8.8.8, FEDC::1] + +**routes**: *<(sequence of mapping)>* + +Add device specific routes. Each mapping includes a ``to``, ``via`` key +with an IPv4 or IPv6 address as value. ``metric`` is an optional value. + +Example: :: + + routes: + - to: 0.0.0.0/0 + via: 10.23.2.1 + metric: 3 + +Ethernets +~~~~~~~~~ +Ethernet device definitions do not support any specific properties beyond the +common ones described above. + +Bonds +~~~~~ + +**interfaces** *<(sequence of scalars)>* + +All devices matching this ID list will be added to the bond. + +Example: :: + + ethernets: + switchports: + match: {name: "enp2*"} + [...] + bonds: + bond0: + interfaces: [switchports] + +**parameters**: *<(mapping)>* + +Customization parameters for special bonding options. Time values are specified +in seconds unless otherwise specified. + +**mode**: *<(scalar)>* + +Set the bonding mode used for the interfaces. The default is +``balance-rr`` (round robin). Possible values are ``balance-rr``, +``active-backup``, ``balance-xor``, ``broadcast``, ``802.3ad``, +``balance-tlb``, and ``balance-alb``. + +**lacp-rate**: *<(scalar)>* + +Set the rate at which LACPDUs are transmitted. This is only useful +in 802.3ad mode. Possible values are ``slow`` (30 seconds, default), +and ``fast`` (every second). + +**mii-monitor-interval**: *<(scalar)>* + +Specifies the interval for MII monitoring (verifying if an interface +of the bond has carrier). The default is ``0``; which disables MII +monitoring. + +**min-links**: *<(scalar)>* + +The minimum number of links up in a bond to consider the bond +interface to be up. + +**transmit-hash-policy**: <*(scalar)>* + +Specifies the transmit hash policy for the selection of slaves. This +is only useful in balance-xor, 802.3ad and balance-tlb modes. +Possible values are ``layer2``, ``layer3+4``, ``layer2+3``, +``encap2+3``, and ``encap3+4``. + +**ad-select**: <*(scalar)>* + +Set the aggregation selection mode. Possible values are ``stable``, +``bandwidth``, and ``count``. This option is only used in 802.3ad mode. + +**all-slaves-active**: <*(bool)>* + +If the bond should drop duplicate frames received on inactive ports, +set this option to ``false``. If they should be delivered, set this +option to ``true``. The default value is false, and is the desirable +behavior in most situations. + +**arp-interval**: <*(scalar)>* + +Set the interval value for how frequently ARP link monitoring should +happen. The default value is ``0``, which disables ARP monitoring. + +**arp-ip-targets**: <*(sequence of scalars)>* + +IPs of other hosts on the link which should be sent ARP requests in +order to validate that a slave is up. This option is only used when +``arp-interval`` is set to a value other than ``0``. At least one IP +address must be given for ARP link monitoring to function. Only IPv4 +addresses are supported. You can specify up to 16 IP addresses. The +default value is an empty list. + +**arp-validate**: <*(scalar)>* + +Configure how ARP replies are to be validated when using ARP link +monitoring. Possible values are ``none``, ``active``, ``backup``, +and ``all``. + +**arp-all-targets**: <*(scalar)>* + +Specify whether to use any ARP IP target being up as sufficient for +a slave to be considered up; or if all the targets must be up. This +is only used for ``active-backup`` mode when ``arp-validate`` is +enabled. Possible values are ``any`` and ``all``. + +**up-delay**: <*(scalar)>* + +Specify the delay before enabling a link once the link is physically +up. The default value is ``0``. + +**down-delay**: <*(scalar)>* + +Specify the delay before disabling a link once the link has been +lost. The default value is ``0``. + +**fail-over-mac-policy**: <*(scalar)>* + +Set whether to set all slaves to the same MAC address when adding +them to the bond, or how else the system should handle MAC addresses. +The possible values are ``none``, ``active``, and ``follow``. + +**gratuitious-arp**: <*(scalar)>* + +Specify how many ARP packets to send after failover. Once a link is +up on a new slave, a notification is sent and possibly repeated if +this value is set to a number greater than ``1``. The default value +is ``1`` and valid values are between ``1`` and ``255``. This only +affects ``active-backup`` mode. + +**packets-per-slave**: <*(scalar)>* + +In ``balance-rr`` mode, specifies the number of packets to transmit +on a slave before switching to the next. When this value is set to +``0``, slaves are chosen at random. Allowable values are between +``0`` and ``65535``. The default value is ``1``. This setting is +only used in ``balance-rr`` mode. + +**primary-reselect-policy**: <*(scalar)>* + +Set the reselection policy for the primary slave. On failure of the +active slave, the system will use this policy to decide how the new +active slave will be chosen and how recovery will be handled. The +possible values are ``always``, ``better``, and ``failure``. + +**learn-packet-interval**: <*(scalar)>* + +Specify the interval between sending learning packets to each slave. +The value range is between ``1`` and ``0x7fffffff``. The default +value is ``1``. This option only affects ``balance-tlb`` and +``balance-alb`` modes. + + +Bridges +~~~~~~~ + +**interfaces**: <*(sequence of scalars)>* + +All devices matching this ID list will be added to the bridge. + +Example: :: + + ethernets: + switchports: + match: {name: "enp2*"} + [...] + bridges: + br0: + interfaces: [switchports] + +**parameters**: <*(mapping)>* + +Customization parameters for special bridging options. Time values are specified +in seconds unless otherwise specified. + +**ageing-time**: <*(scalar)>* + +Set the period of time to keep a MAC address in the forwarding +database after a packet is received. + +**priority**: <*(scalar)>* + +Set the priority value for the bridge. This value should be an +number between ``0`` and ``65535``. Lower values mean higher +priority. The bridge with the higher priority will be elected as +the root bridge. + +**forward-delay**: <*(scalar)>* + +Specify the period of time the bridge will remain in Listening and +Learning states before getting to the Forwarding state. This value +should be set in seconds for the systemd backend, and in milliseconds +for the NetworkManager backend. + +**hello-time**: <*(scalar)>* + +Specify the interval between two hello packets being sent out from +the root and designated bridges. Hello packets communicate +information about the network topology. + +**max-age**: <*(scalar)>* + +Set the maximum age of a hello packet. If the last hello packet is +older than that value, the bridge will attempt to become the root +bridge. + +**path-cost**: <*(scalar)>* + +Set the cost of a path on the bridge. Faster interfaces should have +a lower cost. This allows a finer control on the network topology +so that the fastest paths are available whenever possible. + +**stp**: <*(bool)>* + +Define whether the bridge should use Spanning Tree Protocol. The +default value is "true", which means that Spanning Tree should be +used. + + +VLANs +~~~~~ + +**id**: <*(scalar)>* + +VLAN ID, a number between 0 and 4094. + +**link**: <*(scalar)>* + +ID of the underlying device definition on which this VLAN gets +created. + +Example: :: + + ethernets: + eno1: {...} + vlans: + en-intra: + id: 1 + link: eno1 + dhcp4: yes + en-vpn: + id: 2 + link: eno1 + address: ... + + +Examples +-------- +Configure an ethernet device with networkd, identified by its name, and enable +DHCP: :: + + network: + version: 2 + ethernets: + eno1: + dhcp4: true + +This is a complex example which shows most available features: :: + + network: + version: 2 + ethernets: + # opaque ID for physical interfaces, only referred to by other stanzas + id0: + match: + macaddress: 00:11:22:33:44:55 + wakeonlan: true + dhcp4: true + addresses: + - 192.168.14.2/24 + - 2001:1::1/64 + gateway4: 192.168.14.1 + gateway6: 2001:1::2 + nameservers: + search: [foo.local, bar.local] + addresses: [8.8.8.8] + lom: + match: + driver: ixgbe + # you are responsible for setting tight enough match rules + # that only match one device if you use set-name + set-name: lom1 + dhcp6: true + switchports: + # all cards on second PCI bus; unconfigured by themselves, will be added + # to br0 below + match: + name: enp2* + mtu: 1280 + bonds: + bond0: + interfaces: [id0, lom] + bridges: + # the key name is the name for virtual (created) interfaces; no match: and + # set-name: allowed + br0: + # IDs of the components; switchports expands into multiple interfaces + interfaces: [wlp1s0, switchports] + dhcp4: true + vlans: + en-intra: + id: 1 + link: id0 + dhcp4: yes + # static routes + routes: + - to: 0.0.0.0/0 + via: 11.0.0.1 + metric: 3 + +.. _netplan: https://launchpad.net/netplan +.. vi: textwidth=78 diff --git a/doc/rtd/topics/network-config.rst b/doc/rtd/topics/network-config.rst new file mode 100644 index 00000000..109c86f5 --- /dev/null +++ b/doc/rtd/topics/network-config.rst @@ -0,0 +1,254 @@ +********************* +Network Configuration +********************* + +- Default Behavior +- Disabling Network Configuration +- Fallback Networking +- Network Configuration Sources +- Network Configuration Outputs +- Network Output Policy +- Network Configuration Tools +- Examples + +.. _default_behavior: + +Default Behavior +================ + +`Cloud-init`_ 's searches for network configuration in order of increasing +precedence; each item overriding the previous. + +**Datasource** + +For example, OpenStack may provide network config in the MetaData Service. + +**System Config** + +A ``network:`` entry in /etc/cloud/cloud.cfg.d/* configuration files. + +**Kernel Command Line** + +``ip=`` or ``network-config=`` + +User-data cannot change an instance's network configuration. In the absense +of network configuration in any of the above sources , `Cloud-init`_ will +write out a network configuration that will issue a DHCP request on a "first" +network interface. + + +Disabling Network Configuration +=============================== + +Users may disable `Cloud-init`_ 's network configuration capability and rely +on other methods, such as embedded configuration or other customizations. + +`Cloud-init`_ supports the following methods for disabling cloud-init. + + +**Kernel Command Line** + +`Cloud-init`_ will check for a parameter ``network-config`` and the +value is expected to be YAML string in the :ref:`network_config_v1` format. +The YAML string may optionally be ``Base64`` encoded, and optionally +compressed with ``gzip``. + +Example disabling kernel command line entry: :: + + network-config={config: disabled} + + +**cloud config** + +In the combined cloud-init configuration dictionary. :: + + network: + config: disabled + +If `Cloud-init`_ 's networking config has not been disabled, and +no other network information is found, then it will proceed +to generate a fallback networking configuration. + + +Fallback Network Configuration +============================== + +`Cloud-init`_ will attempt to determine which of any attached network devices +is most likely to have a connection and then generate a network +configuration to issue a DHCP request on that interface. + +`Cloud-init`_ runs during early boot and does not expect composed network +devices (such as Bridges) to be available. `Cloud-init`_ does not consider +the following interface devices as likely 'first' network interfaces for +fallback configuration; they are filtered out from being selected. + +- **loopback**: ``name=lo`` +- **Virtual Ethernet**: ``name=veth*`` +- **Software Bridges**: ``type=bridge`` +- **Software VLANs**: ``type=vlan`` + + +`Cloud-init`_ will prefer network interfaces that indicate they are connected +via the Linux ``carrier`` flag being set. If no interfaces are marked +connected, then all unfiltered interfaces are potential connections. + +Of the potential interfaces, `Cloud-init`_ will attempt to pick the "right" +interface given the information it has available. + +Finally after selecting the "right" interface, a configuration is +generated and applied to the system. + + +Network Configuration Sources +============================= + +`Cloud-init`_ accepts a number of different network configuration formats in +support of different cloud substrates. The Datasource for these clouds in +`Cloud-init`_ will detect and consume Datasource-specific network +configuration formats for use when writing an instance's network +configuration. + +The following Datasources optionally provide network configuration: + +- :ref:`datasource_config_drive` + + - `OpenStack Metadata Service Network`_ + - :ref:`network_config_eni` + +- :ref:`datasource_digital_ocean` + + - `DigitalOcean JSON metadata`_ + +- :ref:`datasource_nocloud` + + - :ref:`network_config_v1` + - :ref:`network_config_v2` + - :ref:`network_config_eni` + +- :ref:`datasource_opennebula` + + - :ref:`network_config_eni` + +- :ref:`datasource_openstack` + + - :ref:`network_config_eni` + - `OpenStack Metadata Service Network`_ + +- :ref:`datasource_smartos` + + - `SmartOS JSON Metadata`_ + +For more information on network configuration formats + +.. toctree:: + :maxdepth: 1 + + network-config-format-eni.rst + network-config-format-v1.rst + network-config-format-v2.rst + + +Network Configuration Outputs +============================= + +`Cloud-init`_ converts various forms of user supplied or automatically +generated configuration into an internal network configuration state. From +this state `Cloud-init`_ delegates rendering of the configuration to Distro +supported formats. The following ``renderers`` are supported in cloud-init: + +- **ENI** + +/etc/network/interfaces or ``ENI`` is supported by the ``ifupdown`` package +found in Ubuntu and Debian. + +- **Netplan** + +Since Ubuntu 16.10, codename Yakkety, the ``netplan`` project has been an +optional network configuration tool which consumes :ref:`network_config_v2` +input and renders network configuration for supported backends such as +``systemd-networkd`` and ``NetworkManager``. + +- **Sysconfig** + +Sysconfig format is used by RHEL, CentOS, Fedora and other derivatives. + + +Network Output Policy +===================== + +The default policy for selecting a network ``renderer`` in order of preference +is as follows: + +- ENI +- Sysconfig +- Netplan + +When applying the policy, `Cloud-init`_ checks if the current instance has the +correct binaries and paths to support the renderer. The first renderer that +can be used is selected. Users may override the network renderer policy by +supplying an updated configuration in cloud-config. :: + + system_info: + network: + renderers: ['netplan', 'eni', 'sysconfig'] + + +Network Configuration Tools +=========================== + +`Cloud-init`_ contains one tool used to test input/output conversion between +formats. The ``tools/net-convert.py`` in the `Cloud-init`_ source repository +is helpful for examining expected output for a given input format. + +CLI Interface : + +.. code-block:: bash + + % tools/net-convert.py --help + usage: net-convert.py [-h] --network-data PATH --kind + {eni,network_data.json,yaml} -d PATH [-m name,mac] + --output-kind {eni,netplan,sysconfig} + + optional arguments: + -h, --help show this help message and exit + --network-data PATH, -p PATH + --kind {eni,network_data.json,yaml}, -k {eni,network_data.json,yaml} + -d PATH, --directory PATH + directory to place output in + -m name,mac, --mac name,mac + interface name to mac mapping + --output-kind {eni,netplan,sysconfig}, -ok {eni,netplan,sysconfig} + + +Example output convertion V2 to sysconfig: + +.. code-block:: bash + + % tools/net-convert.py --network-data v2.yaml --kind yaml \ + --output-kind sysconfig -d target + % cat target/etc/sysconfig/network-scripts/ifcfg-eth* + # Created by cloud-init on instance boot automatically, do not edit. + # + BOOTPROTO=static + DEVICE=eth7 + IPADDR=192.168.1.5/255.255.255.0 + NM_CONTROLLED=no + ONBOOT=yes + TYPE=Ethernet + USERCTL=no + # Created by cloud-init on instance boot automatically, do not edit. + # + BOOTPROTO=dhcp + DEVICE=eth9 + NM_CONTROLLED=no + ONBOOT=yes + TYPE=Ethernet + USERCTL=no + + +.. _Cloud-init: https://launchpad.net/cloud-init +.. _DigitalOcean JSON metadata: https://developers.digitalocean.com/documentation/metadata/#network-interfaces-index +.. _OpenStack Metadata Service Network: https://specs.openstack.org/openstack/nova-specs/specs/liberty/implemented/metadata-service-network-info.html +.. _SmartOS JSON Metadata: https://eng.joyent.com/mdata/datadict.html + +.. vi: textwidth=78 -- cgit v1.2.3 From 4f0f171c29bb9abb5cbb6f9adbe68015089aeed9 Mon Sep 17 00:00:00 2001 From: Paul Meyer Date: Tue, 2 May 2017 22:26:50 +0000 Subject: fs_setup: if cmd is specified, use shell interpretation. If 'cmd' is provided to a fs_setup entry, then cloud-init was trying to execute the rendered string as a single name, rather than splitting the string. The change here will pass the string to shell for interpretation so that it is split there. Also fix some documentation errors and warn when fs_opts or overwrite is provided along with 'cmd'. LP: #1687712 --- cloudinit/config/cc_disk_setup.py | 21 +++++++-- doc/examples/cloud-config-disk-setup.txt | 6 +-- .../test_handler/test_handler_disk_setup.py | 55 ++++++++++++++++++++++ 3 files changed, 74 insertions(+), 8 deletions(-) (limited to 'doc') diff --git a/cloudinit/config/cc_disk_setup.py b/cloudinit/config/cc_disk_setup.py index f49386e3..6f827ddc 100644 --- a/cloudinit/config/cc_disk_setup.py +++ b/cloudinit/config/cc_disk_setup.py @@ -910,12 +910,23 @@ def mkfs(fs_cfg): "must be set.", label) # Create the commands + shell = False if fs_cmd: fs_cmd = fs_cfg['cmd'] % { 'label': label, 'filesystem': fs_type, 'device': device, } + shell = True + + if overwrite: + LOG.warning( + "fs_setup:overwrite ignored because cmd was specified: %s", + fs_cmd) + if fs_opts: + LOG.warning( + "fs_setup:extra_opts ignored because cmd was specified: %s", + fs_cmd) else: # Find the mkfs command mkfs_cmd = util.which("mkfs.%s" % fs_type) @@ -936,14 +947,14 @@ def mkfs(fs_cfg): if overwrite or device_type(device) == "disk": fs_cmd.append(lookup_force_flag(fs_type)) - # Add the extends FS options - if fs_opts: - fs_cmd.extend(fs_opts) + # Add the extends FS options + if fs_opts: + fs_cmd.extend(fs_opts) LOG.debug("Creating file system %s on %s", label, device) - LOG.debug(" Using cmd: %s", " ".join(fs_cmd)) + LOG.debug(" Using cmd: %s", str(fs_cmd)) try: - util.subp(fs_cmd) + util.subp(fs_cmd, shell=shell) except Exception as e: raise Exception("Failed to exec of '%s':\n%s" % (fs_cmd, e)) diff --git a/doc/examples/cloud-config-disk-setup.txt b/doc/examples/cloud-config-disk-setup.txt index 3e46a22e..38ad0528 100644 --- a/doc/examples/cloud-config-disk-setup.txt +++ b/doc/examples/cloud-config-disk-setup.txt @@ -155,11 +155,11 @@ fs_setup: filesystem: 'ext3' device: 'ephemeral0' partition: 'auto' - - label: mylabl2 + - label: mylabl2 filesystem: 'ext4' device: '/dev/xvda1' - - special: - cmd: mkfs -t %(FILESYSTEM)s -L %(LABEL)s %(DEVICE)s + - cmd: mkfs -t %(filesystem)s -L %(label)s %(device)s + label: mylabl3 filesystem: 'btrfs' device: '/dev/xvdh' diff --git a/tests/unittests/test_handler/test_handler_disk_setup.py b/tests/unittests/test_handler/test_handler_disk_setup.py index 7ff39225..9f00d46a 100644 --- a/tests/unittests/test_handler/test_handler_disk_setup.py +++ b/tests/unittests/test_handler/test_handler_disk_setup.py @@ -17,6 +17,10 @@ class TestIsDiskUsed(TestCase): self.check_fs = self.patches.enter_context( mock.patch('{0}.check_fs'.format(mod_name))) + def tearDown(self): + super(TestIsDiskUsed, self).tearDown() + self.patches.close() + def test_multiple_child_nodes_returns_true(self): self.enumerate_disk.return_value = (mock.MagicMock() for _ in range(2)) self.check_fs.return_value = (mock.MagicMock(), None, mock.MagicMock()) @@ -147,4 +151,55 @@ class TestUpdateFsSetupDevices(TestCase): 'filesystem': 'xfs' }, fs_setup) + +@mock.patch('cloudinit.config.cc_disk_setup.find_device_node', + return_value=('/dev/xdb1', False)) +@mock.patch('cloudinit.config.cc_disk_setup.device_type', return_value=None) +@mock.patch('cloudinit.config.cc_disk_setup.util.subp', return_value=('', '')) +class TestMkfsCommandHandling(TestCase): + + def test_with_cmd(self, subp, *args): + """mkfs honors cmd and logs warnings when extra_opts or overwrite are + provided.""" + with self.assertLogs( + 'cloudinit.config.cc_disk_setup') as logs: + cc_disk_setup.mkfs({ + 'cmd': 'mkfs -t %(filesystem)s -L %(label)s %(device)s', + 'filesystem': 'ext4', + 'device': '/dev/xdb1', + 'label': 'with_cmd', + 'extra_opts': ['should', 'generate', 'warning'], + 'overwrite': 'should generate warning too' + }) + + self.assertIn( + 'WARNING:cloudinit.config.cc_disk_setup:fs_setup:extra_opts ' + + 'ignored because cmd was specified: mkfs -t ext4 -L with_cmd ' + + '/dev/xdb1', + logs.output) + self.assertIn( + 'WARNING:cloudinit.config.cc_disk_setup:fs_setup:overwrite ' + + 'ignored because cmd was specified: mkfs -t ext4 -L with_cmd ' + + '/dev/xdb1', + logs.output) + + subp.assert_called_once_with( + 'mkfs -t ext4 -L with_cmd /dev/xdb1', shell=True) + + def test_overwrite_and_extra_opts_without_cmd(self, subp, *args): + """mkfs observes extra_opts and overwrite settings when cmd is not + present.""" + cc_disk_setup.mkfs({ + 'filesystem': 'ext4', + 'device': '/dev/xdb1', + 'label': 'without_cmd', + 'extra_opts': ['are', 'added'], + 'overwrite': True + }) + + subp.assert_called_once_with( + ['/sbin/mkfs.ext4', '/dev/xdb1', + '-L', 'without_cmd', '-F', 'are', 'added'], + shell=False) + # vi: ts=4 expandtab -- cgit v1.2.3