Skip to content

Commit 3e7524c

Browse files
authored
pg migration (#477)
1 parent 0987f21 commit 3e7524c

File tree

5 files changed

+113
-4
lines changed

5 files changed

+113
-4
lines changed

linode_api4/objects/placement.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from dataclasses import dataclass
2-
from typing import List, Union
2+
from typing import List, Optional, Union
33

44
from linode_api4.objects.base import Base, Property
55
from linode_api4.objects.linode import Instance
@@ -34,6 +34,26 @@ class PlacementGroupMember(JSONObject):
3434
is_compliant: bool = False
3535

3636

37+
@dataclass
38+
class MigratedInstance(JSONObject):
39+
"""
40+
The ID for a compute instance being migrated into or out of the placement group.
41+
"""
42+
43+
linode_id: int = 0
44+
45+
46+
@dataclass
47+
class PlacementGroupMigrations(JSONObject):
48+
"""
49+
Any compute instances that are being migrated to or from the placement group.
50+
Returns an empty object if no migrations are taking place.
51+
"""
52+
53+
inbound: Optional[List[MigratedInstance]] = None
54+
outbound: Optional[List[MigratedInstance]] = None
55+
56+
3757
class PlacementGroup(Base):
3858
"""
3959
NOTE: Placement Groups may not currently be available to all users.
@@ -54,6 +74,7 @@ class PlacementGroup(Base):
5474
"placement_group_policy": Property(),
5575
"is_compliant": Property(),
5676
"members": Property(json_object=PlacementGroupMember),
77+
"migrations": Property(json_object=PlacementGroupMigrations),
5778
}
5879

5980
def assign(

test/fixtures/placement_groups.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,19 @@
1212
"linode_id": 123,
1313
"is_compliant": true
1414
}
15-
]
15+
],
16+
"migrations": {
17+
"inbound": [
18+
{
19+
"linode_id": 123
20+
}
21+
],
22+
"outbound": [
23+
{
24+
"linode_id": 456
25+
}
26+
]
27+
}
1628
}
1729
],
1830
"page": 1,

test/fixtures/placement_groups_123.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,17 @@
1010
"linode_id": 123,
1111
"is_compliant": true
1212
}
13-
]
13+
],
14+
"migrations": {
15+
"inbound": [
16+
{
17+
"linode_id": 123
18+
}
19+
],
20+
"outbound": [
21+
{
22+
"linode_id": 456
23+
}
24+
]
25+
}
1426
}

test/integration/models/placement/test_placement.py

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
1+
from test.integration.conftest import get_region
2+
from test.integration.helpers import (
3+
get_test_label,
4+
send_request_when_resource_available,
5+
)
6+
17
import pytest
28

3-
from linode_api4 import PlacementGroup
9+
from linode_api4 import (
10+
MigratedInstance,
11+
MigrationType,
12+
PlacementGroup,
13+
PlacementGroupPolicy,
14+
PlacementGroupType,
15+
)
416

517

618
@pytest.mark.smoke
@@ -48,3 +60,52 @@ def test_pg_assignment(test_linode_client, create_placement_group_with_linode):
4860

4961
assert pg.members[0].linode_id == inst.id
5062
assert inst.placement_group.id == pg.id
63+
64+
65+
def test_pg_migration(
66+
test_linode_client, e2e_test_firewall, create_placement_group
67+
):
68+
"""
69+
Tests that an instance can be migrated into and our of PGs successfully.
70+
"""
71+
client = test_linode_client
72+
73+
label = get_test_label(10)
74+
75+
pg_outbound = client.placement.group_create(
76+
label,
77+
get_region(test_linode_client, {"Placement Group"}),
78+
PlacementGroupType.anti_affinity_local,
79+
PlacementGroupPolicy.flexible,
80+
)
81+
82+
linode = client.linode.instance_create(
83+
"g6-nanode-1",
84+
pg_outbound.region,
85+
label=create_placement_group.label,
86+
placement_group=pg_outbound,
87+
)
88+
89+
pg_inbound = create_placement_group
90+
91+
# Says it could take up to ~6 hrs for migration to fully complete
92+
send_request_when_resource_available(
93+
300,
94+
linode.initiate_migration,
95+
placement_group=pg_inbound.id,
96+
migration_type=MigrationType.COLD,
97+
region=pg_inbound.region,
98+
)
99+
100+
pg_inbound = test_linode_client.load(PlacementGroup, pg_inbound.id)
101+
pg_outbound = test_linode_client.load(PlacementGroup, pg_outbound.id)
102+
103+
assert pg_inbound.migrations.inbound[0] == MigratedInstance(
104+
linode_id=linode.id
105+
)
106+
assert pg_outbound.migrations.outbound[0] == MigratedInstance(
107+
linode_id=linode.id
108+
)
109+
110+
linode.delete()
111+
pg_outbound.delete()

test/unit/objects/placement_test.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from linode_api4 import PlacementGroupPolicy
44
from linode_api4.objects import (
5+
MigratedInstance,
56
PlacementGroup,
67
PlacementGroupMember,
78
PlacementGroupType,
@@ -116,3 +117,5 @@ def validate_pg_123(self, pg: PlacementGroup):
116117
assert pg.members[0] == PlacementGroupMember(
117118
linode_id=123, is_compliant=True
118119
)
120+
assert pg.migrations.inbound[0] == MigratedInstance(linode_id=123)
121+
assert pg.migrations.outbound[0] == MigratedInstance(linode_id=456)

0 commit comments

Comments
 (0)