Revision af3eed60

View differences:

include/RequestManagerVirtualMachine.h
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
#ifndef REQUEST_MANAGER_VIRTUAL_MACHINE_H_
18
#define REQUEST_MANAGER_VIRTUAL_MACHINE_H
19

  
20
#include "Request.h"
21
#include "Nebula.h"
22

  
23
using namespace std;
24

  
25
/* ------------------------------------------------------------------------- */
26
/* ------------------------------------------------------------------------- */
27
/* ------------------------------------------------------------------------- */
28

  
29
class RequestManagerVirtualMachine: public Request
30
{
31
protected:
32
    RequestManagerVirtualMachine(const string& method_name,
33
                       const string& help,
34
                       const string& params)
35
        :Request(method_name,params,help)
36
    {
37
        Nebula& nd  = Nebula::instance();
38
        pool        = nd.get_vmpool();
39

  
40
        auth_object = AuthRequest::VM;
41
        auth_op = AuthRequest::MANAGE;
42
    };
43

  
44
    ~RequestManagerVirtualMachine(){};
45

  
46
    /* -------------------------------------------------------------------- */
47

  
48
    virtual void request_execute(xmlrpc_c::paramList const& _paramList) = 0;
49

  
50
    bool vm_authorization(int id, int hid, ImageTemplate *tmpl);
51

  
52
    int get_host_information(int hid, string& name, string& vmm, string& tm);
53

  
54
    int add_history(VirtualMachine * vm,
55
                    int              hid,
56
                    const string&    hostname,
57
                    const string&    vmm_mad,
58
                    const string&    tm_mad);
59

  
60
    VirtualMachine * get_vm(int id);
61
};
62

  
63
/* ------------------------------------------------------------------------- */
64
/* ------------------------------------------------------------------------- */
65

  
66
class VirtualMachineAction : public RequestManagerVirtualMachine
67
{
68
public:
69
    VirtualMachineAction():
70
        RequestManagerVirtualMachine("VirtualMachineAction",
71
                                     "Performs an action on a virtual machine",
72
                                     "A:ssi"){};
73
    ~VirtualMachineAction(){};
74

  
75
    void request_execute(xmlrpc_c::paramList const& _paramList);
76
};
77

  
78
/* ------------------------------------------------------------------------- */
79
/* ------------------------------------------------------------------------- */
80

  
81
class VirtualMachineDeploy : public RequestManagerVirtualMachine
82
{
83
public:
84
    VirtualMachineDeploy():
85
        RequestManagerVirtualMachine("VirtualMachineDeploy",
86
                                     "Deploys a virtual machine",
87
                                     "A:sii"){};
88

  
89
    ~VirtualMachineDeploy(){};
90

  
91
    void request_execute(xmlrpc_c::paramList const& _paramList);
92
};
93

  
94
/* ------------------------------------------------------------------------- */
95
/* ------------------------------------------------------------------------- */
96

  
97
class VirtualMachineMigrate : public RequestManagerVirtualMachine
98
{
99
public:
100
    VirtualMachineMigrate():
101
        RequestManagerVirtualMachine("VirtualMachineDeploy",
102
                                     "Migrates a virtual machine",
103
                                     "A:siib"){};
104

  
105
    ~VirtualMachineMigrate(){};
106

  
107
    void request_execute(xmlrpc_c::paramList const& _paramList);
108
};
109

  
110
/* ------------------------------------------------------------------------- */
111
/* ------------------------------------------------------------------------- */
112

  
113
class VirtualMachineSaveDisk : public RequestManagerVirtualMachine
114
{
115
public:
116
    VirtualMachineSaveDisk():
117
        RequestManagerVirtualMachine("VirtualMachineSaveDisk",
118
                           "Saves a disk from virtual machine as a new image",
119
                           "A:siis"){};
120

  
121
    ~VirtualMachineSaveDisk(){};
122

  
123
    void request_execute(xmlrpc_c::paramList const& _paramList);
124
};
125

  
126
/* -------------------------------------------------------------------------- */
127
/* -------------------------------------------------------------------------- */
128
/* -------------------------------------------------------------------------- */
129

  
130
#endif
src/rm/RequestManager.cc
26 26
#include "RequestManagerAllocate.h"
27 27

  
28 28
#include "RequestManagerVirtualNetwork.h"
29
#include "RequestManagerVirtualMachine.h"
29 30

  
30 31
#include <sys/signal.h>
31 32
#include <sys/socket.h>
......
222 223
        
