Statistics
| Branch: | Revision:

root / snfOCCI / compute.py @ b7fca2d2

History | View | Annotate | Download (4.6 kB)

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
from occi.exceptions import HTTPError
10

    
11

    
12
#Compute Backend for snf-occi-server
13

    
14
class MyBackend(KindBackend, ActionBackend):
15
    '''
16
    An very simple abstract backend which handles update and replace for
17
    attributes. Support for links and mixins would need to added.
18
    '''
19

    
20
    # Updating and Replacing compute instances not supported by Cyclades
21

    
22
    def update(self, old, new, extras):
23
        raise AttributeError("This action is currently no applicable.")
24

    
25
    def replace(self, old, new, extras):
26
        raise AttributeError("This action is currently no applicable.")
27

    
28

    
29
class ComputeBackend(MyBackend):
30
    '''
31
    Backend for Cyclades/Openstack compute instances
32
    '''
33

    
34
    def create(self, entity, extras):
35

    
36
        #Creating new compute instance
37
    
38
        for mixin in entity.mixins:
39
            if mixin.related[0].term == 'os_tpl':
40
                image = mixin
41
                image_id = mixin.attributes['occi.core.id']
42
            if mixin.related[0].term == 'resource_tpl':
43
                flavor = mixin
44
                flavor_id = mixin.attributes['occi.core.id']
45
                
46
        entity.attributes['occi.compute.state'] = 'inactive'
47
        entity.actions = [START]
48

    
49
        conf = Config()
50
        conf.set('token',extras['token'])
51
        snf = ComputeClient(conf)
52

    
53
        vm_name = entity.attributes['occi.core.title']
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 vm_state == 'ERROR':
83
            raise HTTPError(500, 'ERROR building the compute instance')
84

    
85
        else:
86
            if entity.attributes['occi.compute.state'] == 'inactive':
87
                entity.actions = [START]
88
            if entity.attributes['occi.compute.state'] == 'active': 
89
                entity.actions = [STOP, SUSPEND, RESTART]
90
            if entity.attributes['occi.compute.state'] == 'suspended':
91
                entity.actions = [START]
92

    
93

    
94
    def delete(self, entity, extras):
95

    
96
        #Deleting compute instance
97

    
98
        conf = Config()
99
        conf.set('token',extras['token'])
100
        snf = ComputeClient(conf)
101

    
102
        vm_id = int(entity.attributes['occi.core.id'])
103
        snf.delete_server(vm_id)
104

    
105

    
106
    def action(self, entity, action, extras):
107

    
108
        #Triggering action to compute instances
109

    
110
        conf = Config()
111
        conf.set('token',extras['token'])
112
        client = CycladesClient(conf)
113
        snf = ComputeClient(conf)
114

    
115
        vm_id = int(entity.attributes['occi.core.id'])
116
        vm_info = snf.get_server_details(vm_id)
117
        vm_state = vm_info['status']
118

    
119

    
120
        if vm_state == 'ERROR':
121
            raise HTTPError(500, 'ERROR building the compute instance')
122

    
123
        else:
124
            if action not in entity.actions:
125
                raise AttributeError("This action is currently no applicable.")
126
            
127
            elif action == START:
128
                print "Starting VM"
129
                client.start_server(vm_id)
130
                
131
            elif action == STOP:
132
                print "Stopping VM"
133
                client.shutdown_server(vm_id)
134
    
135
            elif action == RESTART:
136
                print "Restarting VM"
137
                snf.reboot_server(vm_id)
138

    
139
            elif action == SUSPEND:
140
                raise AttributeError("This actions is currently no applicable")