Fixed latency in flavor populating
[snf-occi] / snfOCCI / compute.py
1 from snfOCCI.config import SERVER_CONFIG
2
3 from kamaki.clients.compute import ComputeClient
4 from kamaki.clients.cyclades import CycladesClient
5 from kamaki.config  import Config
6
7 from occi.backend import ActionBackend, KindBackend
8 from occi.extensions.infrastructure import COMPUTE, START, STOP, SUSPEND, RESTART
9
10
11 #Compute Backend for snf-occi-server
12
13 class MyBackend(KindBackend, ActionBackend):
14     '''
15     An very simple abstract backend which handles update and replace for
16     attributes. Support for links and mixins would need to added.
17     '''
18
19     # Update and Replace compute instances not supported by Cyclades
20
21     def update(self, old, new, extras):
22         raise AttributeError("This action is currently no applicable.")
23
24     def replace(self, old, new, extras):
25         raise AttributeError("This action is currently no applicable.")
26
27
28 class ComputeBackend(MyBackend):
29     '''
30     Backend for Cyclades/Openstack compute instances
31     '''
32
33     def create(self, entity, extras):
34     
35         for mixin in entity.mixins:
36             if mixin.related[0].term == 'os_tpl':
37                 image = mixin
38                 image_id = mixin.attributes['occi.core.id']
39             if mixin.related[0].term == 'resource_tpl':
40                 flavor = mixin
41                 flavor_id = mixin.attributes['occi.core.id']
42                 
43         entity.attributes['occi.compute.state'] = 'inactive'
44         entity.actions = [START]
45
46         #Registry identifier is the uuid key occi.handler assigns
47         #attribute 'occi.core.id' will be the snf-server id
48
49         conf = Config()
50         conf.set('token',extras['token'])
51         snf = ComputeClient(conf)
52
53         vm_name = entity.attributes['occi.compute.hostname']
54         info = snf.create_server(vm_name, flavor_id, image_id)
55         entity.attributes['occi.core.id'] = str(info['id'])
56         entity.attributes['occi.compute.architecture'] = SERVER_CONFIG['compute_arch']
57         entity.attributes['occi.compute.cores'] = flavor.attributes['occi.compute.cores']
58         entity.attributes['occi.compute.memory'] = flavor.attributes['occi.compute.memory']
59         entity.attributes['occi.compute.hostname'] = SERVER_CONFIG['hostname'] % {'id':info['id']}
60
61     def retrieve(self, entity, extras):
62         
63         # triggering cyclades to retrieve up to date information
64
65         conf = Config()
66         conf.set('token',extras['token'])
67         snf = ComputeClient(conf)
68
69         vm_id = int(entity.attributes['occi.core.id'])
70         vm_info = snf.get_server_details(vm_id)
71         vm_state = vm_info['status']
72         
73         status_dict = {'ACTIVE' : 'active',
74                        'STOPPED' : 'inactive',
75                        'ERROR' : 'inactive',
76                        'BUILD' : 'inactive',
77                        'DELETED' : 'inactive',
78                        }
79         
80         entity.attributes['occi.compute.state'] = status_dict[vm_state]
81
82         if entity.attributes['occi.compute.state'] == 'inactive':
83             entity.actions = [START]
84         if entity.attributes['occi.compute.state'] == 'active': 
85             entity.actions = [STOP, SUSPEND, RESTART]
86         if entity.attributes['occi.compute.state'] == 'suspended':
87             entity.actions = [START]
88
89
90     def delete(self, entity, extras):
91
92         # delete vm with vm_id = entity.attributes['occi.core.id']
93         conf = Config()
94         conf.set('token',extras['token'])
95         snf = ComputeClient(conf)
96
97         vm_id = int(entity.attributes['occi.core.id'])
98         snf.delete_server(vm_id)
99
100
101     def action(self, entity, action, extras):
102
103         conf = Config()
104         conf.set('token',extras['token'])
105         client = CycladesClient(conf)
106
107         vm_id = int(entity.attributes['occi.core.id'])
108
109         if action not in entity.actions:
110             raise AttributeError("This action is currently no applicable.")
111
112         elif action == START:
113             print "Starting VM"
114             client.start_server(vm_id)
115
116
117         elif action == STOP:
118             print "Stopping VM"
119             client.shutdown_server(vm_id)
120             
121         elif action == RESTART:
122             print "Restarting VM"
123             snf.reboot_server(vm_id)
124
125
126         elif action == SUSPEND:
127             raise AttributeError("This actions is currently no applicable")