Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / logic / callbacks.py @ aee560b0

History | View | Annotate | Download (11.6 kB)

1 cb409cfd Georgios Gousios
# Copyright 2011 GRNET S.A. All rights reserved.
2 ad2d6807 Vangelis Koukis
#
3 cb409cfd Georgios Gousios
# Redistribution and use in source and binary forms, with or without
4 cb409cfd Georgios Gousios
# modification, are permitted provided that the following conditions
5 cb409cfd Georgios Gousios
# are met:
6 ad2d6807 Vangelis Koukis
#
7 cb409cfd Georgios Gousios
#   1. Redistributions of source code must retain the above copyright
8 cb409cfd Georgios Gousios
#      notice, this list of conditions and the following disclaimer.
9 ad2d6807 Vangelis Koukis
#
10 cb409cfd Georgios Gousios
#  2. Redistributions in binary form must reproduce the above copyright
11 cb409cfd Georgios Gousios
#     notice, this list of conditions and the following disclaimer in the
12 cb409cfd Georgios Gousios
#     documentation and/or other materials provided with the distribution.
13 cb409cfd Georgios Gousios
#
14 cb409cfd Georgios Gousios
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
15 cb409cfd Georgios Gousios
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 cb409cfd Georgios Gousios
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 cb409cfd Georgios Gousios
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18 cb409cfd Georgios Gousios
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 cb409cfd Georgios Gousios
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 cb409cfd Georgios Gousios
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 cb409cfd Georgios Gousios
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 cb409cfd Georgios Gousios
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 cb409cfd Georgios Gousios
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 cb409cfd Georgios Gousios
# SUCH DAMAGE.
25 cb409cfd Georgios Gousios
#
26 cb409cfd Georgios Gousios
# The views and conclusions contained in the software and documentation are
27 cb409cfd Georgios Gousios
# those of the authors and should not be interpreted as representing official
28 cb409cfd Georgios Gousios
# policies, either expressed or implied, of GRNET S.A.
29 cb409cfd Georgios Gousios
30 cb409cfd Georgios Gousios
# Callback functions used by the dispatcher to process incoming notifications
31 cb409cfd Georgios Gousios
# from AMQP queues.
32 cb409cfd Georgios Gousios
33 86f046a8 Giorgos Verigakis
import logging
34 23c84263 Georgios Gousios
import json
35 c4e55622 Christos Stavrakakis
from functools import wraps
36 23c84263 Georgios Gousios
37 727fb2f9 Christos Stavrakakis
from synnefo.db.models import (Backend, VirtualMachine, Network,
38 727fb2f9 Christos Stavrakakis
                               BackendNetwork, pooled_rapi_client)
39 aee560b0 Christos Stavrakakis
from synnefo.logic import utils, backend, rapi
40 23c84263 Georgios Gousios
41 c4e55622 Christos Stavrakakis
from synnefo.lib.utils import merge_time
42 c4e55622 Christos Stavrakakis
43 fdfd8c6d Christos Stavrakakis
log = logging.getLogger(__name__)
44 23c84263 Georgios Gousios
45 cc92b70f Christos Stavrakakis
46 a17a8e98 Christos Stavrakakis
def handle_message_delivery(func):
47 a17a8e98 Christos Stavrakakis
    """ Generic decorator for handling messages.
48 c4e55622 Christos Stavrakakis

49 a17a8e98 Christos Stavrakakis
    This decorator is responsible for converting the message into json format,
50 a17a8e98 Christos Stavrakakis
    handling of common exceptions and acknowledment of message if needed.
51 c4e55622 Christos Stavrakakis

52 c4e55622 Christos Stavrakakis
    """
53 c4e55622 Christos Stavrakakis
    @wraps(func)
54 c4e55622 Christos Stavrakakis
    def wrapper(client, message, *args, **kwargs):
55 c4e55622 Christos Stavrakakis
        try:
56 e6f6627c Christos Stavrakakis
            msg = None
57 c4e55622 Christos Stavrakakis
            msg = json.loads(message['body'])
58 a17a8e98 Christos Stavrakakis
            func(msg)
59 a17a8e98 Christos Stavrakakis
            client.basic_ack(message)
