Statistics
| Branch: | Tag: | Revision:

root / logic / backend.py @ 1c382247

History | View | Annotate | Download (11.9 kB)

1 adee02b8 Giorgos Verigakis
# Copyright 2011 GRNET S.A. All rights reserved.
2 37ca953f Christodoulos Psaltis
#
3 adee02b8 Giorgos Verigakis
# Redistribution and use in source and binary forms, with or
4 adee02b8 Giorgos Verigakis
# without modification, are permitted provided that the following
5 adee02b8 Giorgos Verigakis
# conditions are met:
6 37ca953f Christodoulos Psaltis
#
7 adee02b8 Giorgos Verigakis
#   1. Redistributions of source code must retain the above
8 adee02b8 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
9 adee02b8 Giorgos Verigakis
#      disclaimer.
10 37ca953f Christodoulos Psaltis
#
11 adee02b8 Giorgos Verigakis
#   2. Redistributions in binary form must reproduce the above
12 adee02b8 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
13 adee02b8 Giorgos Verigakis
#      disclaimer in the documentation and/or other materials
14 adee02b8 Giorgos Verigakis
#      provided with the distribution.
15 37ca953f Christodoulos Psaltis
#
16 adee02b8 Giorgos Verigakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 adee02b8 Giorgos Verigakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 adee02b8 Giorgos Verigakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 adee02b8 Giorgos Verigakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 adee02b8 Giorgos Verigakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 adee02b8 Giorgos Verigakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 adee02b8 Giorgos Verigakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 adee02b8 Giorgos Verigakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 adee02b8 Giorgos Verigakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 adee02b8 Giorgos Verigakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 adee02b8 Giorgos Verigakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 adee02b8 Giorgos Verigakis
# POSSIBILITY OF SUCH DAMAGE.
28 37ca953f Christodoulos Psaltis
#
29 adee02b8 Giorgos Verigakis
# The views and conclusions contained in the software and
30 adee02b8 Giorgos Verigakis
# documentation are those of the authors and should not be
31 adee02b8 Giorgos Verigakis
# interpreted as representing official policies, either expressed
32 adee02b8 Giorgos Verigakis
# or implied, of GRNET S.A.
33 02feca11 Vassilios Karakoidas
34 529178b1 Giorgos Verigakis
from django.conf import settings
35 207b70d5 Giorgos Verigakis
from django.db import transaction
36 207b70d5 Giorgos Verigakis
37 adee02b8 Giorgos Verigakis
from synnefo.db.models import (VirtualMachine, Network, NetworkInterface,
38 adee02b8 Giorgos Verigakis
                                NetworkLink)
39 234f8b07 Vangelis Koukis
from synnefo.logic import utils
40 529178b1 Giorgos Verigakis
from synnefo.util.rapi import GanetiRapiClient
41 529178b1 Giorgos Verigakis
42 529178b1 Giorgos Verigakis
43 529178b1 Giorgos Verigakis
rapi = GanetiRapiClient(*settings.GANETI_CLUSTER_INFO)
44 529178b1 Giorgos Verigakis
45 efff6193 Giorgos Verigakis
_firewall_tags = {
46 efff6193 Giorgos Verigakis
    'ENABLED': settings.GANETI_FIREWALL_ENABLED_TAG,
47 efff6193 Giorgos Verigakis
    'DISABLED': settings.GANETI_FIREWALL_DISABLED_TAG,
48 efff6193 Giorgos Verigakis
    'PROTECTED': settings.GANETI_FIREWALL_PROTECTED_TAG}
