From 3f381b9e1e1dfb3eb89dd8cbdcebc1a756010afa Mon Sep 17 00:00:00 2001 From: Ryan Harper Date: Wed, 17 Jul 2019 19:21:25 -0500 Subject: Update ubuntu-advantage-revert-tip.patch The patch to revert the ubuntu-advantages did not revert enough of the ubuntu_advantage config module; though it did revert all of the test-cases. This results in unittest failures during building against master where it applies the debian dir from the release against master. --- debian/patches/ubuntu-advantage-revert-tip.patch | 260 ++++++++++++++++++++++- 1 file changed, 255 insertions(+), 5 deletions(-) diff --git a/debian/patches/ubuntu-advantage-revert-tip.patch b/debian/patches/ubuntu-advantage-revert-tip.patch index 2934f9ea..37e5114b 100644 --- a/debian/patches/ubuntu-advantage-revert-tip.patch +++ b/debian/patches/ubuntu-advantage-revert-tip.patch @@ -7,9 +7,257 @@ Origin: backport Bug: https://bugs.launchpad.net/cloud-init/+bug/1828641 Forwarded: not-needed Last-Update: 2019-05-10 ---- a/cloudinit/config/cc_ubuntu_advantage.py -+++ b/cloudinit/config/cc_ubuntu_advantage.py -@@ -152,28 +152,14 @@ def maybe_install_ua_tools(cloud): +Index: cloud-init/cloudinit/config/cc_ubuntu_advantage.py +=================================================================== +--- cloud-init.orig/cloudinit/config/cc_ubuntu_advantage.py ++++ cloud-init/cloudinit/config/cc_ubuntu_advantage.py +@@ -1,143 +1,150 @@ ++# Copyright (C) 2018 Canonical Ltd. ++# + # This file is part of cloud-init. See LICENSE file for license information. + +-"""ubuntu_advantage: Configure Ubuntu Advantage support services""" ++"""Ubuntu advantage: manage ubuntu-advantage offerings from Canonical.""" + ++import sys + from textwrap import dedent + +-import six +- ++from cloudinit import log as logging + from cloudinit.config.schema import ( + get_schema_doc, validate_cloudconfig_schema) +-from cloudinit import log as logging + from cloudinit.settings import PER_INSTANCE ++from cloudinit.subp import prepend_base_command + from cloudinit import util + + +-UA_URL = 'https://ubuntu.com/advantage' +- + distros = ['ubuntu'] ++frequency = PER_INSTANCE ++ ++LOG = logging.getLogger(__name__) + + schema = { + 'id': 'cc_ubuntu_advantage', + 'name': 'Ubuntu Advantage', +- 'title': 'Configure Ubuntu Advantage support services', ++ 'title': 'Install, configure and manage ubuntu-advantage offerings', + 'description': dedent("""\ +- Attach machine to an existing Ubuntu Advantage support contract and +- enable or disable support services such as Livepatch, ESM, +- FIPS and FIPS Updates. When attaching a machine to Ubuntu Advantage, +- one can also specify services to enable. When the 'enable' +- list is present, any named service will be enabled and all absent +- services will remain disabled. +- +- Note that when enabling FIPS or FIPS updates you will need to schedule +- a reboot to ensure the machine is running the FIPS-compliant kernel. +- See :ref:`Power State Change` for information on how to configure +- cloud-init to perform this reboot. ++ This module provides configuration options to setup ubuntu-advantage ++ subscriptions. ++ ++ .. note:: ++ Both ``commands`` value can be either a dictionary or a list. If ++ the configuration provided is a dictionary, the keys are only used ++ to order the execution of the commands and the dictionary is ++ merged with any vendor-data ubuntu-advantage configuration ++ provided. If a ``commands`` is provided as a list, any vendor-data ++ ubuntu-advantage ``commands`` are ignored. ++ ++ Ubuntu-advantage ``commands`` is a dictionary or list of ++ ubuntu-advantage commands to run on the deployed machine. ++ These commands can be used to enable or disable subscriptions to ++ various ubuntu-advantage products. See 'man ubuntu-advantage' for more ++ information on supported subcommands. ++ ++ .. note:: ++ Each command item can be a string or list. If the item is a list, ++ 'ubuntu-advantage' can be omitted and it will automatically be ++ inserted as part of the command. + """), + 'distros': distros, + 'examples': [dedent("""\ +- # Attach the machine to an Ubuntu Advantage support contract with a +- # UA contract token obtained from %s. +- ubuntu_advantage: +- token: +- """ % UA_URL), dedent("""\ +- # Attach the machine to an Ubuntu Advantage support contract enabling +- # only fips and esm services. Services will only be enabled if +- # the environment supports said service. Otherwise warnings will +- # be logged for incompatible services specified. ++ # Enable Extended Security Maintenance using your service auth token ++ ubuntu-advantage: ++ commands: ++ 00: ubuntu-advantage enable-esm ++ """), dedent("""\ ++ # Enable livepatch by providing your livepatch token + ubuntu-advantage: +- token: +- enable: +- - fips +- - esm ++ commands: ++ 00: ubuntu-advantage enable-livepatch ++ + """), dedent("""\ +- # Attach the machine to an Ubuntu Advantage support contract and enable +- # the FIPS service. Perform a reboot once cloud-init has +- # completed. +- power_state: +- mode: reboot ++ # Convenience: the ubuntu-advantage command can be omitted when ++ # specifying commands as a list and 'ubuntu-advantage' will ++ # automatically be prepended. ++ # The following commands are equivalent + ubuntu-advantage: +- token: +- enable: +- - fips +- """)], ++ commands: ++ 00: ['enable-livepatch', 'my-token'] ++ 01: ['ubuntu-advantage', 'enable-livepatch', 'my-token'] ++ 02: ubuntu-advantage enable-livepatch my-token ++ 03: 'ubuntu-advantage enable-livepatch my-token' ++ """)], + 'frequency': PER_INSTANCE, + 'type': 'object', + 'properties': { +- 'ubuntu_advantage': { ++ 'ubuntu-advantage': { + 'type': 'object', + 'properties': { +- 'enable': { +- 'type': 'array', +- 'items': {'type': 'string'}, +- }, +- 'token': { +- 'type': 'string', +- 'description': ( +- 'A contract token obtained from %s.' % UA_URL) ++ 'commands': { ++ 'type': ['object', 'array'], # Array of strings or dict ++ 'items': { ++ 'oneOf': [ ++ {'type': 'array', 'items': {'type': 'string'}}, ++ {'type': 'string'}] ++ }, ++ 'additionalItems': False, # Reject non-string & non-list ++ 'minItems': 1, ++ 'minProperties': 1, + } + }, +- 'required': ['token'], +- 'additionalProperties': False ++ 'additionalProperties': False, # Reject keys not in schema ++ 'required': ['commands'] + } + } + } + ++# TODO schema for 'assertions' and 'commands' are too permissive at the moment. ++# Once python-jsonschema supports schema draft 6 add support for arbitrary ++# object keys with 'patternProperties' constraint to validate string values. ++ + __doc__ = get_schema_doc(schema) # Supplement python help() + +-LOG = logging.getLogger(__name__) ++UA_CMD = "ubuntu-advantage" + + +-def configure_ua(token=None, enable=None): +- """Call ua commandline client to attach or enable services.""" +- error = None +- if not token: +- error = ('ubuntu_advantage: token must be provided') +- LOG.error(error) +- raise RuntimeError(error) +- +- if enable is None: +- enable = [] +- elif isinstance(enable, six.string_types): +- LOG.warning('ubuntu_advantage: enable should be a list, not' +- ' a string; treating as a single enable') +- enable = [enable] +- elif not isinstance(enable, list): +- LOG.warning('ubuntu_advantage: enable should be a list, not' +- ' a %s; skipping enabling services', +- type(enable).__name__) +- enable = [] ++def run_commands(commands): ++ """Run the commands provided in ubuntu-advantage:commands config. + +- attach_cmd = ['ua', 'attach', token] +- LOG.debug('Attaching to Ubuntu Advantage. %s', ' '.join(attach_cmd)) +- try: +- util.subp(attach_cmd) +- except util.ProcessExecutionError as e: +- msg = 'Failure attaching Ubuntu Advantage:\n{error}'.format( +- error=str(e)) +- util.logexc(LOG, msg) +- raise RuntimeError(msg) +- enable_errors = [] +- for service in enable: ++ Commands are run individually. Any errors are collected and reported ++ after attempting all commands. ++ ++ @param commands: A list or dict containing commands to run. Keys of a ++ dict will be used to order the commands provided as dict values. ++ """ ++ if not commands: ++ return ++ LOG.debug('Running user-provided ubuntu-advantage commands') ++ if isinstance(commands, dict): ++ # Sort commands based on dictionary key ++ commands = [v for _, v in sorted(commands.items())] ++ elif not isinstance(commands, list): ++ raise TypeError( ++ 'commands parameter was not a list or dict: {commands}'.format( ++ commands=commands)) ++ ++ fixed_ua_commands = prepend_base_command('ubuntu-advantage', commands) ++ ++ cmd_failures = [] ++ for command in fixed_ua_commands: ++ shell = isinstance(command, str) + try: +- cmd = ['ua', 'enable', service] +- util.subp(cmd, capture=True) ++ util.subp(command, shell=shell, status_cb=sys.stderr.write) + except util.ProcessExecutionError as e: +- enable_errors.append((service, e)) +- if enable_errors: +- for service, error in enable_errors: +- msg = 'Failure enabling "{service}":\n{error}'.format( +- service=service, error=str(error)) +- util.logexc(LOG, msg) +- raise RuntimeError( +- 'Failure enabling Ubuntu Advantage service(s): {}'.format( +- ', '.join('"{}"'.format(service) +- for service, _ in enable_errors))) ++ cmd_failures.append(str(e)) ++ if cmd_failures: ++ msg = ( ++ 'Failures running ubuntu-advantage commands:\n' ++ '{cmd_failures}'.format( ++ cmd_failures=cmd_failures)) ++ util.logexc(LOG, msg) ++ raise RuntimeError(msg) + + + def maybe_install_ua_tools(cloud): + """Install ubuntu-advantage-tools if not present.""" +- if util.which('ua'): ++ if util.which('ubuntu-advantage'): + return + try: + cloud.distro.update_package_sources() +@@ -152,28 +159,14 @@ def maybe_install_ua_tools(cloud): def handle(name, cfg, cloud, log, args): @@ -44,8 +292,10 @@ Last-Update: 2019-05-10 + run_commands(cfgin.get('commands', [])) # vi: ts=4 expandtab ---- a/cloudinit/config/tests/test_ubuntu_advantage.py -+++ b/cloudinit/config/tests/test_ubuntu_advantage.py +Index: cloud-init/cloudinit/config/tests/test_ubuntu_advantage.py +=================================================================== +--- cloud-init.orig/cloudinit/config/tests/test_ubuntu_advantage.py ++++ cloud-init/cloudinit/config/tests/test_ubuntu_advantage.py @@ -1,7 +1,10 @@ # This file is part of cloud-init. See LICENSE file for license information. -- cgit v1.2.1