New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor integration tests to use pycloudlib LXD #1241
Conversation
features/cloud.py
Outdated
Location of the private key path to use. If None, the location | ||
will be a default location. | ||
""" | ||
pub_key_path = "lxd-pubkey" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you mentioned in passing, the integration tests currently take 4 times as long running via ssh to the lxd instance instead of lxc exec. Should this method be a noop (pass) or not be called in typical lxd testing used in our per-PR integration tests? We could rely on the ssh-based lxd communication in either our daily CRON or daily jenkins tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a quick pass on this. will get detailed review tomorrow.
@blackboxsw One idea that I had is that we can use the ssh option only for vm tests, since it is only those tests that require the use of ssh. To make that possible, we need to first merge this PR |
4446fd6
to
e24d7f2
Compare
@blackboxsw I have update the code with the refactoring and FIPS tests. Right now, the |
e24d7f2
to
b58b64a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you mentioned in chat. something is occuring with the shlex usage when trying to run cmds that emit json since we are splitting the cmdstring blindly on spaces. I've suggested a few changes inline but I think we also may have to sort to remaining checks in features/environment which check for a possible path where cloud_api is not set since I don't think we would have that path anymore right?
- features/environment: (before_all)
if context.config.cloud_api:
- features/environment:583 (_install_uat_in_container)
if not config.cloud_api
features/cloud.py
Outdated
@@ -116,10 +123,12 @@ def launch( | |||
:returns: | |||
An cloud provider instance | |||
""" | |||
inst = self._create_instance(series, image_name, user_data) | |||
inst = self._create_instance( | |||
series, instance_name, image_name, user_data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's use names kwargs here so if we change call signature or param ordering in the future, we don't break.
I get a bad feeling every time I see positional arguments re-ordered because we inserted a new one earlier sequentiall than previous params.
series, instance_name, image_name, user_data | |
series=series, instance_name=instance_name, image_name=image_name, user_data=user_data |
@@ -182,7 +182,7 @@ class FIPSUpdatesEntitlement(FIPSCommonEntitlement): | |||
|
|||
name = "fips-updates" | |||
title = "FIPS Updates" | |||
origin = "UbuntuFIPSUpdates" | |||
origin = "UbuntuFIPS" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's please put a comment in here # RELEASE_BLOCKER and reference your RT or a new ua-client issue so we are aware of the blocker
origin = "UbuntuFIPS" | |
origin = "UbuntuFIPS" # RELEASE_BLOCKER RT: #128770 |
features/cloud.py
Outdated
|
||
|
||
class LXDContainer(_LXD): | ||
name = "lxd-virtual-machine" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
name = "lxd-virtual-machine" | |
name = "lxd-container" |
pub_key, priv_key = self.api.create_key_pair() | ||
|
||
with open(pub_key_path, "w") as f: | ||
f.write(pub_key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably want to os.chmod these as 600 so that developers could use them on the cmdline to access instances using ssh -i lxd-pubkey ubuntu@<ip>
features/cloud.py
Outdated
@property | ||
def api(self) -> pycloudlib.cloud.BaseCloud: | ||
"""Return the api used to interact with the cloud provider.""" | ||
if self._api is None: | ||
self._api = pycloudlib.LXDVirtualMachine(tag=self.tag) | ||
|
||
return self._api |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might be able to define this simply in either in _LXD base class or even Cloud if we use a class attr to define the pycloublib.*Cloud callable to create
index 38114a6..c2b8600 100644
--- a/features/cloud.py
+++ b/features/cloud.py
@@ -29,6 +29,7 @@ class Cloud:
name = ""
pro_ids_path = ""
env_vars: "Tuple[str, ...]" = ()
+ pycloudlib_cls = None # type: pycloudlib.cloud.BaseCloud
def __init__(
self,
@@ -64,7 +65,13 @@ class Cloud:
@property
def api(self) -> pycloudlib.cloud.BaseCloud:
"""Return the api used to interact with the cloud provider."""
- raise NotImplementedError
+ if self.pycloudlib_cls is None:
+ raise NotImplementedError
+ if self._api is None:
+ self._api = self.pycloudlib_cls(
+ tag=self.tag, timestamp_suffix=self.timestamp_suffix
+ )
+ return self.api
def manage_ssh_key(self, private_key_path: "Optional[str]" = None) -> None:
"""Create and manage ssh key pairs to be used in the cloud provider.
@@ -496,8 +503,6 @@ class Azure(Cloud):
class _LXD(Cloud):
- name = "_lxd"
-
def _create_instance(
self,
series: str,
@@ -573,6 +578,7 @@ class _LXD(Cloud):
class LXDVirtualMachine(_LXD):
name = "lxd-virtual-machine"
+ pycloudlib_cls = pycloudlib.LXDVirtualMachine
def manage_ssh_key(self, private_key_path: "Optional[str]" = None) -> None:
"""Create and manage ssh key pairs to be used in the cloud provider.
@@ -606,6 +612,7 @@ class LXDVirtualMachine(_LXD):
class LXDContainer(_LXD):
name = "lxd-virtual-machine"
+ pycloudlib_cls = pycloudlib.LXDContainer
def manage_ssh_key(self, private_key_path: "Optional[str]" = None) -> None:
"""Create and manage ssh key pairs to be used in the cloud provider.
features/cloud.py
Outdated
def api(self) -> pycloudlib.cloud.BaseCloud: | ||
"""Return the api used to interact with the cloud provider.""" | ||
if self._api is None: | ||
self._api = pycloudlib.LXDContainer(tag=self.tag) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's also not forget timestamp_suffix=self.timestamp_suffix
features/cloud.py
Outdated
def api(self) -> pycloudlib.cloud.BaseCloud: | ||
"""Return the api used to interact with the cloud provider.""" | ||
if self._api is None: | ||
self._api = pycloudlib.LXDVirtualMachine(tag=self.tag) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't forget timestamp_suffix=self.timestamp_suffix
|
||
from uaclient.defaults import DEFAULT_CONFIG_FILE | ||
|
||
|
||
CONTAINER_PREFIX = "behave-test-" | ||
CONTAINER_PREFIX = "ubuntu-behave-test-" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just to guarantee that the instance name will be properly parsed by this regex:
https://github.com/canonical/pycloudlib/blob/master/pycloudlib/lxd/cloud.py#L580
b58b64a
to
b091699
Compare
@blackboxsw Thanks for the review and great catch on the leftover code for checking cloud_api. I have updated the code and I think instead of worrying about shellify at the moment, we should wait for this pycloudlib PR to land. When that happens, we will no longer need the |
4bfc023
to
a0d7522
Compare
Currently, our integration tests are using our own abstraction to handle LXD containers and vms. Since all other cloud we interact with are using pycloudlib, we have made the decision to apply that for LXD support as well.
The pin priority is not working for FIPS Updates because the preferences file we are creating has the wrong origin data. The product requires origin as "UbuntuFIPS" but we are using "UbuntuFIPSUpdates"
Add FIPS tests for xenial and upgrade test from xenial to bionic when FIPS is enabled in the system. However, FIPS Updates is not currently working when upgrading from xenial to bionic due to a problem on do-release-upgrade where we fail to access the right repo for FIPS Updates during the upgrade and end up disabling the ppa, causing some package, e.g. ubuntu-fips, to be removed.
a0d7522
to
6440f29
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much simpler to use the pycloudlib to rule all the platforms. Thanks for this work!
Refactor integration tests to use pycloudlib LXD implementation. This also allows us to test enabling
FIPS
for xenial.PS: This PR depends on the following pycloudlib PR