49 efff6193 Giorgos Verigakis
50 efff6193 Giorgos Verigakis
_reverse_tags = dict((v.split(':')[3], k) for k, v in _firewall_tags.items())
51 efff6193 Giorgos Verigakis
52 02feca11 Vassilios Karakoidas
53 093f9c53 Vangelis Koukis
@transaction.commit_on_success
54 ad2d6807 Vangelis Koukis
def process_op_status(vm, jobid, opcode, status, logmsg):
55 ad2d6807 Vangelis Koukis
    """Process a job progress notification from the backend
56 02feca11 Vassilios Karakoidas

57 02feca11 Vassilios Karakoidas
    Process an incoming message from the backend (currently Ganeti).
58 02feca11 Vassilios Karakoidas
    Job notifications with a terminating status (sucess, error, or canceled),
59 02feca11 Vassilios Karakoidas
    also update the operating state of the VM.
60 02feca11 Vassilios Karakoidas

61 02feca11 Vassilios Karakoidas
    """
62 02feca11 Vassilios Karakoidas
    if (opcode not in [x[0] for x in VirtualMachine.BACKEND_OPCODES] or
63 02feca11 Vassilios Karakoidas
       status not in [x[0] for x in VirtualMachine.BACKEND_STATUSES]):
64 02feca11 Vassilios Karakoidas
        raise VirtualMachine.InvalidBackendMsgError(opcode, status)
65 02feca11 Vassilios Karakoidas
66 dfd19c2d Vassilios Karakoidas
    vm.backendjobid = jobid
67 dfd19c2d Vassilios Karakoidas
    vm.backendjobstatus = status
68 dfd19c2d Vassilios Karakoidas
    vm.backendopcode = opcode
69 dfd19c2d Vassilios Karakoidas
    vm.backendlogmsg = logmsg
70 02feca11 Vassilios Karakoidas
71 02feca11 Vassilios Karakoidas
    # Notifications of success change the operating state
72 ac63eb4f Vangelis Koukis
    if status == 'success' and VirtualMachine.OPER_STATE_FROM_OPCODE[opcode] is not None:
73 234f8b07 Vangelis Koukis
        utils.update_state(vm, VirtualMachine.OPER_STATE_FROM_OPCODE[opcode])
74 685b219e Vangelis Koukis
        # Set the deleted flag explicitly, to cater for admin-initiated removals
75 685b219e Vangelis Koukis
        if opcode == 'OP_INSTANCE_REMOVE':
76 685b219e Vangelis Koukis
            vm.deleted = True
77 685b219e Vangelis Koukis
78 685b219e Vangelis Koukis
    # Special case: if OP_INSTANCE_CREATE fails --> ERROR
79 02feca11 Vassilios Karakoidas
    if status in ('canceled', 'error') and opcode == 'OP_INSTANCE_CREATE':
80 234f8b07 Vangelis Koukis
        utils.update_state(vm, 'ERROR')
81 093f9c53 Vangelis Koukis
82 093f9c53 Vangelis Koukis
    # Special case: OP_INSTANCE_REMOVE fails for machines in ERROR,
83 093f9c53 Vangelis Koukis
    # when no instance exists at the Ganeti backend.
84 093f9c53 Vangelis Koukis
    # See ticket #799 for all the details.
85 093f9c53 Vangelis Koukis
    #
86 093f9c53 Vangelis Koukis
    if (status == 'error' and opcode == 'OP_INSTANCE_REMOVE' and
87 093f9c53 Vangelis Koukis
        vm.operstate == 'ERROR'):
88 093f9c53 Vangelis Koukis
        vm.deleted = True
89 093f9c53 Vangelis Koukis
90 02feca11 Vassilios Karakoidas
    # Any other notification of failure leaves the operating state unchanged
91 02feca11 Vassilios Karakoidas
92 02feca11 Vassilios Karakoidas
    vm.save()
93 22e52ede Vassilios Karakoidas
94 ad2d6807 Vangelis Koukis
95 207b70d5 Giorgos Verigakis
@transaction.commit_on_success
96 ad2d6807 Vangelis Koukis
def process_net_status(vm, nics):
97 ad2d6807 Vangelis Koukis
    """Process a net status notification from the backend
98 ad2d6807 Vangelis Koukis

99 ad2d6807 Vangelis Koukis
    Process an incoming message from the Ganeti backend,
100 ad2d6807 Vangelis Koukis
    detailing the NIC configuration of a VM instance.
101 ad2d6807 Vangelis Koukis

102 ad2d6807 Vangelis Koukis
    Update the state of the VM in the DB accordingly.
103 ad2d6807 Vangelis Koukis
    """