60 22ee6892 Christos Stavrakakis
        except ValueError as e:
61 22ee6892 Christos Stavrakakis
            log.error("Incoming message not in JSON format %s: %s", e, message)
62 b9d91e62 Christos Stavrakakis
            client.basic_nack(message)
63 22ee6892 Christos Stavrakakis
        except KeyError as e:
64 22ee6892 Christos Stavrakakis
            log.error("Malformed incoming JSON, missing attribute %s: %s",
65 22ee6892 Christos Stavrakakis
                      e, message)
66 b9d91e62 Christos Stavrakakis
            client.basic_nack(message)
67 a17a8e98 Christos Stavrakakis
        except Exception as e:
68 e6f6627c Christos Stavrakakis
            if msg:
69 e6f6627c Christos Stavrakakis
                log.exception("Unexpected error: %s, msg: %s", e, msg)
70 e6f6627c Christos Stavrakakis
            else:
71 e6f6627c Christos Stavrakakis
                log.exception("Unexpected error: %s", e)
72 b9d91e62 Christos Stavrakakis
            client.basic_reject(message)
73 a17a8e98 Christos Stavrakakis
74 a17a8e98 Christos Stavrakakis
    return wrapper
75 a17a8e98 Christos Stavrakakis
76 22ee6892 Christos Stavrakakis
77 a17a8e98 Christos Stavrakakis
def instance_from_msg(func):
78 a17a8e98 Christos Stavrakakis
    """ Decorator for getting the VirtualMachine object of the msg.
79 a17a8e98 Christos Stavrakakis

80 a17a8e98 Christos Stavrakakis
    """
81 a17a8e98 Christos Stavrakakis
    @handle_message_delivery
82 a17a8e98 Christos Stavrakakis
    @wraps(func)
83 a17a8e98 Christos Stavrakakis
    def wrapper(msg):
84 a17a8e98 Christos Stavrakakis
        try:
85 a17a8e98 Christos Stavrakakis
            vm_id = utils.id_from_instance_name(msg["instance"])
86 7f2dbcad Christos Stavrakakis
            vm = VirtualMachine.objects.select_for_update().get(id=vm_id)
87 a17a8e98 Christos Stavrakakis
            func(vm, msg)
88 c4e55622 Christos Stavrakakis
        except VirtualMachine.InvalidBackendIdError:
89 c4e55622 Christos Stavrakakis
            log.debug("Ignoring msg for unknown instance %s.", msg['instance'])
90 c4e55622 Christos Stavrakakis
        except VirtualMachine.DoesNotExist:
91 c4e55622 Christos Stavrakakis
            log.error("VM for instance %s with id %d not found in DB.",
92 c4e55622 Christos Stavrakakis
                      msg['instance'], vm_id)
93 66932293 Christos Stavrakakis
        except (Network.InvalidBackendIdError, Network.DoesNotExist) as e:
94 66932293 Christos Stavrakakis
            log.error("Invalid message, can not find network. msg: %s", msg)
95 a17a8e98 Christos Stavrakakis
    return wrapper
96 a17a8e98 Christos Stavrakakis
97 22ee6892 Christos Stavrakakis
98 a17a8e98 Christos Stavrakakis
def network_from_msg(func):
99 22ee6892 Christos Stavrakakis
    """ Decorator for getting the BackendNetwork object of the msg.
100 a17a8e98 Christos Stavrakakis

101 a17a8e98 Christos Stavrakakis
    """
102 a17a8e98 Christos Stavrakakis
    @handle_message_delivery
103 a17a8e98 Christos Stavrakakis
    @wraps(func)
104 a17a8e98 Christos Stavrakakis
    def wrapper(msg):
105 a17a8e98 Christos Stavrakakis
        try:
106 a17a8e98 Christos Stavrakakis
            network_id = utils.id_from_network_name(msg["network"])
107 d2e73c0c Christos Stavrakakis
            network = Network.objects.select_for_update().get(id=network_id)
108 22ee6892 Christos Stavrakakis
            backend = Backend.objects.get(clustername=msg['cluster'])
109 99af08a4 Christos Stavrakakis
            bnet, new = BackendNetwork.objects.get_or_create(network=network,
110 99af08a4 Christos Stavrakakis
                                                             backend=backend)
