blob: 943512249559338bd5cdf8d3c9ee3efd513834f1 [file] [log] [blame]
Attila Fazekas36b1fcf2013-01-31 16:41:04 +01001# vim: tabstop=4 shiftwidth=4 softtabstop=4
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
15import json
Attila Fazekas36b1fcf2013-01-31 16:41:04 +010016import time
17import urllib
18
19from tempest.common.rest_client import RestClient
20from tempest import exceptions
Matthew Treinishf4a9b0f2013-07-26 16:58:26 -040021from tempest.openstack.common import log as logging
Attila Fazekas36b1fcf2013-01-31 16:41:04 +010022
23LOG = logging.getLogger(__name__)
24
25
26class SnapshotsClientJSON(RestClient):
27 """Client class to send CRUD Volume API requests."""
28
29 def __init__(self, config, username, password, auth_url, tenant_name=None):
30 super(SnapshotsClientJSON, self).__init__(config, username, password,
31 auth_url, tenant_name)
32
33 self.service = self.config.volume.catalog_type
34 self.build_interval = self.config.volume.build_interval
35 self.build_timeout = self.config.volume.build_timeout
36
37 def list_snapshots(self, params=None):
38 """List all the snapshot."""
39 url = 'snapshots'
40 if params:
41 url += '?%s' % urllib.urlencode(params)
42
43 resp, body = self.get(url)
44 body = json.loads(body)
45 return resp, body['snapshots']
46
Abhijeet Malawade5945ffe2013-09-17 05:54:44 -070047 def list_snapshots_with_detail(self, params=None):
Attila Fazekas36b1fcf2013-01-31 16:41:04 +010048 """List the details of all snapshots."""
49 url = 'snapshots/detail'
50 if params:
51 url += '?%s' % urllib.urlencode(params)
52
53 resp, body = self.get(url)
54 body = json.loads(body)
55 return resp, body['snapshots']
56
57 def get_snapshot(self, snapshot_id):
58 """Returns the details of a single snapshot."""
59 url = "snapshots/%s" % str(snapshot_id)
60 resp, body = self.get(url)
61 body = json.loads(body)
62 return resp, body['snapshot']
63
64 def create_snapshot(self, volume_id, **kwargs):
65 """
66 Creates a new snapshot.
67 volume_id(Required): id of the volume.
68 force: Create a snapshot even if the volume attached (Default=False)
69 display_name: Optional snapshot Name.
70 display_description: User friendly snapshot description.
71 """
72 post_body = {'volume_id': volume_id}
73 post_body.update(kwargs)
74 post_body = json.dumps({'snapshot': post_body})
75 resp, body = self.post('snapshots', post_body, self.headers)
76 body = json.loads(body)
77 return resp, body['snapshot']
78
QingXin Mengdc95f5e2013-09-16 19:06:44 -070079 def update_snapshot(self, snapshot_id, **kwargs):
80 """Updates a snapshot."""
81 put_body = json.dumps({'snapshot': kwargs})
82 resp, body = self.put('snapshots/%s' % snapshot_id, put_body,
83 self.headers)
84 body = json.loads(body)
85 return resp, body['snapshot']
86
Attila Fazekasa8b5fe72013-08-01 16:59:06 +020087 # NOTE(afazekas): just for the wait function
Attila Fazekas36b1fcf2013-01-31 16:41:04 +010088 def _get_snapshot_status(self, snapshot_id):
89 resp, body = self.get_snapshot(snapshot_id)
90 status = body['status']
Attila Fazekasa8b5fe72013-08-01 16:59:06 +020091 # NOTE(afazekas): snapshot can reach an "error"
Attila Fazekas36b1fcf2013-01-31 16:41:04 +010092 # state in a "normal" lifecycle
93 if (status == 'error'):
94 raise exceptions.SnapshotBuildErrorException(
Sean Dague14c68182013-04-14 15:34:30 -040095 snapshot_id=snapshot_id)
Attila Fazekas36b1fcf2013-01-31 16:41:04 +010096
97 return status
98
Attila Fazekasa8b5fe72013-08-01 16:59:06 +020099 # NOTE(afazkas): Wait reinvented again. It is not in the correct layer
Attila Fazekas36b1fcf2013-01-31 16:41:04 +0100100 def wait_for_snapshot_status(self, snapshot_id, status):
101 """Waits for a Snapshot to reach a given status."""
102 start_time = time.time()
103 old_value = value = self._get_snapshot_status(snapshot_id)
104 while True:
105 dtime = time.time() - start_time
106 time.sleep(self.build_interval)
107 if value != old_value:
108 LOG.info('Value transition from "%s" to "%s"'
109 'in %d second(s).', old_value,
110 value, dtime)
111 if (value == status):
112 return value
113
114 if dtime > self.build_timeout:
115 message = ('Time Limit Exceeded! (%ds)'
116 'while waiting for %s, '
117 'but we got %s.' %
118 (self.build_timeout, status, value))
119 raise exceptions.TimeoutException(message)
120 time.sleep(self.build_interval)
121 old_value = value
122 value = self._get_snapshot_status(snapshot_id)
123
124 def delete_snapshot(self, snapshot_id):
125 """Delete Snapshot."""
126 return self.delete("snapshots/%s" % str(snapshot_id))
127
128 def is_resource_deleted(self, id):
129 try:
130 self.get_snapshot(id)
131 except exceptions.NotFound:
132 return True
133 return False
zhangyanzid4d3c6d2013-11-06 09:27:13 +0800134
135 def reset_snapshot_status(self, snapshot_id, status):
136 """Reset the specified snapshot's status."""
137 post_body = json.dumps({'os-reset_status': {"status": status}})
138 resp, body = self.post('snapshots/%s/action' % snapshot_id, post_body,
139 self.headers)
140 return resp, body
141
142 def update_snapshot_status(self, snapshot_id, status, progress):
143 """Update the specified snapshot's status."""
144 post_body = {
145 'status': status,
146 'progress': progress
147 }
148 post_body = json.dumps({'os-update_snapshot_status': post_body})
149 url = 'snapshots/%s/action' % str(snapshot_id)
150 resp, body = self.post(url, post_body, self.headers)
151 return resp, body