104 37ca953f Christodoulos Psaltis
105 64938cb0 Giorgos Verigakis
    vm.nics.all().delete()
106 64938cb0 Giorgos Verigakis
    for i, nic in enumerate(nics):
107 64938cb0 Giorgos Verigakis
        if i == 0:
108 ca792e04 Giorgos Verigakis
            net = Network.objects.get(public=True)
109 64938cb0 Giorgos Verigakis
        else:
110 a1dccf43 Vangelis Koukis
            try:
111 a1dccf43 Vangelis Koukis
                link = NetworkLink.objects.get(name=nic['link'])
112 a1dccf43 Vangelis Koukis
            except NetworkLink.DoesNotExist:
113 a1dccf43 Vangelis Koukis
                # Cannot find an instance of NetworkLink for
114 a1dccf43 Vangelis Koukis
                # the link attribute specified in the notification
115 a1dccf43 Vangelis Koukis
                raise NetworkLink.DoesNotExist("Cannot find a NetworkLink "
116 a1dccf43 Vangelis Koukis
                    "object for link='%s'" % nic['link'])
117 64938cb0 Giorgos Verigakis
            net = link.network
118 a1dccf43 Vangelis Koukis
            if net is None:
119 a1dccf43 Vangelis Koukis
                raise Network.DoesNotExist("NetworkLink for link='%s' not "
120 a1dccf43 Vangelis Koukis
                    "associated with an existing Network instance." %
121 a1dccf43 Vangelis Koukis
                    nic['link'])
122 d1387ed7 Christodoulos Psaltis
    
123 658a825a Giorgos Verigakis
        firewall = nic.get('firewall', '')
124 658a825a Giorgos Verigakis
        firewall_profile = _reverse_tags.get(firewall, '')
125 658a825a Giorgos Verigakis
        if not firewall_profile and net.public:
126 658a825a Giorgos Verigakis
            firewall_profile = settings.DEFAULT_FIREWALL_PROFILE
127 d1387ed7 Christodoulos Psaltis
    
128 64938cb0 Giorgos Verigakis
        vm.nics.create(
129 64938cb0 Giorgos Verigakis
            network=net,
130 64938cb0 Giorgos Verigakis
            index=i,
131 64938cb0 Giorgos Verigakis
            mac=nic.get('mac', ''),
132 746c6bf4 Vangelis Koukis
            ipv4=nic.get('ip', ''),
133 efff6193 Giorgos Verigakis
            ipv6=nic.get('ipv6',''),
134 efff6193 Giorgos Verigakis
            firewall_profile=firewall_profile)
135 ad2d6807 Vangelis Koukis
    vm.save()
136 ad2d6807 Vangelis Koukis
137 ad2d6807 Vangelis Koukis
138 22e52ede Vassilios Karakoidas
def start_action(vm, action):
139 22e52ede Vassilios Karakoidas
    """Update the state of a VM when a new action is initiated."""
140 22e52ede Vassilios Karakoidas
    if not action in [x[0] for x in VirtualMachine.ACTIONS]:
141 22e52ede Vassilios Karakoidas
        raise VirtualMachine.InvalidActionError(action)
142 22e52ede Vassilios Karakoidas
143 22e52ede Vassilios Karakoidas
    # No actions to deleted and no actions beside destroy to suspended VMs
144 22e52ede Vassilios Karakoidas
    if vm.deleted:
145 5231a38a Giorgos Verigakis
        raise VirtualMachine.DeletedError
146 37ca953f Christodoulos Psaltis
147 30f3b5e5 Vangelis Koukis
    # No actions to machines being built. They may be destroyed, however.
148 30f3b5e5 Vangelis Koukis
    if vm.operstate == 'BUILD' and action != 'DESTROY':
149 5231a38a Giorgos Verigakis
        raise VirtualMachine.BuildingError
