Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1!11.1.5
1!12.0.0
16 changes: 11 additions & 5 deletions pycloudlib/openstack/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,13 @@ def delete_image(self, image_id, **kwargs):
Args:
image_id: string, id of the image to delete
"""
self.conn.delete_image(image_id, wait=True)
image = self.conn.image.find_image(image_id)
if image is None:
return
self.conn.image.delete_image(image, ignore_missing=True)
# Preserve the wait=True behavior of the old self.conn.delete_image
# shade-compat helper by waiting for the image to actually be gone.
self.conn.image.wait_for_delete(image, wait=3600)

def released_image(self, release, **kwargs):
"""Not supported for openstack."""
Expand Down Expand Up @@ -185,8 +191,8 @@ def snapshot(self, instance, clean=True, **kwargs):
if clean:
instance.clean()
instance.shutdown()
image = self.conn.create_image_snapshot(
"{}-snapshot".format(self.tag), instance.server.id, wait=True
image = self.conn.compute.create_server_image(
instance.server, name="{}-snapshot".format(self.tag), wait=True, timeout=3600
)
self.created_images.append(image.id)
return image.id
Expand All @@ -213,10 +219,10 @@ def _get_openstack_keypair(self) -> KeyPair:
name = self.key_pair.name
public_key_content = self.key_pair.public_key_content

openstack_keypair = self.conn.get_keypair(name)
openstack_keypair = self.conn.compute.find_keypair(name)
if not openstack_keypair:
# If the openstack keypair doesn't exist, create it
return self.conn.create_keypair(name, public_key_content)
return self.conn.compute.create_keypair(name=name, public_key=public_key_content)
if public_key_content == openstack_keypair.public_key:
return openstack_keypair
raise CloudSetupError(
Expand Down
8 changes: 3 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
dynamic = ["version"]
requires-python = ">=3.8"
requires-python = ">=3.10"
name = "pycloudlib"
description = "Python library to launch, interact, and snapshot cloud instances"
classifiers = [
Expand All @@ -14,8 +14,6 @@ classifiers = [
"Natural Language :: English",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand All @@ -37,11 +35,11 @@ dependencies = [
"ibm-vpc >= 0.10, < 0.29.0",
"knack >= 0.7.1",
"oci >= 2.17.0",
"openstacksdk >= 1.1.0, < 1.5.0",
"openstacksdk >= 4.2.0, < 4.9.0",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a huge bump in openstackSDK, can we provide a separate commit to all self.conn changes to align with latest openstacksdk API changes?

It looks to me like we'd expect to see methods hung off of separate self.conn.compute, self.conn.network or self.conn.image. For example, instead of top-level self.conn.create_floating_ip we should be able to use the self.conn.network.create_ip method.

"paramiko >= 2.9.2",
"protobuf",
"pyparsing >= 2, < 3.0.0",
"python-openstackclient >= 5.2.1",
"python-openstackclient >= 5.2.1, < 8.3.0",
"pyyaml >= 5.1",
"qemu.qmp >= 0.0.3",
"requests >= 2.22",
Expand Down
10 changes: 6 additions & 4 deletions tests/unit_tests/openstack/test_cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,26 @@ class TestOpenstackKeypair:

def test_keypair_doesnt_exist(self, m_openstack, _m_public_key_content):
"""Test no pre-existing openstack keypair."""
m_openstack.return_value.get_keypair.return_value = None
m_openstack.return_value.compute.find_keypair.return_value = None
cloud = Openstack(tag="test", network=None, config_file=StringIO(CONFIG))
cloud._get_openstack_keypair()
assert 1 == cloud.conn.create_keypair.call_count
assert 1 == cloud.conn.compute.create_keypair.call_count

def test_keypairs_match(self, m_openstack, m_public_key_content):
"""Test pre-existing openstack keypair has same name and content."""
openstack_keypair_mock = mock.Mock()
openstack_keypair_mock.public_key = m_public_key_content()
m_openstack.return_value.get_keypair.return_value = openstack_keypair_mock
m_openstack.return_value.compute.find_keypair.return_value = openstack_keypair_mock
cloud = Openstack(tag="test", network=None, config_file=StringIO(CONFIG))
assert openstack_keypair_mock == cloud._get_openstack_keypair()

def test_keypairs_dont_match(self, m_openstack, m_public_key_content):
"""Test pre-existing openstack keypair has different content."""
openstack_keypair_mock = mock.Mock()
openstack_keypair_mock.public_key = m_public_key_content()
m_openstack.return_value.get_keypair.return_value = mock.Mock(public_key="something else")
m_openstack.return_value.compute.find_keypair.return_value = mock.Mock(
public_key="something else"
)
cloud = Openstack(tag="test", network=None, config_file=StringIO(CONFIG))
with pytest.raises(CloudSetupError):
cloud._get_openstack_keypair()
8 changes: 1 addition & 7 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
requires =
tox-uv
# As it may be undesired to make formatting changes, by default only check
envlist = ruff, mypy, py38
envlist = ruff, mypy, py310
skipsdist = true

[common]
Expand All @@ -15,12 +15,6 @@ envdir = {[common]envdir}
deps = {[common]deps}
commands = {envpython} -m pytest --doctest-modules --cov=pycloudlib --cov-branch {posargs:tests/unit_tests}

[testenv:py38]
envdir = {[common]envdir}
deps = {[common]deps}
basepython = python3.8
Comment thread
rpocase marked this conversation as resolved.
commands = {[testenv:pytest]commands}

[testenv:py310]
envdir = {[common]envdir}
deps = {[common]deps}
Expand Down
Loading