111 99af08a4 Christos Stavrakakis
            if new:
112 99af08a4 Christos Stavrakakis
                log.info("Created missing BackendNetwork %s", bnet)
113 99af08a4 Christos Stavrakakis
            func(bnet, msg)
114 a17a8e98 Christos Stavrakakis
        except Network.InvalidBackendIdError:
115 a17a8e98 Christos Stavrakakis
            log.debug("Ignoring msg for unknown network %s.", msg['network'])
116 a17a8e98 Christos Stavrakakis
        except Network.DoesNotExist:
117 22ee6892 Christos Stavrakakis
            log.error("Network %s not found in DB.", msg['network'])
118 22ee6892 Christos Stavrakakis
        except Backend.DoesNotExist:
119 22ee6892 Christos Stavrakakis
            log.error("Backend %s not found in DB.", msg['cluster'])
120 22ee6892 Christos Stavrakakis
        except BackendNetwork.DoesNotExist:
121 22ee6892 Christos Stavrakakis
            log.error("Network %s on backend %s not found in DB.",
122 22ee6892 Christos Stavrakakis
                      msg['network'], msg['cluster'])
123 a17a8e98 Christos Stavrakakis
    return wrapper
124 a17a8e98 Christos Stavrakakis
125 22ee6892 Christos Stavrakakis
126 a17a8e98 Christos Stavrakakis
def if_update_required(func):
127 a17a8e98 Christos Stavrakakis
    """
128 a17a8e98 Christos Stavrakakis
    Decorator for checking if an incoming message needs to update the db.
129 a17a8e98 Christos Stavrakakis

130 a17a8e98 Christos Stavrakakis
    The database will not be updated in the following cases:
131 a17a8e98 Christos Stavrakakis
    - The message has been redelivered and the action has already been
132 a17a8e98 Christos Stavrakakis
      completed. In this case the event_time will be equal with the one
133 a17a8e98 Christos Stavrakakis
      in the database.
134 22ee6892 Christos Stavrakakis
    - The message describes a previous state in the ganeti, from the one that
135 22ee6892 Christos Stavrakakis
      is described in the db. In this case the event_time will be smaller from
136 22ee6892 Christos Stavrakakis
      the one in the database.
137 a17a8e98 Christos Stavrakakis

138 a17a8e98 Christos Stavrakakis
    """
139 a17a8e98 Christos Stavrakakis
    @wraps(func)
140 a17a8e98 Christos Stavrakakis
    def wrapper(target, msg):
141 bb80a8d7 Christos Stavrakakis
        try:
142 bb80a8d7 Christos Stavrakakis
            event_time = merge_time(msg['event_time'])
143 bb80a8d7 Christos Stavrakakis
        except:
144 bb80a8d7 Christos Stavrakakis
            log.error("Received message with malformed time: %s",
145 bb80a8d7 Christos Stavrakakis
                      msg['event_time'])
146 bb80a8d7 Christos Stavrakakis
            raise KeyError
147 bb80a8d7 Christos Stavrakakis
148 a17a8e98 Christos Stavrakakis
        db_time = target.backendtime
149 a17a8e98 Christos Stavrakakis
150 22ee6892 Christos Stavrakakis
        if db_time and event_time <= db_time:
151 a17a8e98 Christos Stavrakakis
            format_ = "%d/%m/%y %H:%M:%S:%f"
152 cc92b70f Christos Stavrakakis
            log.debug("Ignoring message %s.\nevent_timestamp: %s"
153 cc92b70f Christos Stavrakakis
                      " db_timestamp: %s",
154 a17a8e98 Christos Stavrakakis
                      msg,
155 a17a8e98 Christos Stavrakakis
                      event_time.strftime(format_),
156 a17a8e98 Christos Stavrakakis
                      db_time.strftime(format_))
157 a17a8e98 Christos Stavrakakis
            return
158 a17a8e98 Christos Stavrakakis
        # New message. Update the database!
159 a17a8e98 Christos Stavrakakis
        func(target, msg, event_time)
160 c4e55622 Christos Stavrakakis
161 c4e55622 Christos Stavrakakis
    return wrapper