150 37ca953f Christodoulos Psaltis
151 dfd19c2d Vassilios Karakoidas
    vm.action = action
152 dfd19c2d Vassilios Karakoidas
    vm.backendjobid = None
153 dfd19c2d Vassilios Karakoidas
    vm.backendopcode = None
154 dfd19c2d Vassilios Karakoidas
    vm.backendjobstatus = None
155 dfd19c2d Vassilios Karakoidas
    vm.backendlogmsg = None
156 22e52ede Vassilios Karakoidas
157 f90c3d8c Vangelis Koukis
    # Update the relevant flags if the VM is being suspended or destroyed.
158 f90c3d8c Vangelis Koukis
    # Do not set the deleted flag here, see ticket #721.
159 f90c3d8c Vangelis Koukis
    #
160 f90c3d8c Vangelis Koukis
    # The deleted flag is set asynchronously, when an OP_INSTANCE_REMOVE
161 f90c3d8c Vangelis Koukis
    # completes successfully. Hence, a server may be visible for some time
162 f90c3d8c Vangelis Koukis
    # after a DELETE /servers/id returns HTTP 204.
163 f90c3d8c Vangelis Koukis
    #
164 22e52ede Vassilios Karakoidas
    if action == "DESTROY":
165 f90c3d8c Vangelis Koukis
        # vm.deleted = True
166 f90c3d8c Vangelis Koukis
        pass
167 22e52ede Vassilios Karakoidas
    elif action == "SUSPEND":
168 22e52ede Vassilios Karakoidas
        vm.suspended = True
169 22e52ede Vassilios Karakoidas
    elif action == "START":
170 22e52ede Vassilios Karakoidas
        vm.suspended = False
171 22e52ede Vassilios Karakoidas
    vm.save()
172 529178b1 Giorgos Verigakis
173 ad2d6807 Vangelis Koukis
174 1ef58e5b Constantinos Venetsanopoulos
def create_instance(vm, flavor, image, password):
175 37ca953f Christodoulos Psaltis
176 64938cb0 Giorgos Verigakis
    nic = {'ip': 'pool', 'mode': 'routed', 'link': settings.GANETI_PUBLIC_LINK}
177 61868190 Vangelis Koukis
178 61868190 Vangelis Koukis
    if settings.IGNORE_FLAVOR_DISK_SIZES:
179 61868190 Vangelis Koukis
        if image.backend_id.find("windows") >= 0:
180 61868190 Vangelis Koukis
            sz = 14000
181 61868190 Vangelis Koukis
        else:
182 61868190 Vangelis Koukis
            sz = 4000
183 cf0e4232 Vangelis Koukis
    else:
184 61868190 Vangelis Koukis
        sz = flavor.disk * 1024
185 37ca953f Christodoulos Psaltis
186 1c382247 Vangelis Koukis
    # Handle arguments to CreateInstance() as a dictionary,
187 1c382247 Vangelis Koukis
    # initialize it based on a deployment-specific value.
188 1c382247 Vangelis Koukis
    # This enables the administrator to override deployment-specific
189 1c382247 Vangelis Koukis
    # arguments, such as the disk templatei to use, name of os provider
190 1c382247 Vangelis Koukis
    # and hypervisor-specific parameters at will (see Synnefo #785, #835).
191 1c382247 Vangelis Koukis
    #
192 1c382247 Vangelis Koukis
    kw = settings.GANETI_CREATEINSTANCE_KWARGS
193 1c382247 Vangelis Koukis
    kw['mode'] = 'create'
194 1c382247 Vangelis Koukis
    kw['name'] = vm.backend_id
195 1c382247 Vangelis Koukis
    # Defined in settings.GANETI_CREATE_INSTANCE_KWARGS
196 1c382247 Vangelis Koukis
    # kw['disk_template'] = settings.GANETI_DISK_TEMPLATE
197 1c382247 Vangelis Koukis
    kw['disks'] = [{"size": sz}]
198 1c382247 Vangelis Koukis
    kw['nics'] = [nic]
