Revision 030eb609

b/snf-cyclades-app/synnefo/api/management/commands/server-create.py
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34
import json
34 35
from optparse import make_option
35 36

  
37
from django.db import transaction
36 38
from django.core.management.base import BaseCommand, CommandError
37 39
from synnefo.management import common
38 40

  
39 41
from synnefo.db.models import VirtualMachine
40 42
from synnefo.logic.backend import create_instance
41 43
from synnefo.logic.backend_allocator import BackendAllocator
42
from synnefo.api.util import allocate_public_address
44
from synnefo.api import util
45
from synnefo.api.servers import server_created
43 46

  
44 47
HELP_MSG = """
45 48

  
......
52 55
class Command(BaseCommand):
53 56
    help = "Create a new VM." + HELP_MSG
54 57

  
55
    output_transaction = True
56

  
57 58
    option_list = BaseCommand.option_list + (
58 59
            make_option("--backend-id", dest="backend_id",
59 60
                        help="Unique identifier of the Ganeti backend."
......
75 76
                        help="Password for the new server")
76 77
        )
77 78

  
79
    @transaction.commit_manually
78 80
    def handle(self, *args, **options):
79 81
        if args:
80 82
            raise CommandError("Command doesn't accept any arguments")
......
97 99
        if flavor_id:
98 100
            flavor = common.get_flavor(flavor_id)
99 101

  
100
        # Get Image
101 102
        if image_id:
102 103
            img = common.get_image(image_id, user_id)
103 104

  
......
110 111
        else:
111 112
            raise CommandError("image-id is mandatory")
112 113

  
113
        # Get Backend
114
        if backend_id:
115
            backend = common.get_backend(backend_id)
114
        # Fix flavor for archipelago
115
        disk_template, provider = util.get_flavor_provider(flavor)
116
        if provider:
117
            flavor.disk_template = disk_template
118
            flavor.disk_provider = provider
119
            flavor.disk_origin = None
120
            if provider == 'vlmc':
121
                flavor.disk_origin = image['checksum']
122
                image['backend_id'] = 'null'
123
        else:
124
            flavor.disk_provider = None
125

  
126
        try:
127
            # Get Backend
128
            if backend_id:
129
                backend = common.get_backend(backend_id)
130
            else:
131
                ballocator = BackendAllocator()
132
                backend = ballocator.allocate(user_id, flavor)
133
                if not backend:
134
                    raise CommandError("Can not allocate VM")
135

  
136
            # Get Public address
137
            (network, address) = util.allocate_public_address(backend)
138
            if address is None:
139
                raise CommandError("Can not allocate a public address."\
140
                                   " No available public network.")
141
            nic = {'ip': address, 'network': network.backend_id}
142

  
143
            # Create the VM in DB
144
            vm = VirtualMachine.objects.create(name=name,
145
                                               backend=backend,
146
                                               userid=user_id,
147
                                               imageid=image_id,
148
                                               flavor=flavor)
149
            # dispatch server created signal
150
            server_created.send(sender=vm, created_vm_params={
151
                'img_id': image['backend_id'],
152
                'img_passwd': password,
153
                'img_format': str(image['format']),
154
                'img_personality': '[]',
155
                'img_properties': json.dumps(image['metadata']),
156
            })
157
        except:
158
            transaction.rollback()
159
            raise
160
        else:
161
            transaction.commit()
162

  
163
        try:
164
            # Create the instance in Backend
165
            jobID = create_instance(vm, nic, flavor, image, password)
166

  
167
            vm.backendjobid = jobID
168
            vm.save()
169
            self.stdout.write("Creating VM %s with IP %s in Backend %s."
170
                              " JobID: %s\n" % (vm, address, backend, jobID))
171
        except:
172
            transaction.rollback()
173
            raise
116 174
        else:
117
            ballocator = BackendAllocator()
118
            backend = ballocator.allocate(user_id, flavor)
119
            if not backend:
120
                raise CommandError("Can not allocate VM")
121

  
122
        # Get Public address
123
        (network, address) = allocate_public_address(backend)
124
        if address is None:
125
            raise CommandError("Can not allocate a public address."\
126
                               " No available public network.")
127
        nic = {'ip': address, 'network': network.backend_id}
128

  
129
        # Create the VM in DB
130
        vm = VirtualMachine.objects.create(name=name,
131
                                           backend=backend,
132
                                           userid=user_id,
133
                                           imageid=image_id,
134
                                           flavor=flavor)
135

  
136
        # Create the instance in Backend
137
        jobID = create_instance(vm, nic, flavor, image, password, [])
138

  
139
        self.stdout.write("Creating VM %s with IP %s in Backend %s. JobID: %s\n" % \
140
                          (vm, address, backend, jobID))
175
            transaction.commit()

Also available in: Unified diff