Scott Moser has proposed merging ~smoser/cloud-init:bug/1745663-use-lxd-console into cloud-init:master.
Commit message: tests: lxd platform replace console log implementation. This disables the '_setup_console_log' path we had for getting a log in lxd. It implements a path that requires liblxc3.0. This should currently work on lxd snap from edge. LP: #1745663 Requested reviews: cloud-init commiters (cloud-init-dev) Related bugs: Bug #1745663 in cloud-init: "tests: lxd console code breaks when using lxd as snap" https://bugs.launchpad.net/cloud-init/+bug/1745663 For more details, see: https://code.launchpad.net/~smoser/cloud-init/+git/cloud-init/+merge/336722 see commit message -- Your team cloud-init commiters is requested to review the proposed merge of ~smoser/cloud-init:bug/1745663-use-lxd-console into cloud-init:master.
diff --git a/tests/cloud_tests/collect.py b/tests/cloud_tests/collect.py index 5ea88e5..d4f9135 100644 --- a/tests/cloud_tests/collect.py +++ b/tests/cloud_tests/collect.py @@ -44,8 +44,9 @@ def collect_console(instance, base_dir): LOG.debug('getting console log for %s to %s', instance, logfile) try: data = instance.console_log() - except NotImplementedError: - data = b'instance.console_log: not implemented' + except NotImplementedError as e: + # args[0] is hacky, but thats all I see to get at the message. + data = b'NotImplementedError:' + e.args[0].encode() with open(logfile, "wb") as fp: fp.write(data) diff --git a/tests/cloud_tests/platforms/lxd/instance.py b/tests/cloud_tests/platforms/lxd/instance.py index d2d2a1f..8b380e7 100644 --- a/tests/cloud_tests/platforms/lxd/instance.py +++ b/tests/cloud_tests/platforms/lxd/instance.py @@ -6,7 +6,8 @@ import os import shutil from tempfile import mkdtemp -from cloudinit.util import subp, ProcessExecutionError +from cloudinit.util import load_yaml, subp, ProcessExecutionError +from tests.cloud_tests.util import PlatformError from ..instances import Instance @@ -30,7 +31,6 @@ class LXDInstance(Instance): super(LXDInstance, self).__init__( platform, name, properties, config, features) self.tmpd = mkdtemp(prefix="%s-%s" % (type(self).__name__, name)) - self._setup_console_log() self.name = name @property @@ -39,21 +39,6 @@ class LXDInstance(Instance): self._pylxd_container.sync() return self._pylxd_container - def _setup_console_log(self): - logf = os.path.join(self.tmpd, "console.log") - - # doing this ensures we can read it. Otherwise it ends up root:root. - with open(logf, "w") as fp: - fp.write("# %s\n" % self.name) - - cfg = "lxc.console.logfile=%s" % logf - orig = self._pylxd_container.config.get('raw.lxc', "") - if orig: - orig += "\n" - self._pylxd_container.config['raw.lxc'] = orig + cfg - self._pylxd_container.save() - self._console_log_file = logf - def _execute(self, command, stdin=None, env=None): if env is None: env = {} @@ -97,19 +82,40 @@ class LXDInstance(Instance): """ self.pylxd_container.files.put(remote_path, data) + def _assert_console_log_support(self): + stdout, _ = subp(['lxc', 'info']) + info = load_yaml(stdout) + if 'console' not in info.get('api_extensions', []): + raise NotImplementedError( + "LXD server does not support console api extension.") + dver = info.get('environment', {}).get('driver_version', "") + if dver.startswith("2.") or dver.startwith("1."): + raise NotImplementedError( + "LXD Driver version not 3.x+ (%s)" % dver) + try: + stdout, stderr = subp(['lxc', 'console', '--help'], decode=False) + if not (b'console' in stdout and b'log' in stdout): + raise NotImplementedError( + "LXC Client console --help did not contain 'log'") + except ProcessExecutionError as e: + raise NotImplementedError( + "LXC client has no 'console' argument") + def console_log(self): """Console log. @return_value: bytes of this instance’s console """ - if not os.path.exists(self._console_log_file): - raise NotImplementedError( - "Console log '%s' does not exist. If this is a remote " - "lxc, then this is really NotImplementedError. If it is " - "A local lxc, then this is a RuntimeError." - "https://github.com/lxc/lxd/issues/1129") - with open(self._console_log_file, "rb") as fp: - return fp.read() + self._assert_console_log_support() + try: + stdout, stderr = subp( + ['lxc', 'console', '--show-log', self.name], decode=False) + return stdout + except ProcessExecutionError as e: + raise PlatformError( + "console log", + "Console log failed [%d]: stdout=%s stderr=%s" % ( + e.exit_code, e.stdout, e.stderr)) def reboot(self, wait=True): """Reboot instance."""
_______________________________________________ Mailing list: https://launchpad.net/~cloud-init-dev Post to : cloud-init-dev@lists.launchpad.net Unsubscribe : https://launchpad.net/~cloud-init-dev More help : https://help.launchpad.net/ListHelp