199 1c382247 Vangelis Koukis
    # Defined in settings.GANETI_CREATE_INSTANCE_KWARGS
200 1c382247 Vangelis Koukis
    # kw['os'] = settings.GANETI_OS_PROVIDER
201 1c382247 Vangelis Koukis
    kw['ip_check'] = False
202 1c382247 Vangelis Koukis
    kw['name_check'] = False
203 1c382247 Vangelis Koukis
    # Do not specific a node explicitly, have
204 1c382247 Vangelis Koukis
    # Ganeti use an iallocator instead
205 1c382247 Vangelis Koukis
    #
206 1c382247 Vangelis Koukis
    # kw['pnode']=rapi.GetNodes()[0]
207 1c382247 Vangelis Koukis
    kw['dry_run'] = settings.TEST
208 1c382247 Vangelis Koukis
    kw['beparams'] = dict(auto_balance=True, vcpus=flavor.cpu,
209 1c382247 Vangelis Koukis
                          memory=flavor.ram)
210 1c382247 Vangelis Koukis
    kw['osparams'] = dict(img_id=image.backend_id, img_passwd=password,
211 1c382247 Vangelis Koukis
                         img_format=image.format)
212 1c382247 Vangelis Koukis
    # Defined in settings.GANETI_CREATE_INSTANCE_KWARGS
213 1c382247 Vangelis Koukis
    # kw['hvparams'] = dict(serial_console=False)
214 1c382247 Vangelis Koukis
215 1c382247 Vangelis Koukis
    return rapi.CreateInstance(**kw)
216 f533f224 Vangelis Koukis
217 529178b1 Giorgos Verigakis
218 529178b1 Giorgos Verigakis
def delete_instance(vm):
219 529178b1 Giorgos Verigakis
    start_action(vm, 'DESTROY')
220 64938cb0 Giorgos Verigakis
    rapi.DeleteInstance(vm.backend_id, dry_run=settings.TEST)
221 d44c236b Giorgos Verigakis
    vm.nics.all().delete()
222 529178b1 Giorgos Verigakis
223 ad2d6807 Vangelis Koukis
224 529178b1 Giorgos Verigakis
def reboot_instance(vm, reboot_type):
225 529178b1 Giorgos Verigakis
    assert reboot_type in ('soft', 'hard')
226 64938cb0 Giorgos Verigakis
    rapi.RebootInstance(vm.backend_id, reboot_type, dry_run=settings.TEST)
227 529178b1 Giorgos Verigakis
228 ad2d6807 Vangelis Koukis
229 529178b1 Giorgos Verigakis
def startup_instance(vm):
230 529178b1 Giorgos Verigakis
    start_action(vm, 'START')
231 64938cb0 Giorgos Verigakis
    rapi.StartupInstance(vm.backend_id, dry_run=settings.TEST)
232 529178b1 Giorgos Verigakis
233 ad2d6807 Vangelis Koukis
234 529178b1 Giorgos Verigakis
def shutdown_instance(vm):
235 529178b1 Giorgos Verigakis
    start_action(vm, 'STOP')
236 64938cb0 Giorgos Verigakis
    rapi.ShutdownInstance(vm.backend_id, dry_run=settings.TEST)
237 529178b1 Giorgos Verigakis
238 ad2d6807 Vangelis Koukis
239 529178b1 Giorgos Verigakis
def get_instance_console(vm):
240 71099804 Vangelis Koukis
    # RAPI GetInstanceConsole() returns endpoints to the vnc_bind_address,
241 71099804 Vangelis Koukis
    # which is a cluster-wide setting, either 0.0.0.0 or 127.0.0.1, and pretty
242 71099804 Vangelis Koukis
    # useless (see #783).
243 71099804 Vangelis Koukis
    #
244 71099804 Vangelis Koukis
    # Until this is fixed on the Ganeti side, construct a console info reply
245 71099804 Vangelis Koukis
    # directly.
246 71099804 Vangelis Koukis
    # 
247 71099804 Vangelis Koukis
    # WARNING: This assumes that VNC runs on port network_port on
