Skip to content

Commit 460846c

Browse files
jichenjcDean Troyer
authored andcommitted
[compute] Add server backup function
Add server backup function There is no return value for this command per following doc http://developer.openstack.org/api-ref-compute-v2.1.html#createBackup, also novaclient can't be updated now due to backward compatible issue http://lists.openstack.org/pipermail/openstack-dev/2016-March/089376.html, so we have to get the information ourselves. The Image tests were not using warlock images, so that needed to be fixed before we could completely test things like --wait. Change-Id: I30159518c4d3fdec89f15963bda641a0b03962d1
1 parent 9da02d1 commit 460846c

7 files changed

Lines changed: 458 additions & 0 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
=============
2+
server backup
3+
=============
4+
5+
A server backup is a disk image created in the Image store from a running server
6+
instance. The backup command manages the number of archival copies to retain.
7+
8+
Compute v2
9+
10+
server backup create
11+
--------------------
12+
13+
Create a server backup image
14+
15+
.. program:: server create
16+
.. code:: bash
17+
18+
os server backup create
19+
[--name <image-name>]
20+
[--type <backup-type>]
21+
[--rotate <count>]
22+
[--wait]
23+
<server>
24+
25+
.. option:: --name <image-name>
26+
27+
Name of the backup image (default: server name)
28+
29+
.. option:: --type <backup-type>
30+
31+
Used to populate the ``backup_type`` property of the backup
32+
image (default: empty)
33+
34+
.. option:: --rotate <count>
35+
36+
Number of backup images to keep (default: 1)
37+
38+
.. option:: --wait
39+
40+
Wait for operation to complete
41+
42+
.. describe:: <server>
43+
44+
Server to back up (name or ID)

doc/source/commands.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ referring to both Compute and Volume quotas.
118118
* ``security group``: (**Compute**, **Network**) - groups of network access rules
119119
* ``security group rule``: (**Compute**, **Network**) - the individual rules that define protocol/IP/port access
120120
* ``server``: (**Compute**) virtual machine instance
121+
* ``server backup``: (**Compute**) backup server disk image by using snapshot method
121122
* ``server dump``: (**Compute**) a dump file of a server created by features like kdump
122123
* ``server group``: (**Compute**) a grouping of servers
123124
* ``server image``: (**Compute**) saved server disk image
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# Copyright 2012-2013 OpenStack Foundation
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
#
15+
16+
"""Compute v2 Server action implementations"""
17+
18+
import sys
19+
20+
from oslo_utils import importutils
21+
import six
22+
23+
from openstackclient.common import command
24+
from openstackclient.common import exceptions
25+
from openstackclient.common import utils
26+
from openstackclient.i18n import _
27+
28+
29+
def _show_progress(progress):
30+
if progress:
31+
sys.stderr.write('\rProgress: %s' % progress)
32+
sys.stderr.flush()
33+
34+
35+
class CreateServerBackup(command.ShowOne):
36+
"""Create a server backup image"""
37+
38+
IMAGE_API_VERSIONS = {
39+
"1": "openstackclient.image.v1.image",
40+
"2": "openstackclient.image.v2.image",
41+
}
42+
43+
def get_parser(self, prog_name):
44+
parser = super(CreateServerBackup, self).get_parser(prog_name)
45+
parser.add_argument(
46+
'server',
47+
metavar='<server>',
48+
help=_('Server to back up (name or ID)'),
49+
)
50+
parser.add_argument(
51+
'--name',
52+
metavar='<image-name>',
53+
help=_('Name of the backup image (default: server name)'),
54+
)
55+
parser.add_argument(
56+
'--type',
57+
metavar='<backup-type>',
58+
help=_(
59+
'Used to populate the backup_type property of the backup '
60+
'image (default: empty)'
61+
),
62+
)
63+
parser.add_argument(
64+
'--rotate',
65+
metavar='<count>',
66+
type=int,
67+
help=_('Number of backups to keep (default: 1)'),
68+
)
69+
parser.add_argument(
70+
'--wait',
71+
action='store_true',
72+
help=_('Wait for backup image create to complete'),
73+
)
74+
return parser
75+
76+
def take_action(self, parsed_args):
77+
compute_client = self.app.client_manager.compute
78+
79+
server = utils.find_resource(
80+
compute_client.servers,
81+
parsed_args.server,
82+
)
83+
84+
# Set sane defaults as this API wants all mouths to be fed
85+
if parsed_args.name is None:
86+
backup_name = server.name
87+
else:
88+
backup_name = parsed_args.name
89+
if parsed_args.type is None:
90+
backup_type = ""
91+
else:
92+
backup_type = parsed_args.type
93+
if parsed_args.rotate is None:
94+
backup_rotation = 1
95+
else:
96+
backup_rotation = parsed_args.rotate
97+
98+
compute_client.servers.backup(
99+
server.id,
100+
backup_name,
101+
backup_type,
102+
backup_rotation,
103+
)
104+
105+
image_client = self.app.client_manager.image
106+
image = utils.find_resource(
107+
image_client.images,
108+
backup_name,
109+
)
110+
111+
if parsed_args.wait:
112+
if utils.wait_for_status(
113+
image_client.images.get,
114+
image.id,
115+
callback=_show_progress,
116+
):
117+
sys.stdout.write('\n')
118+
else:
119+
msg = _('Error creating server backup: %s') % parsed_args.name
120+
raise exceptions.CommandError(msg)
121+
122+
if self.app.client_manager._api_version['image'] == '1':
123+
info = {}
124+
info.update(image._info)
125+
info['properties'] = utils.format_dict(info.get('properties', {}))
126+
else:
127+
# Get the right image module to format the output
128+
image_module = importutils.import_module(
129+
self.IMAGE_API_VERSIONS[
130+
self.app.client_manager._api_version['image']
131+
]
132+
)
133+
info = image_module._format_image(image)
134+
return zip(*sorted(six.iteritems(info)))

0 commit comments

Comments
 (0)