223 224
void RequestManager::register_xml_methods()
224 225
{
226
    // VirtualMachine Methods
227
    xmlrpc_c::methodPtr vm_deploy(new VirtualMachineDeploy());
228
    xmlrpc_c::methodPtr vm_migrate(new VirtualMachineMigrate());
229
    xmlrpc_c::methodPtr vm_action(new VirtualMachineAction()); 
230
    xmlrpc_c::methodPtr vm_savedisk(new VirtualMachineSaveDisk());
231

  
225 232
    // VirtualNetwork Methods
226 233
    xmlrpc_c::methodPtr vn_addleases(new VirtualNetworkAddLeases());
227 234
    xmlrpc_c::methodPtr vn_rmleases(new VirtualNetworkRemoveLeases());
......
275 282
    xmlrpc_c::methodPtr imagepool_info(new ImagePoolInfo());
276 283

  
277 284
/*     
278
    xmlrpc_c::methodPtr vm_deploy(new 
279
        RequestManager::VirtualMachineDeploy(vmpool,hpool,upool));
280
        
281
    xmlrpc_c::methodPtr vm_migrate(new 
282
        RequestManager::VirtualMachineMigrate(vmpool,hpool,upool));
283
        
284
    xmlrpc_c::methodPtr vm_action(new 
285
        RequestManager::VirtualMachineAction(vmpool,upool));
286

  
287
    xmlrpc_c::methodPtr vm_savedisk(new
288
        RequestManager::VirtualMachineSaveDisk(vmpool,upool,ipool));
289

  
290

  
291 285
    xmlrpc_c::methodPtr vm_chown(new
292 286
        RequestManager::GenericChown(this,VM));
293 287

  
294 288

  
295

  
296

  
297 289
    xmlrpc_c::methodPtr template_update(new
298 290
        RequestManager::TemplateUpdate(tpool, upool));
299 291

  
300 292
    xmlrpc_c::methodPtr template_rm_attribute(new
301 293
        RequestManager::TemplateRemoveAttribute(tpool, upool));
302 294

  
303

  
304 295
    xmlrpc_c::methodPtr template_chown(new
305 296
        RequestManager::GenericChown(this,TEMPLATE));
306 297

  
......
348 339
    xmlrpc_c::methodPtr image_rm_attribute(new    
349 340
        RequestManager::ImageRemoveAttribute(ipool, upool));
350 341
        
351
        
352 342
    xmlrpc_c::methodPtr image_persistent(new    
353 343
        RequestManager::ImagePersistent(ipool, upool));
354 344
        
......
360 350
*/
361 351
    /* VM related methods  */    
362 352
/*        
353

  
354
    RequestManagerRegistry.addMethod("one.vm.chown", vm_chown);
355
*/
363 356
    RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy);
364 357
    RequestManagerRegistry.addMethod("one.vm.action", vm_action);
365 358
    RequestManagerRegistry.addMethod("one.vm.migrate", vm_migrate);
366 359
    RequestManagerRegistry.addMethod("one.vm.savedisk", vm_savedisk);
367
    RequestManagerRegistry.addMethod("one.vm.chown", vm_chown);
368
*/
369 360
    RequestManagerRegistry.addMethod("one.vm.allocate", vm_allocate);
370 361
    RequestManagerRegistry.addMethod("one.vm.info", vm_info);
371 362

  
src/rm/RequestManagerVirtualMachine.cc
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
/* -------------------------------------------------------------------------- */
src/rm/SConstruct
31 31
    'RequestManagerPublish.cc',
32 32
    'RequestManagerAllocate.cc',
33 33
    'RequestManagerVirtualNetwork.cc',
34
    'RequestManagerVirtualMachine.cc',
34 35

  
35 36
#    'RequestManagerAction.cc',
36 37
#    'RequestManagerAllocate.cc',

Also available in: Unified diff