248 71099804 Vangelis Koukis
    #          the instance's primary node, and is probably
249 71099804 Vangelis Koukis
    #          hypervisor-specific.
250 71099804 Vangelis Koukis
    #
251 71099804 Vangelis Koukis
    console = {}
252 71099804 Vangelis Koukis
    console['kind'] = 'vnc'
253 71099804 Vangelis Koukis
    i = rapi.GetInstance(vm.backend_id)
254 71099804 Vangelis Koukis
    if i['hvparams']['serial_console']:
255 71099804 Vangelis Koukis
        raise Exception("hv parameter serial_console cannot be true")
256 71099804 Vangelis Koukis
    console['host'] = i['pnode']
257 71099804 Vangelis Koukis
    console['port'] = i['network_port']
258 71099804 Vangelis Koukis
    
259 71099804 Vangelis Koukis
    return console
260 71099804 Vangelis Koukis
    # return rapi.GetInstanceConsole(vm.backend_id)
261 64938cb0 Giorgos Verigakis
262 604b2bf8 Georgios Gousios
def request_status_update(vm):
263 604b2bf8 Georgios Gousios
    return rapi.GetInstanceInfo(vm.backend_id)
264 604b2bf8 Georgios Gousios
265 604b2bf8 Georgios Gousios
266 604b2bf8 Georgios Gousios
def get_job_status(jobid):
267 604b2bf8 Georgios Gousios
    return rapi.GetJobStatus(jobid)
268 604b2bf8 Georgios Gousios
269 604b2bf8 Georgios Gousios
270 604b2bf8 Georgios Gousios
def update_status(vm, status):
271 db7a3230 Vangelis Koukis
    utils.update_state(vm, status)
272 f533f224 Vangelis Koukis
273 64938cb0 Giorgos Verigakis
def create_network_link():
274 64938cb0 Giorgos Verigakis
    try:
275 64938cb0 Giorgos Verigakis
        last = NetworkLink.objects.order_by('-index')[0]
276 64938cb0 Giorgos Verigakis
        index = last.index + 1
277 64938cb0 Giorgos Verigakis
    except IndexError:
278 64938cb0 Giorgos Verigakis
        index = 1
279 37ca953f Christodoulos Psaltis
280 64938cb0 Giorgos Verigakis
    if index <= settings.GANETI_MAX_LINK_NUMBER:
281 64938cb0 Giorgos Verigakis
        name = '%s%d' % (settings.GANETI_LINK_PREFIX, index)
282 f533f224 Vangelis Koukis
        return NetworkLink.objects.create(index=index, name=name,
283 a191bd4d Giorgos Verigakis
                                            available=True)
284 64938cb0 Giorgos Verigakis
    return None     # All link slots are filled
285 64938cb0 Giorgos Verigakis
286 207b70d5 Giorgos Verigakis
@transaction.commit_on_success
287 a3992827 Giorgos Verigakis
def create_network(name, owner):
288 64938cb0 Giorgos Verigakis
    try:
289 64938cb0 Giorgos Verigakis
        link = NetworkLink.objects.filter(available=True)[0]
290 64938cb0 Giorgos Verigakis
    except IndexError:
291 64938cb0 Giorgos Verigakis
        link = create_network_link()
292 64938cb0 Giorgos Verigakis
        if not link:
293 a3992827 Giorgos Verigakis
            return None
294 37ca953f Christodoulos Psaltis
295 a3992827 Giorgos Verigakis
    network = Network.objects.create(
296 a3992827 Giorgos Verigakis
        name=name,
297 a3992827 Giorgos Verigakis
        owner=owner,
298 a3992827 Giorgos Verigakis
        state='ACTIVE',
299 a3992827 Giorgos Verigakis
        link=link)
300 37ca953f Christodoulos Psaltis
301 a3992827 Giorgos Verigakis
    link.network = network
302 64938cb0 Giorgos Verigakis
    link.available = False
303 64938cb0 Giorgos Verigakis
    link.save()
