cc1  v2.1
CC1 source code docs
 All Classes Namespaces Files Functions Variables Pages
farm.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 # @COPYRIGHT_begin
3 #
4 # Copyright [2010-2014] Institute of Nuclear Physics PAN, Krakow, Poland
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #
18 # @COPYRIGHT_end
19 
20 ##
21 # @package src.cm.models.farm
22 #
23 
24 from datetime import datetime
25 
26 from django.db import models
27 
28 from cm.models.user import User
29 from cm.utils import log
30 from cm.utils.exception import CMException
31 from common.states import farm_states, vm_states
32 
33 
34 class Farm(models.Model):
35 
36  user = models.ForeignKey(User)
37  name = models.CharField(max_length=128)
38  description = models.TextField(null=True, blank=True)
39  state = models.IntegerField()
40  head = models.ForeignKey('VM', related_name='+')
41 
42  class Meta:
43  app_label = "cm"
44 
45  def __unicode__(self):
46  return self.name
47 
48  @property
49  def dict(self):
50  d = {}
51  d["farm_id"] = self.id
52  d["user_id"] = self.user.id
53  d["name"] = self.name
54  vms = list(self.vms.order_by('id'))
55  d["vms"] = [vm.dict for vm in vms]
56  d["state"] = self.state
57  d["start_time"] = vms[0].start_time
58  delta = datetime.now() - vms[0].start_time
59  d['uptime'] = delta.seconds + 24 * 3600 * delta.days
60  d["image_name"] = vms[0].system_image.name
61  d["head_template_name"] = vms[0].template.name if len(vms) > 0 else ''
62  d["template_name"] = vms[1].template.name if len(vms) > 1 else ''
63  d["cpu"] = sum([vm.template.cpu for vm in vms])
64  d["memory"] = sum([vm.template.memory for vm in vms])
65  return d
66 
67  @staticmethod
68  def get(user_id, farm_id):
69  try:
70  farm = Farm.objects.get(pk=farm_id)
71  except:
72  raise CMException('vm_get')
73 
74  if farm.user.id != user_id:
75  raise CMException('user_permission')
76 
77  return farm
78 
79  @staticmethod
80  def admin_get(farm_id):
81  try:
82  farm = Farm.objects.get(pk=farm_id)
83  except:
84  raise CMException('vm_get')
85 
86  return farm
87 
88  @staticmethod
89  def create(user, name, description):
90  farm = Farm()
91  farm.name = name
92  farm.user = user
93  farm.description = description
94  farm.state = farm_states['init']
95  return farm
96 
97  @staticmethod
98  ##
99  #
100  # Destroyes farms' VMs (Head and Worker Nodes of each farm) without saving them.
101  #
102  # @parameter{farms,list} list of farms to destroy
103  #
104  # @response{list(dict)} list of statuses returned by destroyed VMs
105  #
106  # @raises{farm_wrong_state,CMException}
107  # @raises{farm_destroy,CMException}
108  #
109  def destroy(farms):
110  from cm.models.vm import VM
111 
112  vm_resp = []
113  for farm in farms:
114  # those are states in which farm can not be destroyed
115  if farm.state in (farm_states['init'], farm_states['closing'], farm_states['closed']):
116  raise CMException('farm_wrong_state')
117 
118  for farm in farms:
119  # stop all threads
120  if farm.state == farm_states['init_head']:
121  for vm in farm.vms.all():
122  if vm.is_head():
123  continue
124  vm.release_resources()
125  vm.state = vm_states['closed']
126  vm.stop_time = datetime.now()
127  vm.save()
128  log.debug(vm.user.id, "vm state %s" % vm.state)
129  r = VM.destroy([farm.head])
130  else:
131  log.debug(farm.user_id, "killing wn: %s" % farm.vms)
132  r = VM.destroy(farm.vms.all())
133 
134  #if r['status'] != 'ok':
135  if True in [x['status'] != 'ok' for x in r]:
136  farm.state = farm_states['failed']
137  try:
138  farm.save()
139  except Exception:
140  raise CMException('farm_destroy')
141  vm_resp.append(r)
142 
143  farm.state = farm_states['closed']
144 
145  try:
146  farm.save()
147  except Exception:
148  raise CMException('farm_destroy')
149 
150  log.debug(farm.user_id, "session commited")
151  for vm in farm.vms.all():
152  log.debug(vm.user.id, "vm state %s" % vm.state)
153 
154  return vm_resp
155 
156  @staticmethod
157  ##
158  #
159  #
160  def save_and_shutdown(farm, name, description):
161  from cm.models.vm import VM
162 
163  if farm.state == farm_states['failed']:
164  raise CMException('farm_wrong_state')
165 
166  head_vm = farm.head
167  try:
168  #VM.save_and_shutdown(head_vm.user_id, head_vm, name, description)
169  head_vm.name = name
170  head_vm.description = description
171  head_vm.save_vm = 2
172  head_vm.save()
173  head_vm.save_image()
174  head_vm.release_resources()
175  head_vm.remove()
176  head_vm.state = vm_states['closed']
177  head_vm.save()
178  except Exception:
179  CMException('farm_save')
180 
181  node_vms = []
182  if farm.state == farm_states['init_head']:
183  for vm in farm.vms.all():
184  if vm.is_head():
185  continue
186  vm.release_resources()
187  vm.state = vm_states['closed']
188  else:
189  for vm in farm.vms.all():
190  node_vms.append(vm)
191  VM.destroy(node_vms)
192 
193  try:
194  farm.state = farm_states['closed']
195  farm.save()
196  except:
197  CMException('farm_save')
198 
199  def hosts(self):
200  hosts_list = []
201  host_id = 1
202  for vm in self.vms.all():
203  if vm.is_head():
204  # TODO: Change leases[0]
205  hosts_list.append({"ip": vm.lease_set.all()[0].vm_address, "host_name": "farm-head"})
206  else:
207  hosts_list.append({"ip": vm.lease_set.all()[0].vm_address, "host_name": vm.name.replace(vm.farm.name, 'farm')})
208  host_id += 1
209  return hosts_list
210