Skip to content

Commit b0e560d

Browse files
k0kamzur
andauthored
Resume suspend server (#394)
* Implement resuming and suspending of servers --------- Co-authored-by: Martin Zurowietz <martin@zurowietz.de>
1 parent 857fcc8 commit b0e560d

File tree

9 files changed

+166
-1
lines changed

9 files changed

+166
-1
lines changed

.github/workflows/integration_tests.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@ jobs:
4242
name: Deploy OpenStack ${{ matrix.name }} and run integration tests with php ${{matrix.php_version}}
4343
steps:
4444
- uses: actions/checkout@v2
45+
4546
- name: get cache directory
4647
id: composer-cache
4748
run: |
4849
echo "::set-output name=dir::$(composer config cache-files-dir)"
50+
4951
- uses: actions/cache@v3
5052
with:
5153
path: |
@@ -54,13 +56,16 @@ jobs:
5456
key: ${{ runner.os }}-composer-${{ matrix.php_version }}-${{ hashFiles('**.composer.lock') }}
5557
restore-keys: |
5658
${{ runner.os }}-composer-${{ matrix.php_version }}-
59+
5760
- uses: shivammathur/setup-php@v2
5861
with:
5962
php-version: ${{ matrix.php_version }}
6063
extensions: curl
6164
tools: composer:v2
6265
coverage: none
66+
6367
- run: composer install --prefer-dist --no-interaction --no-progress
68+
6469
- name: Restore devstack cache
6570
uses: actions/cache@v3
6671
with:
@@ -69,6 +74,7 @@ jobs:
6974
!/opt/stack/data
7075
~/devstack/
7176
key: ${{ runner.os }}-openstack-${{ matrix.openstack_version }}-${{ github.workflow }}
77+
7278
- name: Deploy devstack
7379
uses: EmilienM/devstack-action@v0.11
7480
with:
@@ -81,6 +87,7 @@ jobs:
8187
[filter:versioned_writes]
8288
allow_object_versioning = true
8389
enabled_services: 's-account,s-container,s-object,s-proxy,s-bak'
90+
8491
- name: Set env variables
8592
run: |
8693
{
@@ -96,9 +103,23 @@ jobs:
96103
echo OS_FLAVOR=1
97104
echo OS_DOMAIN_ID=default
98105
} >> "$GITHUB_ENV"
106+
99107
- name: Check if Block Storage API v2 must be tested
100108
if: matrix.block_storage_v2 == true
101109
run: echo "OS_BLOCK_STORAGE_V2=1" >> "$GITHUB_ENV"
110+
102111
- name: Execute Integration tests via PhpUnit
103112
run: vendor/bin/phpunit --configuration ./phpunit.sample.xml.dist
104113

114+
- name: Collect logs
115+
if: ${{ failure() }}
116+
run: |
117+
set -x
118+
journalctl >failure-logs
119+
120+
- name: Save logs
121+
if: ${{ failure() }}
122+
uses: actions/upload-artifact@v3
123+
with:
124+
name: failure-logs
125+
path: failure-logs

doc/services/compute/v2/servers.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,3 +280,14 @@ You can also refine by network label:
280280
$ipAddresses = $server->listAddresses([
281281
'networkLabel' => '{networkLabel}',
282282
]);
283+
284+
Suspend
285+
-------
286+
287+
.. sample:: Compute/v2/images/suspend.php
288+
289+
Resume
290+
------
291+
292+
.. sample:: Compute/v2/images/resume.php
293+

samples/Compute/v2/servers/resume.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
require 'vendor/autoload.php';
4+
5+
$openstack = new OpenStack\OpenStack([
6+
'authUrl' => '{authUrl}',
7+
'region' => '{region}',
8+
'user' => [
9+
'id' => '{userId}',
10+
'password' => '{password}',
11+
],
12+
]);
13+
14+
$service = $openstack->computeV2();
15+
$server = $service->getServer(['id' => '{serverId}']);
16+
17+
$server->resume();
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
require 'vendor/autoload.php';
4+
5+
$openstack = new OpenStack\OpenStack([
6+
'authUrl' => '{authUrl}',
7+
'region' => '{region}',
8+
'user' => [
9+
'id' => '{userId}',
10+
'password' => '{password}',
11+
],
12+
]);
13+
14+
$service = $openstack->computeV2();
15+
$server = $service->getServer(['id' => '{serverId}']);
16+
17+
$server->suspend();

src/Compute/v2/Api.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,30 @@ public function stopServer(): array
332332
];
333333
}
334334