304 37ca953f Christodoulos Psaltis
305 a3992827 Giorgos Verigakis
    return network
306 64938cb0 Giorgos Verigakis
307 207b70d5 Giorgos Verigakis
@transaction.commit_on_success
308 64938cb0 Giorgos Verigakis
def delete_network(net):
309 64938cb0 Giorgos Verigakis
    link = net.link
310 06a16b24 Giorgos Verigakis
    if link.name != settings.GANETI_NULL_LINK:
311 06a16b24 Giorgos Verigakis
        link.available = True
312 06a16b24 Giorgos Verigakis
        link.network = None
313 06a16b24 Giorgos Verigakis
        link.save()
314 37ca953f Christodoulos Psaltis
315 64938cb0 Giorgos Verigakis
    for vm in net.machines.all():
316 64938cb0 Giorgos Verigakis
        disconnect_from_network(vm, net)
317 64938cb0 Giorgos Verigakis
        vm.save()
318 64938cb0 Giorgos Verigakis
    net.state = 'DELETED'
319 64938cb0 Giorgos Verigakis
    net.save()
320 64938cb0 Giorgos Verigakis
321 64938cb0 Giorgos Verigakis
def connect_to_network(vm, net):
322 64938cb0 Giorgos Verigakis
    nic = {'mode': 'bridged', 'link': net.link.name}
323 ca792e04 Giorgos Verigakis
    rapi.ModifyInstance(vm.backend_id,
324 ca792e04 Giorgos Verigakis
        nics=[('add', nic)],
325 ca792e04 Giorgos Verigakis
        dry_run=settings.TEST)
326 64938cb0 Giorgos Verigakis
327 64938cb0 Giorgos Verigakis
def disconnect_from_network(vm, net):
328 ca792e04 Giorgos Verigakis
    nics = vm.nics.filter(network__public=False).order_by('index')
329 ca792e04 Giorgos Verigakis
    new_nics = [nic for nic in nics if nic.network != net]
330 ca792e04 Giorgos Verigakis
    if new_nics == nics:
331 ca792e04 Giorgos Verigakis
        return      # Nothing to remove
332 ca792e04 Giorgos Verigakis
    ops = [('remove', {})]
333 ca792e04 Giorgos Verigakis
    for i, nic in enumerate(new_nics):
334 ca792e04 Giorgos Verigakis
        ops.append((i + 1, {
335 64938cb0 Giorgos Verigakis
            'mode': 'bridged',
336 ca792e04 Giorgos Verigakis
            'link': nic.network.link.name}))
337 ca792e04 Giorgos Verigakis
    rapi.ModifyInstance(vm.backend_id, nics=ops, dry_run=settings.TEST)
338 91826390 Giorgos Verigakis
339 91826390 Giorgos Verigakis
def set_firewall_profile(vm, profile):
340 26563957 Giorgos Verigakis
    try:
341 26563957 Giorgos Verigakis
        tag = _firewall_tags[profile]
342 26563957 Giorgos Verigakis
    except KeyError:
343 91826390 Giorgos Verigakis
        raise ValueError("Unsopported Firewall Profile: %s" % profile)
344 37ca953f Christodoulos Psaltis
345 26563957 Giorgos Verigakis
    # Delete all firewall tags
346 efff6193 Giorgos Verigakis
    for t in _firewall_tags.values():
347 efff6193 Giorgos Verigakis
        rapi.DeleteInstanceTags(vm.backend_id, [t], dry_run=settings.TEST)
348 37ca953f Christodoulos Psaltis
349 26563957 Giorgos Verigakis
    rapi.AddInstanceTags(vm.backend_id, [tag], dry_run=settings.TEST)
350 2da5f785 Giorgos Verigakis
    
351 2da5f785 Giorgos Verigakis
    # XXX NOP ModifyInstance call to force process_net_status to run
352 2da5f785 Giorgos Verigakis
    # on the dispatcher
353 2da5f785 Giorgos Verigakis
    rapi.ModifyInstance(vm.backend_id, os_name=settings.GANETI_OS_PROVIDER)