Statistics
| Branch: | Tag: | Revision:

one / src / rm / RequestManagerVirtualMachine.cc @ af3eed60

History | View | Annotate | Download (11 KB)

1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)             */
3
/*                                                                            */
4
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
5
/* not use this file except in compliance with the License. You may obtain    */
6
/* a copy of the License at                                                   */
7
/*                                                                            */
8
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
9
/*                                                                            */
10
/* Unless required by applicable law or agreed to in writing, software        */
11
/* distributed under the License is distributed on an "AS IS" BASIS,          */
12
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
13
/* See the License for the specific language governing permissions and        */
14
/* limitations under the License.                                             */
15
/* -------------------------------------------------------------------------- */
16

    
17
#include "RequestManagerVirtualMachine.h"
18
#include "Nebula.h"
19

    
20
/* -------------------------------------------------------------------------- */
21
/* -------------------------------------------------------------------------- */
22

    
23
bool RequestManagerVirtualMachine::vm_authorization(int oid, int hid, ImageTemplate *tmpl)
24
{
25
    PoolObjectSQL * object;
26

    
27
    int  ouid;
28

    
29
    if ( uid == 0 )
30
    {
31
        return true;
32
    }
33

    
34
    object = pool->get(oid,true);
35

    
36
    if ( object == 0 )
37
    {
38
        failure_response(NO_EXISTS, get_error(object_name(auth_object),oid)); 
39
        return false;
40
    }
41

    
42
    ouid = object->get_uid();
43

    
44
    object->unlock();
45

    
46
    AuthRequest ar(uid);
47

    
48
    ar.add_auth(auth_object, oid, auth_op, ouid, false);
49

    
50
    if (hid != -1)
51
    {
52
        ar.add_auth(AuthRequest::HOST,hid,AuthRequest::USE,0,false);
53
    }
54
    else if (tmpl != 0)
55
    {
56
        string t64;
57

    
58
        ar.add_auth(AuthRequest::IMAGE,
59
                    tmpl->to_xml(t64),
60
                    AuthRequest::CREATE,
61
                    uid,
62
                    false);
63
    }
64

    
65
    if (UserPool::authorize(ar) == -1)
66
    {
67
        failure_response(AUTHORIZATION, //TODO
68
                 authorization_error("INFO",object_name(auth_object),oid,-1));
69

    
70
        return false;
71
    }
72

    
73
    return true;
74
}
75

    
76
/* -------------------------------------------------------------------------- */
77
/* -------------------------------------------------------------------------- */
78

    
79
int RequestManagerVirtualMachine::get_host_information(int hid, 
80
                                                string& name, 
81
                                                string& vmm, 
82
                                                string& tm)
83
{
84
    Nebula&    nd    = Nebula::instance();
85
    HostPool * hpool = nd.get_hpool();
86

    
87
    Host * host;
88

    
89
    host = hpool->get(hid,true);
90

    
91
    if ( host == 0 )
92
    {
93
        failure_response(NO_EXISTS,
94
                get_error(object_name(AuthRequest::HOST),hid)); 
95
        return -1;
96
    }
97

    
98
    name = host->get_name();
99
    vmm  = host->get_vmm_mad();
100
    tm   = host->get_tm_mad();
101

    
102
    host->unlock();
103

    
104
    return 0;
105
}
106

    
107
/* -------------------------------------------------------------------------- */
108
/* -------------------------------------------------------------------------- */
109

    
110
VirtualMachine * RequestManagerVirtualMachine::get_vm(int id)
111
{
112
    VirtualMachine * vm;
113

    
114
    vm = static_cast<VirtualMachine *>(pool->get(id,true));
115

    
116
    if ( vm == 0 )
117
    {
118
        failure_response(NO_EXISTS,get_error(object_name(auth_object),id)); 
119
        return 0;
120
    }
121

    
122
    return vm;
123
}
124
/* -------------------------------------------------------------------------- */
125
/* -------------------------------------------------------------------------- */
126

    
127
int RequestManagerVirtualMachine::add_history(VirtualMachine * vm,
128
                                       int              hid,
129
                                       const string&    hostname,
130
                                       const string&    vmm_mad,
131
                                       const string&    tm_mad)
