Skip to content

Commit

Permalink
schema: add json defs for modules U-Z (#1360)
Browse files Browse the repository at this point in the history
Migrate legacy schema to cloud-init-schema.json:
    - cc_ubuntu_advantage
    - cc_ubuntu_drivers
    - cc_write_files: added minItems: 1 to list to catch potential
      YAML typos
    - cc_write_files_deferred
    - cc_zypper_add_repo

Defined JSON schema for the following modules:
- cc_update_hostname
- cc_update_etc_hosts: deprecate manage_etc_hosts: "template" as
      it is non-intuitive alias of True value
- cc_yum_add_repo:  docstring incorrectly status PER_ALWAYS, but no
  module frequency attribute was defined which defaults to
  PER_INSTANCE. Set it PER_INSTANCE to avoid change in behavior.

LP: #1858928, #1858929, #1858931, #1858932
  • Loading branch information
blackboxsw committed Apr 8, 2022
1 parent 0450a1f commit dd87c03
Show file tree
Hide file tree
Showing 18 changed files with 700 additions and 549 deletions.
31 changes: 2 additions & 29 deletions cloudinit/config/cc_ubuntu_advantage.py
Expand Up @@ -6,11 +6,7 @@

from cloudinit import log as logging
from cloudinit import subp, util
from cloudinit.config.schema import (
MetaSchema,
get_meta_doc,
validate_cloudconfig_schema,
)
from cloudinit.config.schema import MetaSchema, get_meta_doc
from cloudinit.settings import PER_INSTANCE

UA_URL = "https://ubuntu.com/advantage"
Expand Down Expand Up @@ -77,29 +73,7 @@
"frequency": PER_INSTANCE,
}

schema = {
"type": "object",
"properties": {
"ubuntu_advantage": {
"type": "object",
"properties": {
"enable": {
"type": "array",
"items": {"type": "string"},
},
"token": {
"type": "string",
"description": "A contract token obtained from %s."
% UA_URL,
},
},
"required": ["token"],
"additionalProperties": False,
}
},
}

__doc__ = get_meta_doc(meta, schema) # Supplement python help()
__doc__ = get_meta_doc(meta)

LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -194,7 +168,6 @@ def handle(name, cfg, cloud, log, args):
name,
)
return
validate_cloudconfig_schema(cfg, schema)
if "commands" in ua_section:
msg = (
'Deprecated configuration "ubuntu-advantage: commands" provided.'
Expand Down
47 changes: 5 additions & 42 deletions cloudinit/config/cc_ubuntu_drivers.py
Expand Up @@ -7,17 +7,13 @@

from cloudinit import log as logging
from cloudinit import subp, temp_utils, type_utils, util
from cloudinit.config.schema import (
MetaSchema,
get_meta_doc,
validate_cloudconfig_schema,
)
from cloudinit.config.schema import MetaSchema, get_meta_doc
from cloudinit.settings import PER_INSTANCE

LOG = logging.getLogger(__name__)

frequency = PER_INSTANCE
distros = ["ubuntu"]

meta: MetaSchema = {
"id": "cc_ubuntu_drivers",
"name": "Ubuntu Drivers",
Expand All @@ -37,47 +33,15 @@
"""
)
],
"frequency": frequency,
"frequency": PER_INSTANCE,
}

schema = {
"type": "object",
"properties": {
"drivers": {
"type": "object",
"additionalProperties": False,
"properties": {
"nvidia": {
"type": "object",
"additionalProperties": False,
"required": ["license-accepted"],
"properties": {
"license-accepted": {
"type": "boolean",
"description": (
"Do you accept the NVIDIA driver license?"
),
},
"version": {
"type": "string",
"description": (
"The version of the driver to install (e.g."
' "390", "410"). Defaults to the latest'
" version."
),
},
},
},
},
},
},
}
__doc__ = get_meta_doc(meta)

OLD_UBUNTU_DRIVERS_STDERR_NEEDLE = (
"ubuntu-drivers: error: argument <command>: invalid choice: 'install'"
)

__doc__ = get_meta_doc(meta, schema) # Supplement python help()


# Use a debconf template to configure a global debconf variable
# (linux/nvidia/latelink) setting this to "true" allows the
Expand Down Expand Up @@ -180,5 +144,4 @@ def handle(name, cfg, cloud, log, _args):
log.debug("Skipping module named %s, no 'drivers' key in config", name)
return

validate_cloudconfig_schema(cfg, schema)
install_drivers(cfg["drivers"], cloud.distro.install_packages)
84 changes: 63 additions & 21 deletions cloudinit/config/cc_update_etc_hosts.py
Expand Up @@ -6,18 +6,22 @@
#
# This file is part of cloud-init. See LICENSE file for license information.

"""
Update Etc Hosts
----------------
**Summary:** update the hosts file (usually ``/etc/hosts``)
"""Update Etc Hosts: Update the hosts file (usually ``/etc/hosts``)"""

from textwrap import dedent

from cloudinit import templater, util
from cloudinit.config.schema import MetaSchema, get_meta_doc
from cloudinit.settings import PER_ALWAYS

MODULE_DESCRIPTION = """\
This module will update the contents of the local hosts database (hosts file;
usually ``/etc/hosts``) based on the hostname/fqdn specified in config.
Management of the hosts file is controlled using ``manage_etc_hosts``. If this
is set to false, cloud-init will not manage the hosts file at all. This is the
default behavior.
If set to ``true`` or ``template``, cloud-init will generate the hosts file
If set to ``true``, cloud-init will generate the hosts file
using the template located in ``/etc/cloud/templates/hosts.tmpl``. In the
``/etc/cloud/templates/hosts.tmpl`` template, the strings ``$hostname`` and
``$fqdn`` will be replaced with the hostname and fqdn respectively.
Expand All @@ -36,24 +40,57 @@
.. note::
for instructions on specifying hostname and fqdn, see documentation for
``cc_set_hostname``
**Internal name:** ``cc_update_etc_hosts``
**Module frequency:** always
**Supported distros:** all
**Config keys**::
manage_etc_hosts: <true/"template"/false/"localhost">
fqdn: <fqdn>
hostname: <fqdn/hostname>
"""

from cloudinit import templater, util
from cloudinit.settings import PER_ALWAYS

frequency = PER_ALWAYS
distros = ["all"]

meta: MetaSchema = {
"id": "cc_update_etc_hosts",
"name": "Update Etc Hosts",
"title": "Update the hosts file (usually ``/etc/hosts``)",
"description": MODULE_DESCRIPTION,
"distros": distros,
"examples": [
dedent(
"""\
# Do not update or manage /etc/hosts at all. This is the default behavior.
#
# Whatever is present at instance boot time will be present after boot.
# User changes will not be overwritten.
manage_etc_hosts: false
"""
),
dedent(
"""\
# Manage /etc/hosts with cloud-init.
# On every boot, /etc/hosts will be re-written from
# ``/etc/cloud/templates/hosts.tmpl``.
#
# The strings '$hostname' and '$fqdn' are replaced in the template
# with the appropriate values either from the config-config ``fqdn`` or
# ``hostname`` if provided. When absent, the cloud metadata will be
# checked for ``local-hostname` which can be split into <hostname>.<fqdn>.
#
# To make modifications persistent across a reboot, you must modify
# ``/etc/cloud/templates/hosts.tmpl``.
manage_etc_hosts: true
"""
),
dedent(
"""\
# Update /etc/hosts every boot providing a "localhost" 127.0.1.1 entry
# with the latest hostname and fqdn as provided by either IMDS or
# cloud-config.
# All other entries will be left as is.
# 'ping `hostname`' will ping 127.0.1.1
manage_etc_hosts: localhost
"""
),
],
"frequency": PER_ALWAYS,
}

__doc__ = get_meta_doc(meta)


def handle(name, cfg, cloud, log, _args):
Expand All @@ -62,6 +99,11 @@ def handle(name, cfg, cloud, log, _args):
hosts_fn = cloud.distro.hosts_fn

if util.translate_bool(manage_hosts, addons=["template"]):
if manage_hosts == "template":
log.warning(
"DEPRECATED: please use manage_etc_hosts: true instead of"
" 'template'"
)
(hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud)
if not hostname:
log.warning(
Expand Down
86 changes: 62 additions & 24 deletions cloudinit/config/cc_update_hostname.py
Expand Up @@ -6,38 +6,76 @@
#
# This file is part of cloud-init. See LICENSE file for license information.

"""
Update Hostname
---------------
**Summary:** update hostname and fqdn
"""Update Hostname: Update hostname and fqdn"""

import os
from textwrap import dedent

from cloudinit import util
from cloudinit.config.schema import MetaSchema, get_meta_doc
from cloudinit.settings import PER_ALWAYS

MODULE_DESCRIPTION = """\
This module will update the system hostname and fqdn. If ``preserve_hostname``
is set, then the hostname will not be altered.
is set ``true``, then the hostname will not be altered.
.. note::
for instructions on specifying hostname and fqdn, see documentation for
``cc_set_hostname``
**Internal name:** ``cc_update_hostname``
**Module frequency:** always
**Supported distros:** all
**Config keys**::
preserve_hostname: <true/false>
prefer_fqdn_over_hostname: <true/false>
fqdn: <fqdn>
hostname: <fqdn/hostname>
"""

import os

from cloudinit import util
from cloudinit.settings import PER_ALWAYS

frequency = PER_ALWAYS
distros = ["all"]

meta: MetaSchema = {
"id": "cc_update_hostname",
"name": "Update Hostname",
"title": "Update hostname and fqdn",
"description": MODULE_DESCRIPTION,
"distros": distros,
"examples": [
dedent(
"""\
# By default: when ``preserve_hostname`` is not specified cloud-init
# updates ``/etc/hostname`` per-boot based on the cloud provided
# ``local-hostname`` setting. If you manually change ``/etc/hostname``
# after boot cloud-init will no longer modify it.
#
# This default cloud-init behavior is equivalent to this cloud-config:
preserve_hostname: false
"""
),
dedent(
"""\
# Prevent cloud-init from updating the system hostname.
preseve_hostname: true
"""
),
dedent(
"""\
# Prevent cloud-init from updating ``/etc/hostname``
preseve_hostname: true
"""
),
dedent(
"""\
# Set hostname to "external.fqdn.me" instead of "myhost"
fqdn: external.fqdn.me
hostname: myhost
prefer_fqdn_over_hostname: true
"""
),
dedent(
"""\
# Set hostname to "external" instead of "external.fqdn.me" when
# cloud metadata provides the ``local-hostname``: "external.fqdn.me".
prefer_fqdn_over_hostname: false
"""
),
],
"frequency": PER_ALWAYS,
}

__doc__ = get_meta_doc(meta)


def handle(name, cfg, cloud, log, _args):
Expand Down

0 comments on commit dd87c03

Please sign in to comment.