162 c4e55622 Christos Stavrakakis
163 c4e55622 Christos Stavrakakis
164 a17a8e98 Christos Stavrakakis
@instance_from_msg
165 a17a8e98 Christos Stavrakakis
@if_update_required
166 a17a8e98 Christos Stavrakakis
def update_db(vm, msg, event_time):
167 c25cc9ec Vangelis Koukis
    """Process a notification of type 'ganeti-op-status'"""
168 33b93f81 Christos Stavrakakis
    log.debug("Processing ganeti-op-status msg: %s", msg)
169 23c84263 Georgios Gousios
170 c4e55622 Christos Stavrakakis
    if msg['type'] != "ganeti-op-status":
171 c4e55622 Christos Stavrakakis
        log.error("Message is of unknown type %s.", msg['type'])
172 c4e55622 Christos Stavrakakis
        return
173 7ca9e930 Vangelis Koukis
174 727fb2f9 Christos Stavrakakis
    operation = msg["operation"]
175 727fb2f9 Christos Stavrakakis
    status = msg["status"]
176 727fb2f9 Christos Stavrakakis
    jobID = msg["jobId"]
177 727fb2f9 Christos Stavrakakis
    logmsg = msg["logmsg"]
178 fd95834e Christos Stavrakakis
    nics = msg.get("nics", None)
179 727fb2f9 Christos Stavrakakis
    job_fields = msg.get("job_fields", {})
180 aee560b0 Christos Stavrakakis
    result = msg.get("result", [])
181 727fb2f9 Christos Stavrakakis
182 727fb2f9 Christos Stavrakakis
    # Special case: OP_INSTANCE_CREATE with opportunistic locking may fail
183 727fb2f9 Christos Stavrakakis
    # if all Ganeti nodes are already locked. Retry the job without
184 727fb2f9 Christos Stavrakakis
    # opportunistic locking..
185 727fb2f9 Christos Stavrakakis
    if (operation == "OP_INSTANCE_CREATE" and status == "error" and
186 727fb2f9 Christos Stavrakakis
       job_fields.get("opportunistic_locking", False)):
187 aee560b0 Christos Stavrakakis
        try:
188 aee560b0 Christos Stavrakakis
            error_code = result[1][1]
189 aee560b0 Christos Stavrakakis
        except IndexError:
190 aee560b0 Christos Stavrakakis
            error_code = None
191 aee560b0 Christos Stavrakakis
        if error_code == rapi.ECODE_TEMP_NORES:
192 aee560b0 Christos Stavrakakis
            if vm.backendjobid != jobID:  # The job has already been retried!
193 aee560b0 Christos Stavrakakis
                return
194 aee560b0 Christos Stavrakakis
            # Remove extra fields
195 aee560b0 Christos Stavrakakis
            [job_fields.pop(f) for f in ("OP_ID", "reason")]
196 aee560b0 Christos Stavrakakis
            # Remove 'pnode' and 'snode' if they were set by Ganeti iallocator.
197 aee560b0 Christos Stavrakakis
            # Ganeti will fail if both allocator and nodes are specified.
198 aee560b0 Christos Stavrakakis
            allocator = job_fields.pop("iallocator")
199 aee560b0 Christos Stavrakakis
            if allocator is not None:
200 aee560b0 Christos Stavrakakis
                [job_fields.pop(f) for f in ("pnode", "snode")]
201 aee560b0 Christos Stavrakakis
            name = job_fields.pop("name", job_fields.pop("instance_name"))
202 aee560b0 Christos Stavrakakis
            # Turn off opportunistic locking before retrying the job
203 aee560b0 Christos Stavrakakis
            job_fields["opportunistic_locking"] = False
204 aee560b0 Christos Stavrakakis
            with pooled_rapi_client(vm) as c:
205 aee560b0 Christos Stavrakakis
                jobID = c.CreateInstance(name=name, **job_fields)
206 aee560b0 Christos Stavrakakis
            # Update the VM fields
207 aee560b0 Christos Stavrakakis
            vm.backendjobid = jobID
208 aee560b0 Christos Stavrakakis
            vm.backendjobstatus = None
209 aee560b0 Christos Stavrakakis
            vm.save()
