From 63d69ccefdca774d90be02a5625f543194163e73 Mon Sep 17 00:00:00 2001 From: Brett Holman Date: Sat, 6 Aug 2022 00:11:25 +0200 Subject: [PATCH] Add Ansible Config Module (#1579) Reference:https://github.com/canonical/cloud-init/commit/63d69ccefdca774d90be02a5625f543194163e73 Conflict:(1)only change cloudinit/util.py. (2)add 'from collections import namedtuple' The intended purpose of this commit is to augment cloud-init's configuration capabilities during boot. This allows users to run ansible playbooks against the local node as part of the boot order. Current Ansible workflows on nodes booted by cloud-init requires waiting for the booted node before running the playbook against the online node from the external control node. In the current state this could potentially be automated to using phone-home or runcmd modules, however neither of these options provides an obvious solution for integration and both require an external service to operate. This module enables users to seamlessly integrate cloud-init and Ansible auto-configuration during boot using ansible-pull, a less common mode of operation that differs from the normal mode of operation by installing Ansible locally and running a playbook pulled from a VCS repository. Expected future work in this module includes an option to configure management nodes. --- cloudinit/util.py | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/cloudinit/util.py b/cloudinit/util.py index 7c47871..8763050 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -33,7 +33,8 @@ import sys import time from base64 import b64decode, b64encode from errno import ENOENT -from functools import lru_cache +from collections import namedtuple +from functools import lru_cache, total_ordering from urllib import parse from typing import List @@ -2776,4 +2777,46 @@ def get_proc_ppid(pid): LOG.warning('Failed to load /proc/%s/stat. %s', pid, e) return ppid -# vi: ts=4 expandtab + +@total_ordering +class Version(namedtuple("Version", ["major", "minor", "patch", "rev"])): + def __new__(cls, major=-1, minor=-1, patch=-1, rev=-1): + """Default of -1 allows us to tiebreak in favor of the most specific + number""" + return super(Version, cls).__new__(cls, major, minor, patch, rev) + + @classmethod + def from_str(cls, version: str): + return cls(*(list(map(int, version.split("."))))) + + def __gt__(self, other): + return 1 == self._compare_version(other) + + def __eq__(self, other): + return ( + self.major == other.major + and self.minor == other.minor + and self.patch == other.patch + and self.rev == other.rev + ) + + def _compare_version(self, other) -> int: + """ + return values: + 1: self > v2 + -1: self < v2 + 0: self == v2 + to break a tie between 3.1.N and 3.1, always treat the more + specific number as larger + """ + if self == other: + return 0 + if self.major > other.major: + return 1 + if self.minor > other.minor: + return 1 + if self.patch > other.patch: + return 1 + if self.rev > other.rev: + return 1 + return -1 -- 2.33.0