335+
public function resumeServer(): array
336+
{
337+
return [
338+
'method' => 'POST',
339+
'path' => 'servers/{id}/action',
340+
'params' => [
341+
'id' => $this->params->urlId('server'),
342+
'resume' => $this->params->nullAction(),
343+
],
344+
];
345+
}
346+
347+
public function suspendServer(): array
348+
{
349+
return [
350+
'method' => 'POST',
351+
'path' => 'servers/{id}/action',
352+
'params' => [
353+
'id' => $this->params->urlId('server'),
354+
'suspend' => $this->params->nullAction(),
355+
],
356+
];
357+
}
358+
335359
public function rebuildServer(): array
336360
{
337361
return [

src/Compute/v2/Models/Server.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,28 @@ public function stop()
217217
]);
218218
}
219219

220+
/**
221+
* Resumes server.
222+
*/
223+
public function resume(): void
224+
{
225+
$this->execute($this->api->resumeServer(), [
226+
'id' => $this->id,
227+
'resume' => null,
228+
]);
229+
}
230+
231+
/**
232+
* Suspends server.
233+
*/
234+
public function suspend(): void
235+
{
236+
$this->execute($this->api->suspendServer(), [
237+
'id' => $this->id,
238+
'suspend' => null,
239+
]);
240+
}
241+
220242
/**
221243
* Rebuilds the server.
222244
*

tests/sample/Compute/v2/ServerTest.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ public function testGetVncConsole(Server $createdServer)
318318
{
319319
/** @var array $console */
320320
require_once $this->sampleFile('servers/get_server_vnc_console.php', [
321-
'{serverId}' => $createdServer->id
321+
'{serverId}' => $createdServer->id,
322322
]);
323323

324324
$this->assertIsArray($console);
@@ -331,6 +331,9 @@ public function testGetVncConsole(Server $createdServer)
331331
*/
332332
public function testGetConsoleOutput(Server $createdServer)
333333
{
334+
// wait for the server to be ready
335+
sleep(5);
336+
334337
/** @var string $consoleOutput */
335338
require_once $this->sampleFile('servers/get_server_console_output.php', ['{serverId}' => $createdServer->id]);
336339

@@ -361,4 +364,31 @@ public function testDelete(Server $createdServer)
361364
$this->expectException(BadResponseError::class);
362365
$createdServer->retrieve();
363366
}
367+
368+
public function testSuspend()
369+
{
370+
$server = $this->createServer();
371+
372+
require_once $this->sampleFile('servers/suspend.php', ['{serverId}' => $server->id]);
373+
374+
$server->waitUntil('SUSPENDED');
375+
$this->assertEquals('SUSPENDED', $server->status);
376+
377+
return $server;
378+
}
379+
380+
/**
381+
* @depends testSuspend
382+
*/
383+
public function testResume(Server $server)
384+
{
385+
$this->assertEquals('SUSPENDED', $server->status);
386+
387+
require_once $this->sampleFile('servers/resume.php', ['{serverId}' => $server->id]);
388+
389+
$server->waitUntil('ACTIVE', 300);
390+
$this->assertEquals('ACTIVE', $server->status);
391+
392+
$this->deleteServer($server);
393+
}
364394
}

tests/sample/Compute/v2/VolumeAttachmentTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ public function testAttach(): VolumeAttachment
1111
{
1212
$server = $this->createServer();
1313

14+
// let's wait for the server to be completely up
15+
// https://bugs.launchpad.net/nova/+bug/1998148
16+
// https://bugs.launchpad.net/nova/+bug/1960346
17+
sleep(10);
18+
1419
$volume = $this->getCachedService(Service::class)->createVolume(
1520
[
1621
'name' => $this->randomStr(),

tests/unit/Compute/v2/Models/ServerTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,24 @@ public function test_it_stops()
211211
self::assertNull($this->server->stop());
212212
}
213213

214+
public function test_it_resumes()
215+
{
216+
$expectedJson = ['resume' => null];
217+
218+
$this->setupMock('POST', 'servers/serverId/action', $expectedJson, [], new Response(202));
219+
220+
$this->assertNull($this->server->resume());
221+
}
222+
223+
public function test_it_suspends()
224+
{
225+
$expectedJson = ['suspend' => null];
226+
227+
$this->setupMock('POST', 'servers/serverId/action', $expectedJson, [], new Response(202));
228+
229+
$this->assertNull($this->server->suspend());
230+
}
231+
214232
public function test_it_resizes()
215233
{
216234
$expectedJson = ['resize' => ['flavorRef' => 'flavorId']];

0 commit comments

Comments
 (0)