132
{
133
    Nebula& nd = Nebula::instance();
134
    string  vmdir;
135

    
136
    int     rc;
137

    
138
    VirtualMachinePool * vmpool = static_cast<VirtualMachinePool *>(pool);
139

    
140
    nd.get_configuration_attribute("VM_DIR",vmdir);
141

    
142
    vm->add_history(hid,hostname,vmdir,vmm_mad,tm_mad);
143

    
144
    rc = vmpool->update_history(vm);
145

    
146
    if ( rc != 0 )
147
    {
148
        failure_response(INTERNAL, "Can not update virtual machine history");
149
        return -1;
150
    }
151

    
152
    vmpool->update(vm);
153

    
154
    return 0;
155
}  
156

    
157
/* -------------------------------------------------------------------------- */
158
/* -------------------------------------------------------------------------- */
159
void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList)
160
{
161
    string action = xmlrpc_c::value_string(paramList.getString(1));
162
    int    id     = xmlrpc_c::value_int(paramList.getInt(2));
163

    
164
    int    rc;
165

    
166
    Nebula& nd = Nebula::instance();
167
    DispatchManager * dm = nd.get_dm();
168

    
169
    if ( vm_authorization(id,-1,0) == false )
170
    {
171
        return;
172
    }
173

    
174
    if (action == "shutdown")
175
    {
176
        rc = dm->shutdown(id);
177
    }
178
    else if (action == "hold")
179
    {
180
        rc = dm->hold(id);
181
    }
182
    else if (action == "release")
183
    {
184
        rc = dm->release(id);
185
    }
186
    else if (action == "stop")
187
    {
188
        rc = dm->stop(id);
189
    }
190
    else if (action == "cancel")
191
    {
192
        rc = dm->cancel(id);
193
    }
194
    else if (action == "suspend")
195
    {
196
        rc = dm->suspend(id);
197
    }
198
    else if (action == "resume")
199
    {
200
        rc = dm->resume(id);
201
    }
202
    else if (action == "restart")
203
    {
204
        rc = dm->restart(id);
205
    }
206
    else if (action == "finalize")
207
    {
208
        rc = dm->finalize(id);
209
    }
210
    else if (action == "resubmit")
211
    {
212
        rc = dm->resubmit(id);
213
    }
214

    
215
    switch (rc)
216
    { 
217
        case 0:
218
            success_response(id);
219
            break;
220
        case -1:
221
            failure_response(NO_EXISTS,get_error(object_name(auth_object),id));
222
            break;
223
        case -2:
224
             failure_response(ACTION, "Worng state to perform action");
225
             break;
226
        case -3:
227
            failure_response(ACTION, "Virtual machine action not supported");
228
            break;
229
        default:
230
            failure_response(INTERNAL, "Internal error");
231
    }
232

    
233
    return;
234
}
235

    
236
/* -------------------------------------------------------------------------- */
237
/* -------------------------------------------------------------------------- */
238

    
239
void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList)
240
{
241
    Nebula&             nd = Nebula::instance();
242
    DispatchManager *   dm = nd.get_dm();
243

    
244
    VirtualMachine * vm;
245

    
246
    string hostname;
247
    string vmm_mad;
248
    string tm_mad;
249

    
250
    int id  = xmlrpc_c::value_int(paramList.getInt(1));
251
    int hid = xmlrpc_c::value_int(paramList.getInt(2));
252

    
253
    if ( vm_authorization(id,hid,0) == false )
254
    {
255
        return;
256
    }
257

    
258
    if (get_host_information(hid,hostname,vmm_mad,tm_mad) != 0)
259
    {
260
        return;
261
    }
262

    
263
    if ( (vm = get_vm(id)) == 0 )
264
    {
265
        return;
266
    }
267

    
268
    if ( vm->get_state() != VirtualMachine::PENDING )
269
    {
270
        failure_response(ACTION, "Worng state to perform action");
271
        vm->unlock();
272
        return;
273
    }
274

    
275
    if ( add_history(vm,hid,hostname,vmm_mad,tm_mad) != 0)
276
    {
277
        vm->unlock();
278
        return;
279
    }
280

    
281
    dm->deploy(vm);
282

    
283
    vm->unlock();
284

    
285
    success_response(id);
286
}
287

    
288
/* -------------------------------------------------------------------------- */
289
/* -------------------------------------------------------------------------- */
290

    
291
void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList)
292
{
293
    Nebula&             nd = Nebula::instance();
294
    DispatchManager *   dm = nd.get_dm();
295

    
296
    VirtualMachine * vm;
297

    
298
    string hostname;
299
    string vmm_mad;
300
    string tm_mad;
301

    
302
    int  id   = xmlrpc_c::value_int(paramList.getInt(1));
303
    int  hid  = xmlrpc_c::value_int(paramList.getInt(2));
304
    bool live = xmlrpc_c::value_boolean(paramList.getBoolean(3));
305

    
306
    if ( vm_authorization(id,hid,0) == false )
307
    {
308
        return;
309
    }
310

    
311
    if (get_host_information(hid,hostname,vmm_mad,tm_mad) == false)
312
    {
313
        return;
314
    }
315

    
316
    if ( (vm = get_vm(id)) == 0 )
317
    {
318
        return;
319
    }
320

    
321
    if((vm->get_state()     != VirtualMachine::ACTIVE)  ||
322
       (vm->get_lcm_state() != VirtualMachine::RUNNING) ||
323
       (vm->hasPreviousHistory() && vm->get_previous_reason() == History::NONE))
324
    {
325
        failure_response(ACTION, "Worng state to perform action");
326
        vm->unlock();
327
        return;
328
    }
329

    
330
    if ( add_history(vm,hid,hostname,vmm_mad,tm_mad) != 0)
331
    {
332
        vm->unlock();
333
        return;
334
    }
335

    
336
    if ( live == true )
337
    {
338
        dm->live_migrate(vm);
339
    }
340
    else
341
    {
342
        dm->migrate(vm);
343
    }
344

    
345
    vm->unlock();
346

    
347
    success_response(id);
348
}
349

    
350
/* -------------------------------------------------------------------------- */
351
/* -------------------------------------------------------------------------- */
352

    
353
void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramList)
354
{
355
    Nebula&     nd    = Nebula::instance();
356
    ImagePool * ipool = nd.get_ipool();
357

    
358
    int    id       = xmlrpc_c::value_int(paramList.getInt(1));
359
    int    disk_id  = xmlrpc_c::value_int(paramList.getInt(2));
360
    string img_name = xmlrpc_c::value_string(paramList.getString(3));
361

    
362
    VirtualMachine * vm;
363
    string           vm_owner;
364

    
365
    int              iid;
366
    ImageTemplate *  itemplate;
367

    
368
    int           rc;
369
    ostringstream oss;
370
    string        error_str;
371

    
372
    // ------------------ Template for the new image ------------------
373

    
374
    oss << "NAME= " << img_name << endl;
375
    oss << "PUBLIC = NO " << endl;
376
    oss << "SOURCE = - " << endl;
377

    
378
    itemplate = new ImageTemplate;
379

    
380
    itemplate->parse(oss.str(),0);
381

    
382
    // ------------------ Authorize the operation ------------------
383

    
384
    if ( vm_authorization(id,-1,itemplate) == false )
385
    {
386
        return;
387
    }
388

    
389
    // ------------------ Create the image ------------------
390

    
391
    rc = ipool->allocate(uid, gid, itemplate, &iid,error_str);
392

    
393
    if ( rc < 0 )
394
    {
395
        failure_response(INTERNAL,"Allocate Image"); //allocate_error(error_str)); //TODO
396
        return;
397
    }
398
 
399
    // ------------------ Store image id to save the disk ------------------
400

    
401
    if ( (vm = get_vm(id)) == 0 )
402
    {
403
        Image * img;
404

    
405
        if ( (img = ipool->get(iid,true)) != 0 )
406
        {
407
            ipool->drop(img);
408
        }
409

    
410
        return;
411
    }
412

    
413
    rc = vm->save_disk(disk_id, iid, error_str);
414

    
415
    if ( rc == -1 )
416
    {
417
        Image * img;
418

    
419
        if ( (img = ipool->get(iid,true)) != 0 )
420
        {
421
            ipool->drop(img);
422
        }
423

    
424
        failure_response(INTERNAL,error_str); //TODO
425
        
426
        return;
427
    }
428

    
429
    pool->update(vm);
430

    
431
    vm->unlock();
432

    
433
    success_response(id);
434
}
435

    
436
/* -------------------------------------------------------------------------- */
437
/* -------------------------------------------------------------------------- */