summaryrefslogtreecommitdiff
path: root/cloudinit/util.py
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/util.py')
-rw-r--r--cloudinit/util.py62
1 files changed, 55 insertions, 7 deletions
diff --git a/cloudinit/util.py b/cloudinit/util.py
index e3a891e4..77e7f66b 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -34,7 +34,7 @@ import time
from base64 import b64decode, b64encode
from collections import deque, namedtuple
from errno import EACCES, ENOENT
-from functools import lru_cache
+from functools import lru_cache, total_ordering
from typing import Callable, List, TypeVar
from urllib import parse
@@ -2894,13 +2894,19 @@ def get_proc_ppid(pid):
ppid = 0
try:
contents = load_file("/proc/%s/stat" % pid, quiet=True)
+ if contents:
+ # see proc.5 for format
+ m = re.search(r"^\d+ \(.+\) [RSDZTtWXxKPI] (\d+)", str(contents))
+ if m:
+ ppid = int(m.group(1))
+ else:
+ LOG.warning(
+ "Unable to match parent pid of process pid=%s input: %s",
+ pid,
+ contents,
+ )
except IOError as e:
LOG.warning("Failed to load /proc/%s/stat. %s", pid, e)
- if contents:
- parts = contents.split(" ", 4)
- # man proc says
- # ppid %d (4) The PID of the parent.
- ppid = int(parts[3])
return ppid
@@ -2919,4 +2925,46 @@ def error(msg, rc=1, fmt="Error:\n{}", sys_exit=False):
return rc
-# 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