Revision 8e67ea28 snf-cyclades-app/synnefo/logic/servers.py

b/snf-cyclades-app/synnefo/logic/servers.py
1 1
import logging
2
import datetime
2 3

  
3 4
from socket import getfqdn
4 5
from functools import wraps
......
12 13
from synnefo.api import util
13 14
from synnefo.logic import backend
14 15
from synnefo.logic.backend_allocator import BackendAllocator
15
from synnefo.logic.rapi import GanetiApiError
16 16
from synnefo.db.models import (NetworkInterface, VirtualMachine, Network,
17 17
                               VirtualMachineMetadata, FloatingIP)
18 18

  
......
177 177

  
178 178
        log.info("Created entry in DB for VM '%s'", vm)
179 179

  
180
        # dispatch server created signal
181
        server_created.send(sender=vm, created_vm_params={
182
            'img_id': image['backend_id'],
183
            'img_passwd': password,
184
            'img_format': str(image['format']),
185
            'img_personality': json.dumps(personality),
186
            'img_properties': json.dumps(image['metadata']),
187
        })
188

  
189 180
        nics = create_instance_nics(vm, userid, private_networks, floating_ips)
190 181

  
191 182
        # Also we must create the VM metadata in the same transaction.
......
204 195
    else:
205 196
        transaction.commit()
206 197

  
198
    jobID = None
207 199
    try:
200
        vm = VirtualMachine.objects.select_for_update().get(id=vm.id)
201
        # dispatch server created signal needed to trigger the 'vmapi', which
202
        # enriches the vm object with the 'config_url' attribute which must be
203
        # passed to the Ganeti job.
204
        server_created.send(sender=vm, created_vm_params={
205
            'img_id': image['backend_id'],
206
            'img_passwd': password,
207
            'img_format': str(image['format']),
208
            'img_personality': json.dumps(personality),
209
            'img_properties': json.dumps(image['metadata']),
210
        })
211

  
208 212
        jobID = backend.create_instance(vm, nics, flavor, image)
209 213
        # At this point the job is enqueued in the Ganeti backend
210 214
        vm.backendjobid = jobID
......
214 218
        transaction.commit()
215 219
        log.info("User %s created VM %s, NICs %s, Backend %s, JobID %s",
216 220
                 userid, vm, nics, backend, str(jobID))
217
    except GanetiApiError as e:
218
        log.exception("Can not communicate to backend %s: %s.",
219
                      backend, e)
220
        # Failed while enqueuing OP_INSTANCE_CREATE to backend. Restore
221
        # already reserved quotas by issuing a negative commission
222
        vm.operstate = "ERROR"
223
        vm.backendlogmsg = "Can not communicate to backend."
224
        vm.deleted = True
225
        vm.save()
226
        quotas.issue_and_accept_commission(vm, delete=True)
227
        raise
228 221
    except:
229
        transaction.rollback()
222
        # If an exception is raised, then the user will never get the VM id.
223
        # In order to delete it from DB and release it's resources, we
224
        # mock a successful OP_INSTANCE_REMOVE job.
225
        backend.process_op_status(vm=vm, etime=datetime.datetime.now(),
226
                                  jobid=-0,
227
                                  opcode="OP_INSTANCE_REMOVE",
228
                                  status="success",
229
                                  logmsg="Reconciled eventd: VM creation"
230
                                         " failed.")
230 231
        raise
231 232

  
232 233
    return vm

Also available in: Unified diff