Statistics
| Branch: | Revision:

root / snfOCCI / compute.py @ f25a4623

History | View | Annotate | Download (6.1 kB)

1
# Copyright 2012-2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#     copyright notice, this list of conditions and the following
9
#     disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#     copyright notice, this list of conditions and the following
13
#     disclaimer in the documentation and/or other materials
14
#     provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34

    
35
from snfOCCI.config import SERVER_CONFIG
36

    
37
from occi.backend import ActionBackend, KindBackend
38
from occi.extensions.infrastructure import START, STOP, SUSPEND, RESTART
39
from occi.exceptions import HTTPError
40

    
41

    
42
#Compute Backend for snf-occi-server
43

    
44
class MyBackend(KindBackend, ActionBackend):
45

    
46
    # Updating and Replacing compute instances not supported by Cyclades
47

    
48
    def update(self, old, new, extras):
49
        raise HTTPError(501, "Update is currently no applicable")
50

    
51
    def replace(self, old, new, extras):
52
        raise HTTPError(501, "Replace is currently no applicable")
53

    
54

    
55
class ComputeBackend(MyBackend):
56
    '''
57
    Backend for Cyclades/Openstack compute instances
58
    '''
59

    
60
    def create(self, entity, extras):
61

    
62
        #Creating new compute instance
63
        
64
        try:
65

    
66
            snf = extras['snf']
67

    
68
            for mixin in entity.mixins:
69
                if mixin.related[0].term == 'os_tpl':
70
                    image_id = mixin.attributes['occi.core.id']
71
                if mixin.related[0].term == 'resource_tpl':
72
                    flavor = mixin
73
                    flavor_id = mixin.attributes['occi.core.id']
74

    
75
            vm_name = entity.attributes['occi.core.title']
76
            info = snf.create_server(vm_name, flavor_id, image_id)
77
           
78
            entity.actions = [START]
79
            entity.attributes['occi.compute.state'] = 'inactive'
80
            entity.attributes['occi.core.id'] = str(info['id'])
81
            entity.attributes['occi.compute.architecture'] = SERVER_CONFIG['compute_arch']
82
            entity.attributes['occi.compute.cores'] = flavor.attributes['occi.compute.cores']
83
            entity.attributes['occi.compute.memory'] = flavor.attributes['occi.compute.memory']
84
           
85
            # entity.attributes['occi.compute.hostname'] = SERVER_CONFIG['hostname'] % {'id':info['id']}
86
            info['adminPass']= ""
87
            print info
88
            networkIDs = info['addresses'].keys()
89
                #resource.attributes['occi.compute.hostname'] = SERVER_CONFIG['hostname'] % {'id':int(key)}
90
            if len(networkIDs)>0:    
91
                entity.attributes['occi.compute.hostname'] =  str(info['addresses'][networkIDs[0]][0]['addr'])
92
            else:
93
                entity.attributes['occi.compute.hostname'] = ""
94
               
95
        except (UnboundLocalError, KeyError) as e:
96
            raise HTTPError(406, 'Missing details about compute instance')
97
            
98

    
99
    def retrieve(self, entity, extras):
100
        
101
        #Triggering cyclades to retrieve up to date information
102

    
103
        snf = extras['snf']
104

    
105
        vm_id = int(entity.attributes['occi.core.id'])
106
        vm_info = snf.get_server_details(vm_id)
107
        vm_state = vm_info['status']
108
        
109
        status_dict = {'ACTIVE' : 'active',
110
                       'STOPPED' : 'inactive',
111
                       'ERROR' : 'inactive',
112
                       'BUILD' : 'inactive',
113
                       'DELETED' : 'inactive',
114
                       }
115
        
116
        entity.attributes['occi.compute.state'] = status_dict[vm_state]
117
                
118
        if vm_state == 'ERROR':
119
            raise HTTPError(500, 'ERROR building the compute instance')
120

    
121
        else:
122
            if entity.attributes['occi.compute.state'] == 'inactive':
123
                entity.actions = [START]
124
            if entity.attributes['occi.compute.state'] == 'active': 
125
                entity.actions = [STOP, SUSPEND, RESTART]
126

    
127

    
128
    def delete(self, entity, extras):
129

    
130
        #Deleting compute instance
131

    
132
        snf = extras['snf']
133
        vm_id = int(entity.attributes['occi.core.id'])
134
        snf.delete_server(vm_id)
135

    
136

    
137
    def action(self, entity, action, extras):
138

    
139
        #Triggering action to compute instances
140

    
141
        client = extras['client']
142
        snf = extras['snf']
143

    
144
        vm_id = int(entity.attributes['occi.core.id'])
145
        vm_info = snf.get_server_details(vm_id)
146
        vm_state = vm_info['status']
147

    
148

    
149
        if vm_state == 'ERROR':
150
            raise HTTPError(500, 'ERROR building the compute instance')
151

    
152
        else:
153
            if action not in entity.actions:
154
                raise AttributeError("This action is currently no applicable.")
155
            
156
            elif action == START:
157
                print "Starting VM"
158
                client.start_server(vm_id)
159
                
160
            elif action == STOP:
161
                print "Stopping VM"
162
                client.shutdown_server(vm_id)
163
    
164
            elif action == RESTART:
165
                print "Restarting VM"
166
                snf.reboot_server(vm_id)
167

    
168
            elif action == SUSPEND:
169
                raise HTTPError(501, "This actions is currently no applicable")