Revision f533f224 logic/backend.py

b/logic/backend.py
5 5
#
6 6

  
7 7
from django.conf import settings
8
from synnefo.db.models import VirtualMachine
8
from django.db import transaction
9

  
10
from synnefo.db.models import VirtualMachine, Network, NetworkLink
9 11
from synnefo.logic import utils
10 12
from synnefo.util.rapi import GanetiRapiClient
11 13

  
......
45 47
    vm.save()
46 48

  
47 49

  
50
@transaction.commit_on_success
48 51
def process_net_status(vm, nics):
49 52
    """Process a net status notification from the backend
50 53

  
......
52 55
    detailing the NIC configuration of a VM instance.
53 56

  
54 57
    Update the state of the VM in the DB accordingly.
55

  
56 58
    """
57

  
58
    # For the time being, we can only update the ipfour field,
59
    # based on the IPv4 address of the first NIC
60
    if len(nics) > 0:
61
        ipv4 = nics[0]['ip']
62
        if ipv4 == '':
63
            ipv4 = '0.0.0.0'
64
        vm.ipfour = ipv4
59
    
60
    vm.nics.all().delete()
61
    for i, nic in enumerate(nics):
62
        if i == 0:
63
            net = Network.objects.get(public=True)
64
        else:
65
            try:
66
                link = NetworkLink.objects.get(name=nic['link'])
67
            except NetworkLink.DoesNotExist:
68
                # Cannot find an instance of NetworkLink for
69
                # the link attribute specified in the notification
70
                raise NetworkLink.DoesNotExist("Cannot find a NetworkLink "
71
                    "object for link='%s'" % nic['link'])
72
            net = link.network
73
            if net is None:
74
                raise Network.DoesNotExist("NetworkLink for link='%s' not "
75
                    "associated with an existing Network instance." %
76
                    nic['link'])
77

  
78
        vm.nics.create(
79
            network=net,
80
            index=i,
81
            mac=nic.get('mac', ''),
82
            ipv4=nic.get('ip', ''))
65 83
    vm.save()
66 84

  
67 85

  
......
95 113

  
96 114

  
97 115
def create_instance(vm, flavor, image, password):
116
    
117
    nic = {'ip': 'pool', 'mode': 'routed', 'link': settings.GANETI_PUBLIC_LINK}
118
    
98 119
    return rapi.CreateInstance(
99 120
        mode='create',
100 121
        name=vm.backend_id,
101 122
        disk_template='plain',
102
        disks=[{"size": 4000}],         #FIXME: Always ask for a 4GB disk for now
103
        nics=[{}],
123
        disks=[{"size": 4000}],     #FIXME: Always ask for a 4GB disk for now
124
        nics=[nic],
104 125
        os='image+default',
105 126
        ip_check=False,
106 127
        name_check=False,
107
        pnode=rapi.GetNodes()[0],       #TODO: verify if this is necessary
128
        pnode=rapi.GetNodes()[0],   #TODO: use a Ganeti iallocator instead
108 129
        dry_run=settings.TEST,
109 130
        beparams=dict(auto_balance=True, vcpus=flavor.cpu, memory=flavor.ram),
110
        osparams=dict(img_id=image.backend_id, img_passwd=password, img_format=image.format))
131
        osparams=dict(img_id=image.backend_id, img_passwd=password,
132
                      img_format=image.format))
133

  
111 134

  
112 135
def delete_instance(vm):
113 136
    start_action(vm, 'DESTROY')
114
    rapi.DeleteInstance(vm.backend_id)
137
    rapi.DeleteInstance(vm.backend_id, dry_run=settings.TEST)
138
    vm.nics.all().delete()
115 139

  
116 140

  
117 141
def reboot_instance(vm, reboot_type):
118 142
    assert reboot_type in ('soft', 'hard')
119
    rapi.RebootInstance(vm.backend_id, reboot_type)
143
    rapi.RebootInstance(vm.backend_id, reboot_type, dry_run=settings.TEST)
120 144

  
121 145

  
122 146
def startup_instance(vm):
123 147
    start_action(vm, 'START')
124
    rapi.StartupInstance(vm.backend_id)
148
    rapi.StartupInstance(vm.backend_id, dry_run=settings.TEST)
125 149

  
126 150

  
127 151
def shutdown_instance(vm):
128 152
    start_action(vm, 'STOP')
129
    rapi.ShutdownInstance(vm.backend_id)
153
    rapi.ShutdownInstance(vm.backend_id, dry_run=settings.TEST)
130 154

  
131 155

  
132 156
def get_instance_console(vm):
......
143 167

  
144 168
def update_status(vm, status):
145 169
    utils.update_state(vm, status)
170

  
171
def create_network_link():
172
    try:
173
        last = NetworkLink.objects.order_by('-index')[0]
174
        index = last.index + 1
175
    except IndexError:
176
        index = 1
177
    
178
    if index <= settings.GANETI_MAX_LINK_NUMBER:
179
        name = '%s%d' % (settings.GANETI_LINK_PREFIX, index)
180
        return NetworkLink.objects.create(index=index, name=name,
181
                                          available=True)
182
    # FIXME: Shouldn't something at least be logged here?
183
    return None     # All link slots are filled
184

  
185

  
186
@transaction.commit_on_success
187
def create_network(name, owner):
188
    try:
189
        link = NetworkLink.objects.filter(available=True)[0]
190
    except IndexError:
191
        link = create_network_link()
192
        if not link:
193
            return None
194
    
195
    network = Network.objects.create(
196
        name=name,
197
        owner=owner,
198
        state='ACTIVE',
199
        link=link)
200
    
201
    link.network = network
202
    link.available = False
203
    link.save()
204
    
205
    return network
206

  
207

  
208
@transaction.commit_on_success
209
def delete_network(net):
210
    link = net.link
211
    if link.name != settings.GANETI_NULL_LINK:
212
        link.available = True
213
        link.network = None
214
        link.save()
215
    
216
    for vm in net.machines.all():
217
        disconnect_from_network(vm, net)
218
        vm.save()
219
    net.state = 'DELETED'
220
    net.save()
221

  
222

  
223
def connect_to_network(vm, net):
224
    nic = {'mode': 'bridged', 'link': net.link.name}
225
    rapi.ModifyInstance(vm.backend_id,
226
        nics=[('add', nic)],
227
        dry_run=settings.TEST)
228

  
229

  
230
def disconnect_from_network(vm, net):
231
    nics = vm.nics.filter(network__public=False).order_by('index')
232
    new_nics = [nic for nic in nics if nic.network != net]
233
    if new_nics == nics:
234
        return      # Nothing to remove
235
    ops = [('remove', {})]
236
    for i, nic in enumerate(new_nics):
237
        ops.append((i + 1, {
238
            'mode': 'bridged',
239
            'link': nic.network.link.name}))
240
    rapi.ModifyInstance(vm.backend_id, nics=ops, dry_run=settings.TEST)
241

  

Also available in: Unified diff