210 aee560b0 Christos Stavrakakis
            log.info("Retrying failed creation of instance '%s' without"
211 aee560b0 Christos Stavrakakis
                     " opportunistic locking. New job ID: '%s'", name, jobID)
212 727fb2f9 Christos Stavrakakis
            return
213 727fb2f9 Christos Stavrakakis
214 727fb2f9 Christos Stavrakakis
    backend.process_op_status(vm, event_time, jobID, operation,
215 727fb2f9 Christos Stavrakakis
                              status, logmsg, nics)
216 c4e55622 Christos Stavrakakis
217 c4e55622 Christos Stavrakakis
    log.debug("Done processing ganeti-op-status msg for vm %s.",
218 c4e55622 Christos Stavrakakis
              msg['instance'])
219 c4e55622 Christos Stavrakakis
220 c4e55622 Christos Stavrakakis
221 a17a8e98 Christos Stavrakakis
@network_from_msg
222 a17a8e98 Christos Stavrakakis
@if_update_required
223 a17a8e98 Christos Stavrakakis
def update_network(network, msg, event_time):
224 a17a8e98 Christos Stavrakakis
    """Process a notification of type 'ganeti-network-status'"""
225 a17a8e98 Christos Stavrakakis
    log.debug("Processing ganeti-network-status msg: %s", msg)
226 a17a8e98 Christos Stavrakakis
227 a17a8e98 Christos Stavrakakis
    if msg['type'] != "ganeti-network-status":
228 a17a8e98 Christos Stavrakakis
        log.error("Message is of unknown type %s.", msg['type'])
229 a17a8e98 Christos Stavrakakis
        return
230 a17a8e98 Christos Stavrakakis
231 fd2bdbb2 Christos Stavrakakis
    opcode = msg['operation']
232 fd2bdbb2 Christos Stavrakakis
    status = msg['status']
233 fd2bdbb2 Christos Stavrakakis
    jobid = msg['jobId']
234 fd2bdbb2 Christos Stavrakakis
235 fd2bdbb2 Christos Stavrakakis
    if opcode == "OP_NETWORK_SET_PARAMS":
236 fd2bdbb2 Christos Stavrakakis
        backend.process_network_modify(network, event_time, jobid, opcode,
237 fd2bdbb2 Christos Stavrakakis
                                       status, msg['add_reserved_ips'],
238 fd2bdbb2 Christos Stavrakakis
                                       msg['remove_reserved_ips'])
239 fd2bdbb2 Christos Stavrakakis
    else:
240 fd2bdbb2 Christos Stavrakakis
        backend.process_network_status(network, event_time, jobid, opcode,
241 fd2bdbb2 Christos Stavrakakis
                                       status, msg['logmsg'])
242 a17a8e98 Christos Stavrakakis
243 22ee6892 Christos Stavrakakis
    log.debug("Done processing ganeti-network-status msg for network %s.",
244 22ee6892 Christos Stavrakakis
              msg['network'])
245 a17a8e98 Christos Stavrakakis
246 a17a8e98 Christos Stavrakakis
247 a17a8e98 Christos Stavrakakis
@instance_from_msg
248 a17a8e98 Christos Stavrakakis
@if_update_required
249 a17a8e98 Christos Stavrakakis
def update_build_progress(vm, msg, event_time):
250 6138f0ef Kostas Papadimitriou
    """
251 6138f0ef Kostas Papadimitriou
    Process a create progress message. Update build progress, or create
252 6138f0ef Kostas Papadimitriou
    appropriate diagnostic entries for the virtual machine instance.
253 6138f0ef Kostas Papadimitriou
    """
254 33b93f81 Christos Stavrakakis
    log.debug("Processing ganeti-create-progress msg: %s", msg)
255 604b2bf8 Georgios Gousios
256 a3b1aee2 Nikos Skalkotos
    if msg['type'] not in ('image-copy-progress', 'image-error', 'image-info',
257 a3b1aee2 Nikos Skalkotos
                           'image-warning', 'image-helper'):
258 c4e55622 Christos Stavrakakis
        log.error("Message is of unknown type %s", msg['type'])
259 c4e55622 Christos Stavrakakis
        return
260 c25cc9ec Vangelis Koukis
261 0827883e Nikos Skalkotos
    if msg['type'] == 'image-copy-progress':
