summaryrefslogtreecommitdiff
path: root/cloudinit/util.py
diff options
context:
space:
mode:
authorAndrew Lee <andrew.lee@metaswitch.com>2022-04-07 21:52:44 +0100
committerGitHub <noreply@github.com>2022-04-07 15:52:44 -0500
commitfa53c7f4086f5937bc9bd328dba9f91ca73b6614 (patch)
treeae8d9a3fb18a77a7e72d2eaf08d58764535ecf22 /cloudinit/util.py
parente57cdc8b4b9aaa08b3c694208370a129e329905f (diff)
downloadcloud-init-git-fa53c7f4086f5937bc9bd328dba9f91ca73b6614.tar.gz
BUG 1473527: module ssh-authkey-fingerprints fails Input/output error… (#1340)
Don't error if we cannot log to /dev/console We've seen instances on VMware of serial consoles not being set up correctly by the kernel, making /dev/ttyS0 not set up correctly, and hence /dev/console not writeable to. In such circumstances, cloud-init should not fail, instead it should gracefully fall back to logging to stdout. The only time cloud-init tries to write to `/dev/console` is in the `multi_log` command- which is called by the ssh-authkey-fingerprints module LP: #1473527
Diffstat (limited to 'cloudinit/util.py')
-rw-r--r--cloudinit/util.py33
1 files changed, 25 insertions, 8 deletions
diff --git a/cloudinit/util.py b/cloudinit/util.py
index 10a7ca71..2864e18b 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -381,6 +381,12 @@ def find_modules(root_dir) -> dict:
return entries
+def write_to_console(conpath, text):
+ with open(conpath, "w") as wfh:
+ wfh.write(text)
+ wfh.flush()
+
+
def multi_log(
text,
console=True,
@@ -393,14 +399,25 @@ def multi_log(
sys.stderr.write(text)
if console:
conpath = "/dev/console"
+ writing_to_console_worked = False
if os.path.exists(conpath):
- with open(conpath, "w") as wfh:
- wfh.write(text)
- wfh.flush()
- elif fallback_to_stdout:
- # A container may lack /dev/console (arguably a container bug). If
- # it does not exist, then write output to stdout. this will result
- # in duplicate stderr and stdout messages if stderr was True.
+ try:
+ write_to_console(conpath, text)
+ writing_to_console_worked = True
+ except OSError:
+ console_error = "Failed to write to /dev/console"
+ sys.stdout.write(f"{console_error}\n")
+ if log:
+ log.log(logging.WARNING, console_error)
+
+ if fallback_to_stdout and not writing_to_console_worked:
+ # A container may lack /dev/console (arguably a container bug).
+ # Additionally, /dev/console may not be writable to on a VM (again
+ # likely a VM bug or virtualization bug).
+ #
+ # If either of these is the case, then write output to stdout.
+ # This will result in duplicate stderr and stdout messages if
+ # stderr was True.
#
# even though upstart or systemd might have set up output to go to
# /dev/console, the user may have configured elsewhere via
@@ -2061,7 +2078,7 @@ def write_file(
omode="wb",
preserve_mode=False,
*,
- ensure_dir_exists=True
+ ensure_dir_exists=True,
):
"""
Writes a file with the given content and sets the file mode as specified.