diff options
author | Scott Moser <smoser@brickies.net> | 2017-04-27 12:50:12 -0400 |
---|---|---|
committer | Scott Moser <smoser@brickies.net> | 2017-04-27 12:50:12 -0400 |
commit | 8310484a880690529a4936615df596d467e51708 (patch) | |
tree | 886aeb1a6e3ca809e466ddbcacbe9741b56dafa0 /doc | |
parent | af63cf763946bca6163dc797195a3aeae975f8da (diff) | |
parent | 513e99e049eab4acea14e187f59d760adc755b40 (diff) | |
download | vyos-cloud-init-8310484a880690529a4936615df596d467e51708.tar.gz vyos-cloud-init-8310484a880690529a4936615df596d467e51708.zip |
merge from 513e99e049ea at 0.7.9-113-g513e99e0
Diffstat (limited to 'doc')
-rw-r--r-- | doc/examples/cloud-config-chef.txt | 72 | ||||
-rw-r--r-- | doc/examples/cloud-config-resolv-conf.txt | 4 | ||||
-rw-r--r-- | doc/examples/cloud-config-update-apt.txt | 7 | ||||
-rw-r--r-- | doc/merging.rst | 201 | ||||
-rw-r--r-- | doc/rtd/topics/examples.rst | 30 | ||||
-rw-r--r-- | doc/rtd/topics/merging.rst | 200 | ||||
-rw-r--r-- | doc/rtd/topics/modules.rst | 1 |
7 files changed, 273 insertions, 242 deletions
diff --git a/doc/examples/cloud-config-chef.txt b/doc/examples/cloud-config-chef.txt index 75d78a15..3cb62006 100644 --- a/doc/examples/cloud-config-chef.txt +++ b/doc/examples/cloud-config-chef.txt @@ -5,46 +5,50 @@ # Make sure that this file is valid yaml before starting instances. # It should be passed as user-data when starting the instance. # -# This example assumes the instance is 12.04 (precise) +# This example assumes the instance is 16.04 (xenial) # The default is to install from packages. -# Key from http://apt.opscode.com/packages@opscode.com.gpg.key +# Key from https://packages.chef.io/chef.asc apt: - sources: - - source: "deb http://apt.opscode.com/ $RELEASE-0.10 main" - key: | - -----BEGIN PGP PUBLIC KEY BLOCK----- - Version: GnuPG v1.4.9 (GNU/Linux) + source1: + source: "deb http://packages.chef.io/repos/apt/stable $RELEASE main" + key: | + -----BEGIN PGP PUBLIC KEY BLOCK----- + Version: GnuPG v1.4.12 (Darwin) + Comment: GPGTools - http://gpgtools.org - mQGiBEppC7QRBADfsOkZU6KZK+YmKw4wev5mjKJEkVGlus+NxW8wItX5sGa6kdUu - twAyj7Yr92rF+ICFEP3gGU6+lGo0Nve7KxkN/1W7/m3G4zuk+ccIKmjp8KS3qn99 - dxy64vcji9jIllVa+XXOGIp0G8GEaj7mbkixL/bMeGfdMlv8Gf2XPpp9vwCgn/GC - JKacfnw7MpLKUHOYSlb//JsEAJqao3ViNfav83jJKEkD8cf59Y8xKia5OpZqTK5W - ShVnNWS3U5IVQk10ZDH97Qn/YrK387H4CyhLE9mxPXs/ul18ioiaars/q2MEKU2I - XKfV21eMLO9LYd6Ny/Kqj8o5WQK2J6+NAhSwvthZcIEphcFignIuobP+B5wNFQpe - DbKfA/0WvN2OwFeWRcmmd3Hz7nHTpcnSF+4QX6yHRF/5BgxkG6IqBIACQbzPn6Hm - sMtm/SVf11izmDqSsQptCrOZILfLX/mE+YOl+CwWSHhl+YsFts1WOuh1EhQD26aO - Z84HuHV5HFRWjDLw9LriltBVQcXbpfSrRP5bdr7Wh8vhqJTPjrQnT3BzY29kZSBQ - YWNrYWdlcyA8cGFja2FnZXNAb3BzY29kZS5jb20+iGAEExECACAFAkppC7QCGwMG - CwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRApQKupg++Caj8sAKCOXmdG36gWji/K - +o+XtBfvdMnFYQCfTCEWxRy2BnzLoBBFCjDSK6sJqCu5Ag0ESmkLtBAIAIO2SwlR - lU5i6gTOp42RHWW7/pmW78CwUqJnYqnXROrt3h9F9xrsGkH0Fh1FRtsnncgzIhvh - DLQnRHnkXm0ws0jV0PF74ttoUT6BLAUsFi2SPP1zYNJ9H9fhhK/pjijtAcQwdgxu - wwNJ5xCEscBZCjhSRXm0d30bK1o49Cow8ZIbHtnXVP41c9QWOzX/LaGZsKQZnaMx - EzDk8dyyctR2f03vRSVyTFGgdpUcpbr9eTFVgikCa6ODEBv+0BnCH6yGTXwBid9g - w0o1e/2DviKUWCC+AlAUOubLmOIGFBuI4UR+rux9affbHcLIOTiKQXv79lW3P7W8 - AAfniSQKfPWXrrcAAwUH/2XBqD4Uxhbs25HDUUiM/m6Gnlj6EsStg8n0nMggLhuN - QmPfoNByMPUqvA7sULyfr6xCYzbzRNxABHSpf85FzGQ29RF4xsA4vOOU8RDIYQ9X - Q8NqqR6pydprRFqWe47hsAN7BoYuhWqTtOLSBmnAnzTR5pURoqcquWYiiEavZixJ - 3ZRAq/HMGioJEtMFrvsZjGXuzef7f0ytfR1zYeLVWnL9Bd32CueBlI7dhYwkFe+V - Ep5jWOCj02C1wHcwt+uIRDJV6TdtbIiBYAdOMPk15+VBdweBXwMuYXr76+A7VeDL - zIhi7tKFo6WiwjKZq0dzctsJJjtIfr4K4vbiD9Ojg1iISQQYEQIACQUCSmkLtAIb - DAAKCRApQKupg++CauISAJ9CxYPOKhOxalBnVTLeNUkAHGg2gACeIsbobtaD4ZHG - 0GLl8EkfA8uhluM= - =zKAm - -----END PGP PUBLIC KEY BLOCK----- + mQGiBEppC7QRBADfsOkZU6KZK+YmKw4wev5mjKJEkVGlus+NxW8wItX5sGa6kdUu + twAyj7Yr92rF+ICFEP3gGU6+lGo0Nve7KxkN/1W7/m3G4zuk+ccIKmjp8KS3qn99 + dxy64vcji9jIllVa+XXOGIp0G8GEaj7mbkixL/bMeGfdMlv8Gf2XPpp9vwCgn/GC + JKacfnw7MpLKUHOYSlb//JsEAJqao3ViNfav83jJKEkD8cf59Y8xKia5OpZqTK5W + ShVnNWS3U5IVQk10ZDH97Qn/YrK387H4CyhLE9mxPXs/ul18ioiaars/q2MEKU2I + XKfV21eMLO9LYd6Ny/Kqj8o5WQK2J6+NAhSwvthZcIEphcFignIuobP+B5wNFQpe + DbKfA/0WvN2OwFeWRcmmd3Hz7nHTpcnSF+4QX6yHRF/5BgxkG6IqBIACQbzPn6Hm + sMtm/SVf11izmDqSsQptCrOZILfLX/mE+YOl+CwWSHhl+YsFts1WOuh1EhQD26aO + Z84HuHV5HFRWjDLw9LriltBVQcXbpfSrRP5bdr7Wh8vhqJTPjrQnT3BzY29kZSBQ + YWNrYWdlcyA8cGFja2FnZXNAb3BzY29kZS5jb20+iGAEExECACAFAkppC7QCGwMG + CwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRApQKupg++Caj8sAKCOXmdG36gWji/K + +o+XtBfvdMnFYQCfTCEWxRy2BnzLoBBFCjDSK6sJqCu0IENIRUYgUGFja2FnZXMg + PHBhY2thZ2VzQGNoZWYuaW8+iGIEExECACIFAlQwYFECGwMGCwkIBwMCBhUIAgkK + CwQWAgMBAh4BAheAAAoJEClAq6mD74JqX94An26z99XOHWpLN8ahzm7cp13t4Xid + AJ9wVcgoUBzvgg91lKfv/34cmemZn7kCDQRKaQu0EAgAg7ZLCVGVTmLqBM6njZEd + Zbv+mZbvwLBSomdiqddE6u3eH0X3GuwaQfQWHUVG2yedyDMiG+EMtCdEeeRebTCz + SNXQ8Xvi22hRPoEsBSwWLZI8/XNg0n0f1+GEr+mOKO0BxDB2DG7DA0nnEISxwFkK + OFJFebR3fRsrWjj0KjDxkhse2ddU/jVz1BY7Nf8toZmwpBmdozETMOTx3LJy1HZ/ + Te9FJXJMUaB2lRyluv15MVWCKQJro4MQG/7QGcIfrIZNfAGJ32DDSjV7/YO+IpRY + IL4CUBQ65suY4gYUG4jhRH6u7H1p99sdwsg5OIpBe/v2Vbc/tbwAB+eJJAp89Zeu + twADBQf/ZcGoPhTGFuzbkcNRSIz+boaeWPoSxK2DyfScyCAuG41CY9+g0HIw9Sq8 + DuxQvJ+vrEJjNvNE3EAEdKl/zkXMZDb1EXjGwDi845TxEMhhD1dDw2qpHqnJ2mtE + WpZ7juGwA3sGhi6FapO04tIGacCfNNHmlRGipyq5ZiKIRq9mLEndlECr8cwaKgkS + 0wWu+xmMZe7N5/t/TK19HXNh4tVacv0F3fYK54GUjt2FjCQV75USnmNY4KPTYLXA + dzC364hEMlXpN21siIFgB04w+TXn5UF3B4FfAy5hevvr4DtV4MvMiGLu0oWjpaLC + MpmrR3Ny2wkmO0h+vgri9uIP06ODWIhJBBgRAgAJBQJKaQu0AhsMAAoJEClAq6mD + 74Jq4hIAoJ5KrYS8kCwj26SAGzglwggpvt3CAJ0bekyky56vNqoegB+y4PQVDv4K + zA== + =IxPr + -----END PGP PUBLIC KEY BLOCK----- chef: diff --git a/doc/examples/cloud-config-resolv-conf.txt b/doc/examples/cloud-config-resolv-conf.txt index 37ffc91a..c4843f54 100644 --- a/doc/examples/cloud-config-resolv-conf.txt +++ b/doc/examples/cloud-config-resolv-conf.txt @@ -5,9 +5,9 @@ # # Ensure that your yaml is valid and pass this as user-data when starting # the instance. Also be sure that your cloud.cfg file includes this -# configuration module in the appropirate section. +# configuration module in the appropriate section. # -manage-resolv-conf: true +manage_resolv_conf: true resolv_conf: nameservers: ['8.8.4.4', '8.8.8.8'] diff --git a/doc/examples/cloud-config-update-apt.txt b/doc/examples/cloud-config-update-apt.txt index a83ce3f7..647241ca 100644 --- a/doc/examples/cloud-config-update-apt.txt +++ b/doc/examples/cloud-config-update-apt.txt @@ -1,7 +1,8 @@ #cloud-config -# Update apt database on first boot -# (ie run apt-get update) +# Update apt database on first boot (run 'apt-get update'). +# Note, if packages are given, or package_upgrade is true, then +# update will be done independent of this setting. # -# Default: true +# Default: false # Aliases: apt_update package_update: false diff --git a/doc/merging.rst b/doc/merging.rst deleted file mode 100644 index bf49b909..00000000 --- a/doc/merging.rst +++ /dev/null @@ -1,201 +0,0 @@ -Overview -======== - -This was implemented because it has been a common feature request that there be -a way to specify how cloud-config yaml "dictionaries" provided as user-data are -merged together when there are multiple yamls to merge together (say when -performing an #include). - -Since previously the merging algorithm was very simple and would only overwrite -and not append lists, or strings, and so on it was decided to create a new and -improved way to merge dictionaries (and there contained objects) together in a -way that is customizable, thus allowing for users who provide cloud-config -user-data to determine exactly how there objects will be merged. - -For example. - -.. code-block:: yaml - - #cloud-config (1) - run_cmd: - - bash1 - - bash2 - - #cloud-config (2) - run_cmd: - - bash3 - - bash4 - -The previous way of merging the following 2 objects would result in a final -cloud-config object that contains the following. - -.. code-block:: yaml - - #cloud-config (merged) - run_cmd: - - bash3 - - bash4 - -Typically this is not what users want, instead they would likely prefer: - -.. code-block:: yaml - - #cloud-config (merged) - run_cmd: - - bash1 - - bash2 - - bash3 - - bash4 - -This way makes it easier to combine the various cloud-config objects you have -into a more useful list, thus reducing duplication that would have had to -occur in the previous method to accomplish the same result. - -Customizability -=============== - -Since the above merging algorithm may not always be the desired merging -algorithm (like how the previous merging algorithm was not always the preferred -one) the concept of customizing how merging can be done was introduced through -a new concept call 'merge classes'. - -A merge class is a class defintion which provides functions that can be used -to merge a given type with another given type. - -An example of one of these merging classes is the following: - -.. code-block:: python - - class Merger(object): - def __init__(self, merger, opts): - self._merger = merger - self._overwrite = 'overwrite' in opts - - # This merging algorithm will attempt to merge with - # another dictionary, on encountering any other type of object - # it will not merge with said object, but will instead return - # the original value - # - # On encountering a dictionary, it will create a new dictionary - # composed of the original and the one to merge with, if 'overwrite' - # is enabled then keys that exist in the original will be overwritten - # by keys in the one to merge with (and associated values). Otherwise - # if not in overwrite mode the 2 conflicting keys themselves will - # be merged. - def _on_dict(self, value, merge_with): - if not isinstance(merge_with, (dict)): - return value - merged = dict(value) - for (k, v) in merge_with.items(): - if k in merged: - if not self._overwrite: - merged[k] = self._merger.merge(merged[k], v) - else: - merged[k] = v - else: - merged[k] = v - return merged - -As you can see there is a '_on_dict' method here that will be given a source -value and a value to merge with. The result will be the merged object. This -code itself is called by another merging class which 'directs' the merging to -happen by analyzing the types of the objects to merge and attempting to find a -know object that will merge that type. I will avoid pasting that here, but it -can be found in the `mergers/__init__.py` file (see `LookupMerger` and -`UnknownMerger`). - -So following the typical cloud-init way of allowing source code to be -downloaded and used dynamically, it is possible for users to inject there own -merging files to handle specific types of merging as they choose (the basic -ones included will handle lists, dicts, and strings). Note how each merge can -have options associated with it which affect how the merging is performed, for -example a dictionary merger can be told to overwrite instead of attempt to -merge, or a string merger can be told to append strings instead of discarding -other strings to merge with. - -How to activate -=============== - -There are a few ways to activate the merging algorithms, and to customize them -for your own usage. - -1. The first way involves the usage of MIME messages in cloud-init to specify - multipart documents (this is one way in which multiple cloud-config is - joined together into a single cloud-config). Two new headers are looked - for, both of which can define the way merging is done (the first header to - exist wins). These new headers (in lookup order) are 'Merge-Type' and - 'X-Merge-Type'. The value should be a string which will satisfy the new - merging format defintion (see below for this format). - -2. The second way is actually specifying the merge-type in the body of the - cloud-config dictionary. There are 2 ways to specify this, either as a - string or as a dictionary (see format below). The keys that are looked up - for this definition are the following (in order), 'merge_how', - 'merge_type'. - -String format -------------- - -The string format that is expected is the following. - -:: - - classname1(option1,option2)+classname2(option3,option4).... - -The class name there will be connected to class names used when looking for the -class that can be used to merge and options provided will be given to the class -on construction of that class. - -For example, the default string that is used when none is provided is the -following: - -:: - - list()+dict()+str() - -Dictionary format ------------------ - -In cases where a dictionary can be used to specify the same information as the -string format (ie option #2 of above) it can be used, for example. - -.. code-block:: python - - {'merge_how': [{'name': 'list', 'settings': ['extend']}, - {'name': 'dict', 'settings': []}, - {'name': 'str', 'settings': ['append']}]} - -This would be the equivalent format for default string format but in dictionary -form instead of string form. - -Specifying multiple types and its effect -======================================== - -Now you may be asking yourself, if I specify a merge-type header or dictionary -for every cloud-config that I provide, what exactly happens? - -The answer is that when merging, a stack of 'merging classes' is kept, the -first one on that stack is the default merging classes, this set of mergers -will be used when the first cloud-config is merged with the initial empty -cloud-config dictionary. If the cloud-config that was just merged provided a -set of merging classes (via the above formats) then those merging classes will -be pushed onto the stack. Now if there is a second cloud-config to be merged -then the merging classes from the cloud-config before the first will be used -(not the default) and so on. This way a cloud-config can decide how it will -merge with a cloud-config dictionary coming after it. - -Other uses -========== - -In addition to being used for merging user-data sections, the default merging -algorithm for merging 'conf.d' yaml files (which form an initial yaml config -for cloud-init) was also changed to use this mechanism so its full -benefits (and customization) can also be used there as well. Other places that -used the previous merging are also, similarly, now extensible (metadata -merging, for example). - -Note, however, that merge algorithms are not used *across* types of -configuration. As was the case before merging was implemented, -user-data will overwrite conf.d configuration without merging. - -.. vi: textwidth=78 diff --git a/doc/rtd/topics/examples.rst b/doc/rtd/topics/examples.rst index a110721c..c30d2263 100644 --- a/doc/rtd/topics/examples.rst +++ b/doc/rtd/topics/examples.rst @@ -93,6 +93,13 @@ Install arbitrary packages :language: yaml :linenos: +Update apt database on first boot +================================= + +.. literalinclude:: ../../examples/cloud-config-update-apt.txt + :language: yaml + :linenos: + Run apt or yum upgrade ====================== @@ -149,6 +156,27 @@ Register RedHat Subscription :language: yaml :linenos: -.. _chef: http://www.opscode.com/chef/ +Configure data sources +====================== + +.. literalinclude:: ../../examples/cloud-config-datasources.txt + :language: yaml + :linenos: + +Create partitions and filesystems +================================= + +.. literalinclude:: ../../examples/cloud-config-disk-setup.txt + :language: yaml + :linenos: + +Grow partitions +=============== + +.. literalinclude:: ../../examples/cloud-config-growpart.txt + :language: yaml + :linenos: + +.. _chef: http://www.chef.io/chef/ .. _puppet: http://puppetlabs.com/ .. vi: textwidth=78 diff --git a/doc/rtd/topics/merging.rst b/doc/rtd/topics/merging.rst index eca118f5..2f927a47 100644 --- a/doc/rtd/topics/merging.rst +++ b/doc/rtd/topics/merging.rst @@ -2,5 +2,203 @@ Merging User-Data Sections ************************** -.. include:: ../../merging.rst +Overview +======== + +This was implemented because it has been a common feature request that there be +a way to specify how cloud-config yaml "dictionaries" provided as user-data are +merged together when there are multiple yamls to merge together (say when +performing an #include). + +Since previously the merging algorithm was very simple and would only overwrite +and not append lists, or strings, and so on it was decided to create a new and +improved way to merge dictionaries (and their contained objects) together in a +way that is customizable, thus allowing for users who provide cloud-config +user-data to determine exactly how their objects will be merged. + +For example. + +.. code-block:: yaml + + #cloud-config (1) + run_cmd: + - bash1 + - bash2 + + #cloud-config (2) + run_cmd: + - bash3 + - bash4 + +The previous way of merging the two objects above would result in a final +cloud-config object that contains the following. + +.. code-block:: yaml + + #cloud-config (merged) + run_cmd: + - bash3 + - bash4 + +Typically this is not what users want; instead they would likely prefer: + +.. code-block:: yaml + + #cloud-config (merged) + run_cmd: + - bash1 + - bash2 + - bash3 + - bash4 + +This way makes it easier to combine the various cloud-config objects you have +into a more useful list, thus reducing duplication necessary to accomplish the +same result with the previous method. + +Customizability +=============== + +Because the above merging algorithm may not always be desired (just as the +previous merging algorithm was not always the preferred one), the concept of +customized merging was introduced through 'merge classes'. + +A merge class is a class definition which provides functions that can be used +to merge a given type with another given type. + +An example of one of these merging classes is the following: + +.. code-block:: python + + class Merger(object): + def __init__(self, merger, opts): + self._merger = merger + self._overwrite = 'overwrite' in opts + + # This merging algorithm will attempt to merge with + # another dictionary, on encountering any other type of object + # it will not merge with said object, but will instead return + # the original value + # + # On encountering a dictionary, it will create a new dictionary + # composed of the original and the one to merge with, if 'overwrite' + # is enabled then keys that exist in the original will be overwritten + # by keys in the one to merge with (and associated values). Otherwise + # if not in overwrite mode the 2 conflicting keys themselves will + # be merged. + def _on_dict(self, value, merge_with): + if not isinstance(merge_with, (dict)): + return value + merged = dict(value) + for (k, v) in merge_with.items(): + if k in merged: + if not self._overwrite: + merged[k] = self._merger.merge(merged[k], v) + else: + merged[k] = v + else: + merged[k] = v + return merged + +As you can see there is a '_on_dict' method here that will be given a source +value and a value to merge with. The result will be the merged object. This +code itself is called by another merging class which 'directs' the merging to +happen by analyzing the types of the objects to merge and attempting to find a +know object that will merge that type. I will avoid pasting that here, but it +can be found in the `mergers/__init__.py` file (see `LookupMerger` and +`UnknownMerger`). + +So following the typical cloud-init way of allowing source code to be +downloaded and used dynamically, it is possible for users to inject there own +merging files to handle specific types of merging as they choose (the basic +ones included will handle lists, dicts, and strings). Note how each merge can +have options associated with it which affect how the merging is performed, for +example a dictionary merger can be told to overwrite instead of attempt to +merge, or a string merger can be told to append strings instead of discarding +other strings to merge with. + +How to activate +=============== + +There are a few ways to activate the merging algorithms, and to customize them +for your own usage. + +1. The first way involves the usage of MIME messages in cloud-init to specify + multipart documents (this is one way in which multiple cloud-config is + joined together into a single cloud-config). Two new headers are looked + for, both of which can define the way merging is done (the first header to + exist wins). These new headers (in lookup order) are 'Merge-Type' and + 'X-Merge-Type'. The value should be a string which will satisfy the new + merging format defintion (see below for this format). + +2. The second way is actually specifying the merge-type in the body of the + cloud-config dictionary. There are 2 ways to specify this, either as a + string or as a dictionary (see format below). The keys that are looked up + for this definition are the following (in order), 'merge_how', + 'merge_type'. + +String format +------------- + +The string format that is expected is the following. + +:: + + classname1(option1,option2)+classname2(option3,option4).... + +The class name there will be connected to class names used when looking for the +class that can be used to merge and options provided will be given to the class +on construction of that class. + +For example, the default string that is used when none is provided is the +following: + +:: + + list()+dict()+str() + +Dictionary format +----------------- + +A dictionary can be used when it specifies the same information as the +string format (i.e. the second option above), for example: + +.. code-block:: python + + {'merge_how': [{'name': 'list', 'settings': ['extend']}, + {'name': 'dict', 'settings': []}, + {'name': 'str', 'settings': ['append']}]} + +This would be the equivalent format for default string format but in dictionary +form instead of string form. + +Specifying multiple types and its effect +======================================== + +Now you may be asking yourself, if I specify a merge-type header or dictionary +for every cloud-config that I provide, what exactly happens? + +The answer is that when merging, a stack of 'merging classes' is kept, the +first one on that stack is the default merging classes, this set of mergers +will be used when the first cloud-config is merged with the initial empty +cloud-config dictionary. If the cloud-config that was just merged provided a +set of merging classes (via the above formats) then those merging classes will +be pushed onto the stack. Now if there is a second cloud-config to be merged +then the merging classes from the cloud-config before the first will be used +(not the default) and so on. This way a cloud-config can decide how it will +merge with a cloud-config dictionary coming after it. + +Other uses +========== + +In addition to being used for merging user-data sections, the default merging +algorithm for merging 'conf.d' yaml files (which form an initial yaml config +for cloud-init) was also changed to use this mechanism so its full +benefits (and customization) can also be used there as well. Other places that +used the previous merging are also, similarly, now extensible (metadata +merging, for example). + +Note, however, that merge algorithms are not used *across* types of +configuration. As was the case before merging was implemented, +user-data will overwrite conf.d configuration without merging. + .. vi: textwidth=78 diff --git a/doc/rtd/topics/modules.rst b/doc/rtd/topics/modules.rst index a3ead4f1..c963c09a 100644 --- a/doc/rtd/topics/modules.rst +++ b/doc/rtd/topics/modules.rst @@ -44,6 +44,7 @@ Modules .. automodule:: cloudinit.config.cc_set_hostname .. automodule:: cloudinit.config.cc_set_passwords .. automodule:: cloudinit.config.cc_snappy +.. automodule:: cloudinit.config.cc_snap_config .. automodule:: cloudinit.config.cc_spacewalk .. automodule:: cloudinit.config.cc_ssh .. automodule:: cloudinit.config.cc_ssh_authkey_fingerprints |