262 0827883e Nikos Skalkotos
        backend.process_create_progress(vm, event_time, msg['progress'])
263 6138f0ef Kostas Papadimitriou
        # we do not add diagnostic messages for copy-progress messages
264 6138f0ef Kostas Papadimitriou
        return
265 6138f0ef Kostas Papadimitriou
266 6138f0ef Kostas Papadimitriou
    # default diagnostic fields
267 6138f0ef Kostas Papadimitriou
    source = msg['type']
268 6138f0ef Kostas Papadimitriou
    level = 'DEBUG'
269 f659cd15 Kostas Papadimitriou
    message = msg.get('messages', '')
270 6138f0ef Kostas Papadimitriou
    if isinstance(message, list):
271 6138f0ef Kostas Papadimitriou
        message = " ".join(message)
272 6138f0ef Kostas Papadimitriou
273 6138f0ef Kostas Papadimitriou
    details = msg.get('stderr', None)
274 6138f0ef Kostas Papadimitriou
275 6138f0ef Kostas Papadimitriou
    if msg['type'] == 'image-helper':
276 6138f0ef Kostas Papadimitriou
        # for helper task events join subtype to diagnostic source and
277 6138f0ef Kostas Papadimitriou
        # set task name as diagnostic message
278 cc92b70f Christos Stavrakakis
        if msg.get('subtype', None):
279 cc92b70f Christos Stavrakakis
            if msg.get('subtype') in ['task-start', 'task-end']:
280 cc92b70f Christos Stavrakakis
                message = msg.get('task', message)
281 cc92b70f Christos Stavrakakis
                source = "%s-%s" % (source, msg.get('subtype'))
282 6138f0ef Kostas Papadimitriou
283 6138f0ef Kostas Papadimitriou
        if msg.get('subtype', None) == 'warning':
284 6138f0ef Kostas Papadimitriou
            level = 'WARNING'
285 6138f0ef Kostas Papadimitriou
286 6138f0ef Kostas Papadimitriou
        if msg.get('subtype', None) == 'error':
287 6138f0ef Kostas Papadimitriou
            level = 'ERROR'
288 6138f0ef Kostas Papadimitriou
289 6138f0ef Kostas Papadimitriou
        if msg.get('subtype', None) == 'info':
290 6138f0ef Kostas Papadimitriou
            level = 'INFO'
291 6138f0ef Kostas Papadimitriou
292 6138f0ef Kostas Papadimitriou
    if msg['type'] == 'image-error':
293 6138f0ef Kostas Papadimitriou
        level = 'ERROR'
294 6138f0ef Kostas Papadimitriou
295 6138f0ef Kostas Papadimitriou
    if msg['type'] == 'image-warning':
296 6138f0ef Kostas Papadimitriou
        level = 'WARNING'
297 6138f0ef Kostas Papadimitriou
298 6138f0ef Kostas Papadimitriou
    if not message.strip():
299 6138f0ef Kostas Papadimitriou
        message = " ".join(source.split("-")).capitalize()
300 6138f0ef Kostas Papadimitriou
301 6138f0ef Kostas Papadimitriou
    # create the diagnostic entry
302 6138f0ef Kostas Papadimitriou
    backend.create_instance_diagnostic(vm, message, source, level, event_time,
303 cc92b70f Christos Stavrakakis
                                       details=details)
304 604b2bf8 Georgios Gousios
305 c4e55622 Christos Stavrakakis
    log.debug("Done processing ganeti-create-progress msg for vm %s.",
306 c4e55622 Christos Stavrakakis
              msg['instance'])
307 604b2bf8 Georgios Gousios
308 604b2bf8 Georgios Gousios
309 a17a8e98 Christos Stavrakakis
def dummy_proc(client, message, *args, **kwargs):
310 23c84263 Georgios Gousios
    try:
311 c4e55622 Christos Stavrakakis
        log.debug("Msg: %s", message['body'])
312 33b93f81 Christos Stavrakakis
        client.basic_ack(message)
313 23c84263 Georgios Gousios
    except Exception as e:
314 22ee6892 Christos Stavrakakis
        log.exception("Could not receive message %s" % e)