Statistics
| Branch: | Tag: | Revision:

one / src / vm / History.cc @ 5f28a7bf

History | View | Annotate | Download (17.5 KB)

1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2017, OpenNebula Project, OpenNebula Systems                */
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 "VirtualMachine.h"
18
#include "Nebula.h"
19

    
20
#include <iostream>
21
#include <sstream>
22

    
23
/* -------------------------------------------------------------------------- */
24
/* -------------------------------------------------------------------------- */
25

    
26
const char * History::table = "history";
27

    
28
const char * History::db_names = "vid, seq, body, stime, etime";
29

    
30
const char * History::db_bootstrap = "CREATE TABLE IF NOT EXISTS "
31
    "history (vid INTEGER, seq INTEGER, body MEDIUMTEXT, "
32
    "stime INTEGER, etime INTEGER,PRIMARY KEY(vid,seq))";
33

    
34
/* -------------------------------------------------------------------------- */
35
/* -------------------------------------------------------------------------- */
36

    
37
History::History(
38
    int _oid,
39
    int _seq):
40
        ObjectXML(),
41
        oid(_oid),
42
        seq(_seq),
43
        uid(-1),
44
        gid(-1),
45
        req_id(-1),
46
        hid(-1),
47
        hostname(""),
48
        cid(-1),
49
        vmm_mad_name(""),
50
        tm_mad_name(""),
51
        ds_id(0),
52
        stime(0),
53
        etime(0),
54
        prolog_stime(0),
55
        prolog_etime(0),
56
        running_stime(0),
57
        running_etime(0),
58
        epilog_stime(0),
59
        epilog_etime(0),
60
        action(NONE_ACTION),
61
        vm_info("<VM/>"){};
62

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

    
65
History::History(
66
    int _oid,
67
    int _seq,
68
    int _hid,
69
    const string& _hostname,
70
    int _cid,
71
    const string& _vmm,
72
    const string& _tmm,
73
    int           _ds_id,
74
    const string& _vm_info):
75
        oid(_oid),
76
        seq(_seq),
77
        uid(-1),
78
        gid(-1),
79
        req_id(-1),
80
        hid(_hid),
81
        hostname(_hostname),
82
        cid(_cid),
83
        vmm_mad_name(_vmm),
84
        tm_mad_name(_tmm),
85
        ds_id(_ds_id),
86
        stime(0),
87
        etime(0),
88
        prolog_stime(0),
89
        prolog_etime(0),
90
        running_stime(0),
91
        running_etime(0),
92
        epilog_stime(0),
93
        epilog_etime(0),
94
        action(NONE_ACTION),
95
        vm_info(_vm_info)
96
{
97
    non_persistent_data();
98
};
99

    
100
/* -------------------------------------------------------------------------- */
101
/* -------------------------------------------------------------------------- */
102

    
103
void History::non_persistent_data()
104
{
105
    ostringstream os;
106

    
107
    string vm_lhome;
108
    string ds_location;
109

    
110
    Nebula& nd = Nebula::instance();
111

    
112
    nd.get_ds_location(ds_location);
113

    
114
    // ----------- Local Locations ------------
115
    os.str("");
116
    os << nd.get_vms_location() << oid;
117

    
118
    vm_lhome = os.str();
119

    
120
    os << "/deployment." << seq;
121

    
122
    deployment_file = os.str();
123

    
124
    os.str("");
125
    os << vm_lhome << "/transfer." << seq;
126

    
127
    transfer_file = os.str();
128

    
129
    os.str("");
130
    os << vm_lhome << "/context.sh";
131

    
132
    context_file = os.str();
133

    
134
    os.str("");
135
    os << vm_lhome << "/token.txt";
136

    
137
    token_file = os.str();
138

    
139
    // ----------- Remote Locations ------------
140
    os.str("");
141
    os << ds_location << "/" << ds_id << "/" << oid;
142

    
143
    system_dir = os.str();
144

    
145
    os << "/checkpoint";
146
    checkpoint_file = os.str();
147

    
148
    os.str("");
149
    os << system_dir << "/deployment." << seq;
150

    
151
    rdeployment_file = os.str();
152
}
153

    
154
/* -------------------------------------------------------------------------- */
155
/* -------------------------------------------------------------------------- */
156

    
157
int History::insert_replace(SqlDB *db, bool replace)
158
{
159
    ostringstream   oss;
160

    
161
    string xml_body;
162
    char * sql_xml;
163

    
164
    int    rc;
165

    
166
    if (seq == -1)
167
    {
168
        return 0;
169
    }
170

    
171
    sql_xml = db->escape_str(to_db_xml(xml_body).c_str());
172

    
173
    if ( sql_xml == 0 )
174
    {
175
        goto error_body;
176
    }
177

    
178
    if(replace)
179
    {
180
        oss << "REPLACE";
181
    }
182
    else
183
    {
184
        oss << "INSERT";
185
    }
186

    
187
    oss << " INTO " << table << " ("<< db_names <<") VALUES ("
188
        <<          oid             << ","
189
        <<          seq             << ","
190
        << "'" <<   sql_xml         << "',"
191
        <<          stime           << ","
192
        <<          etime           << ")";
193

    
194
    rc = db->exec_wr(oss);
195

    
196
    db->free_str(sql_xml);
197

    
198
    return rc;
199

    
200
error_body:
201
    return -1;
202
}
203

    
204
/* -------------------------------------------------------------------------- */
205
/* -------------------------------------------------------------------------- */
206

    
207
int History::select_cb(void *nil, int num, char **values, char **names)
208
{
209
    if ( (!values[0]) || (num != 1) )
210
    {
211
        return -1;
212
    }
213

    
214
    return from_xml(values[0]);
215
}
216

    
217
/* -------------------------------------------------------------------------- */
218
/* -------------------------------------------------------------------------- */
219

    
220
int History::select(SqlDB * db)
221
{
222
    ostringstream   oss;
223
    int             rc;
224

    
225
    if (oid == -1)
226
    {
227
        return -1;
228
    }
229

    
230
    if ( seq == -1)
231
    {
232
        oss << "SELECT body FROM history WHERE vid = "<< oid <<
233
            " AND seq=(SELECT MAX(seq) FROM history WHERE vid = " << oid << ")";
234
    }
235
    else
236
    {
237
        oss << "SELECT body FROM history WHERE vid = " << oid
238
            << " AND seq = " << seq;
239
    }
240

    
241
    set_callback(static_cast<Callbackable::Callback>(&History::select_cb));
242

    
243
    rc = db->exec_rd(oss,this);
244

    
245
    unset_callback();
246

    
247
        if ( hostname.empty() )
248
        {
249
                rc = -1;
250
        }
251

    
252
    if ( rc == 0 ) // Regenerate non-persistent data
253
    {
254
        non_persistent_data();
255
    }
256

    
257
    return rc;
258
}
259

    
260
/* -------------------------------------------------------------------------- */
261
/* -------------------------------------------------------------------------- */
262

    
263
int History::drop(SqlDB * db)
264
{
265
    ostringstream   oss;
266

    
267
    oss << "DELETE FROM " << table << " WHERE vid= "<< oid;
268

    
269
    return db->exec_wr(oss);
270
}
271

    
272
/* -------------------------------------------------------------------------- */
273
/* -------------------------------------------------------------------------- */
274

    
275
ostream& operator<<(ostream& os, const History& history)
276
{
277
    string history_str;
278

    
279
    os << history.to_xml(history_str);
280

    
281
    return os;
282
};
283

    
284
/* -------------------------------------------------------------------------- */
285
/* -------------------------------------------------------------------------- */
286

    
287
string& History::to_xml(string& xml) const
288
{
289
    return to_xml(xml, false);
290
}
291

    
292
/* -------------------------------------------------------------------------- */
293

    
294
string& History::to_db_xml(string& xml) const
295
{
296
    return to_xml(xml, true);
297
}
298

    
299
/* -------------------------------------------------------------------------- */
300

    
301
string& History::to_xml(string& xml, bool database) const
302
{
303
    ostringstream oss;
304

    
305
    oss <<
306
        "<HISTORY>" <<
307
          "<OID>"        << oid           << "</OID>"   <<
308
          "<SEQ>"        << seq           << "</SEQ>"   <<
309
          "<HOSTNAME>"   << hostname      << "</HOSTNAME>"<<
310
          "<HID>"        << hid           << "</HID>"   <<
311
          "<CID>"        << cid           << "</CID>"   <<
312
          "<STIME>"      << stime         << "</STIME>" <<
313
          "<ETIME>"      << etime         << "</ETIME>" <<
314
          "<VM_MAD>"     << one_util::escape_xml(vmm_mad_name)<<"</VM_MAD>"<<
315
          "<TM_MAD>"     << one_util::escape_xml(tm_mad_name) <<"</TM_MAD>" <<
316
          "<DS_ID>"      << ds_id         << "</DS_ID>" <<
317
          "<PSTIME>"     << prolog_stime  << "</PSTIME>"<<
318
          "<PETIME>"     << prolog_etime  << "</PETIME>"<<
319
          "<RSTIME>"     << running_stime << "</RSTIME>"<<
320
          "<RETIME>"     << running_etime << "</RETIME>"<<
321
          "<ESTIME>"     << epilog_stime  << "</ESTIME>"<<
322
          "<EETIME>"     << epilog_etime  << "</EETIME>"<<
323
          "<ACTION>"     << action        << "</ACTION>"<<
324
          "<UID>"        << uid           << "</UID>"<<
325
          "<GID>"        << gid           << "</GID>"<<
326
          "<REQUEST_ID>" << req_id        << "</REQUEST_ID>";
327

    
328
    if ( database )
329
    {
330
        oss << vm_info;
331
    }
332

    
333
    oss <<
334
        "</HISTORY>";
335

    
336
   xml = oss.str();
337

    
338
   return xml;
339
}
340

    
341
/* -------------------------------------------------------------------------- */
342
/* -------------------------------------------------------------------------- */
343

    
344
int History::rebuild_attributes()
345
{
346
    vector<xmlNodePtr> content;
347

    
348
    int int_action;
349
    int rc = 0;
350

    
351
    rc += xpath(seq, "/HISTORY/SEQ", -1);
352
    rc += xpath(hid, "/HISTORY/HID", -1);
353
    rc += xpath(cid, "/HISTORY/CID", -1);
354

    
355
    rc += xpath(ds_id, "/HISTORY/DS_ID", 0);
356

    
357
    rc += xpath(hostname, "/HISTORY/HOSTNAME", "not_found");
358

    
359
    rc += xpath<time_t>(stime , "/HISTORY/STIME", 0);
360
    rc += xpath<time_t>(etime , "/HISTORY/ETIME", 0);
361

    
362
    rc += xpath(vmm_mad_name, "/HISTORY/VM_MAD", "not_found");
363
    rc += xpath(tm_mad_name , "/HISTORY/TM_MAD", "not_found");
364

    
365
    rc += xpath<time_t>(prolog_stime , "/HISTORY/PSTIME", 0);
366
    rc += xpath<time_t>(prolog_etime , "/HISTORY/PETIME", 0);
367
    rc += xpath<time_t>(running_stime, "/HISTORY/RSTIME", 0);
368
    rc += xpath<time_t>(running_etime, "/HISTORY/RETIME", 0);
369
    rc += xpath<time_t>(epilog_stime , "/HISTORY/ESTIME", 0);
370
    rc += xpath<time_t>(epilog_etime , "/HISTORY/EETIME", 0);
371

    
372
    rc += xpath(int_action , "/HISTORY/ACTION", 0);
373

    
374
    rc += xpath(uid, "/HISTORY/UID", -1);
375
    rc += xpath(gid, "/HISTORY/GID", -1);
376
    rc += xpath(req_id, "/HISTORY/REQUEST_ID", -1);
377

    
378
    action = static_cast<VMAction>(int_action);
379

    
380
    // -------------------------------------------------------------------------
381
    ObjectXML::get_nodes("/HISTORY/VM", content);
382

    
383
    if (!content.empty())
384
    {
385
        ObjectXML vm_info_xml(content[0]);
386

    
387
        ostringstream oss;
388

    
389
        oss << vm_info_xml;
390

    
391
        vm_info = oss.str();
392

    
393
        ObjectXML::free_nodes(content);
394

    
395
        content.clear();
396
    }
397

    
398
    non_persistent_data();
399

    
400
    if (rc != 0)
401
    {
402
        return -1;
403
    }
404

    
405
    return 0;
406
}
407

    
408
/* -------------------------------------------------------------------------- */
409
/* -------------------------------------------------------------------------- */
410

    
411
string History::action_to_str(VMAction action)
412
{
413
    string st;
414

    
415
    switch (action)
416
    {
417
        case MIGRATE_ACTION:
418
            st = "migrate";
419
        break;
420
        case LIVE_MIGRATE_ACTION:
421
            st = "live-migrate";
422
        break;
423
        case TERMINATE_ACTION:
424
            st = "terminate";
425
        break;
426
        case TERMINATE_HARD_ACTION:
427
            st = "terminate-hard";
428
        break;
429
        case UNDEPLOY_ACTION:
430
            st = "undeploy";
431
        break;
432
        case UNDEPLOY_HARD_ACTION:
433
            st = "undeploy-hard";
434
        break;
435
        case HOLD_ACTION:
436
            st = "hold";
437
        break;
438
        case RELEASE_ACTION:
439
            st = "release";
440
        break;
441
        case STOP_ACTION:
442
            st = "stop";
443
        break;
444
        case SUSPEND_ACTION:
445
            st = "suspend";
446
        break;
447
        case RESUME_ACTION:
448
            st = "resume";
449
        break;
450
        case DELETE_ACTION:
451
            st = "delete";
452
        break;
453
        case DELETE_RECREATE_ACTION:
454
            st = "delete-recreate";
455
        break;
456
        case REBOOT_ACTION:
457
            st = "reboot";
458
        break;
459
        case REBOOT_HARD_ACTION:
460
            st = "reboot-hard";
461
        break;
462
        case RESCHED_ACTION:
463
            st = "resched";
464
        break;
465
        case UNRESCHED_ACTION:
466
            st = "unresched";
467
        break;
468
        case POWEROFF_ACTION:
469
            st = "poweroff";
470
        break;
471
        case POWEROFF_HARD_ACTION:
472
            st = "poweroff-hard";
473
        break;
474
        case DISK_ATTACH_ACTION:
475
            st = "disk-attach";
476
        break;
477
        case DISK_DETACH_ACTION:
478
            st = "disk-detach";
479
        break;
480
        case NIC_ATTACH_ACTION:
481
            st = "nic-attach";
482
        break;
483
        case NIC_DETACH_ACTION:
484
            st = "nic-detach";
485
        break;
486
        case DISK_SNAPSHOT_CREATE_ACTION:
487
            st = "disk-snapshot-create";
488
        break;
489
        case DISK_SNAPSHOT_DELETE_ACTION:
490
            st = "disk-snapshot-delete";
491
        break;
492
        case DISK_RESIZE_ACTION:
493
            st = "disk-resize";
494
        break;
495
        case DEPLOY_ACTION:
496
            st = "deploy";
497
        break;
498
        case CHOWN_ACTION:
499
            st = "chown";
500
        break;
501
        case CHMOD_ACTION:
502
            st = "chmod";
503
        break;
504
        case UPDATECONF_ACTION:
505
            st = "updateconf";
506
        break;
507
        case RENAME_ACTION:
508
            st = "rename";
509
        break;
510
        case RESIZE_ACTION:
511
            st = "resize";
512
        break;
513
        case UPDATE_ACTION:
514
            st = "update";
515
        break;
516
        case SNAPSHOT_CREATE_ACTION:
517
            st = "snapshot-resize";
518
        break;
519
        case SNAPSHOT_DELETE_ACTION:
520
            st = "snapshot-delete";
521
        break;
522
        case SNAPSHOT_REVERT_ACTION:
523
            st = "snapshot-revert";
524
        break;
525
        case DISK_SAVEAS_ACTION:
526
            st = "disk-saveas";
527
        break;
528
        case DISK_SNAPSHOT_REVERT_ACTION:
529
            st = "disk-snapshot-revert";
530
        break;
531
        case RECOVER_ACTION:
532
            st = "recover";
533
        break;
534
        case RETRY_ACTION:
535
            st = "retry";
536
        break;
537
        case MONITOR_ACTION:
538
            st = "monitor";
539
        break;
540
        case NONE_ACTION:
541
            st = "none";
542
        break;
543
    }
544

    
545
    return st;
546
};
547

    
548
int History::action_from_str(const string& st, VMAction& action)
549
{
550
    if (st == "migrate")
551
    {
552
        action = MIGRATE_ACTION;
553
    }
554
    else if (st == "live-migrate")
555
    {
556
        action = LIVE_MIGRATE_ACTION;
557
    }
558
    else if (st == "terminate")
559
    {
560
        action = TERMINATE_ACTION;
561
    }
562
    else if (st == "terminate-hard")
563
    {
564
        action = TERMINATE_HARD_ACTION;
565
    }
566
    else if (st == "undeploy")
567
    {
568
        action = UNDEPLOY_ACTION;
569
    }
570
    else if (st == "undeploy-hard")
571
    {
572
        action = UNDEPLOY_HARD_ACTION;
573
    }
574
    else if (st == "hold")
575
    {
576
        action = HOLD_ACTION;
577
    }
578
    else if (st == "release")
579
    {
580
        action = RELEASE_ACTION;
581
    }
582
    else if (st == "stop")
583
    {
584
        action = STOP_ACTION;
585
    }
586
    else if (st == "suspend")
587
    {
588
        action = SUSPEND_ACTION;
589
    }
590
    else if (st == "resume")
591
    {
592
        action = RESUME_ACTION;
593
    }
594
    else if (st == "delete")
595
    {
596
        action = DELETE_ACTION;
597
    }
598
    else if (st == "delete-recreate")
599
    {
600
        action = DELETE_RECREATE_ACTION;
601
    }
602
    else if (st == "reboot")
603
    {
604
        action = REBOOT_ACTION;
605
    }
606
    else if (st == "reboot-hard")
607
    {
608
        action = REBOOT_HARD_ACTION;
609
    }
610
    else if (st == "resched")
611
    {
612
        action = RESCHED_ACTION;
613
    }
614
    else if (st == "unresched")
615
    {
616
        action = UNRESCHED_ACTION;
617
    }
618
    else if (st == "poweroff")
619
    {
620
        action = POWEROFF_ACTION;
621
    }
622
    else if (st == "poweroff-hard")
623
    {
624
        action = POWEROFF_HARD_ACTION;
625
    }
626
    else if (st == "disk-attach")
627
    {
628
        action = DISK_ATTACH_ACTION;
629
    }
630
    else if (st == "disk-detach")
631
    {
632
        action = DISK_DETACH_ACTION;
633
    }
634
    else if (st == "nic-attach")
635
    {
636
        action = NIC_ATTACH_ACTION;
637
    }
638
    else if (st == "nic-detach")
639
    {
640
        action = NIC_DETACH_ACTION;
641
    }
642
    else if (st == "disk-snapshot-create")
643
    {
644
        action = DISK_SNAPSHOT_CREATE_ACTION;
645
    }
646
    else if (st == "disk-snapshot-snap-delete")
647
    {
648
        action = DISK_SNAPSHOT_DELETE_ACTION;
649
    }
650
    else if (st == "disk-resize")
651
    {
652
        action = DISK_RESIZE_ACTION;
653
    }
654
    else if ( st == "deploy")
655
    {
656
        action = DEPLOY_ACTION;
657
    }
658
    else if ( st == "chown")
659
    {
660
        action = CHOWN_ACTION;
661
    }
662
    else if ( st == "chmod")
663
    {
664
        action = CHMOD_ACTION;
665
    }
666
    else if ( st == "updateconf")
667
    {
668
        action = UPDATECONF_ACTION;
669
    }
670
    else if ( st == "rename")
671
    {
672
        action = RENAME_ACTION;
673
    }
674
    else if ( st == "resize")
675
    {
676
        action = RESIZE_ACTION;
677
    }
678
    else if ( st == "update")
679
    {
680
        action = UPDATE_ACTION;
681
    }
682
    else if ( st == "snapshot-resize")
683
    {
684
        action = SNAPSHOT_CREATE_ACTION;
685
    }
686
    else if ( st == "snapshot-delete")
687
    {
688
        action = SNAPSHOT_DELETE_ACTION;
689
    }
690
    else if ( st == "snapshot-revert")
691
    {
692
        action = SNAPSHOT_REVERT_ACTION;
693
    }
694
    else if ( st == "disk-saveas")
695
    {
696
        action = DISK_SAVEAS_ACTION;
697
    }
698
    else if ( st == "disk-snapshot-revert")
699
    {
700
        action = DISK_SNAPSHOT_REVERT_ACTION;
701
    }
702
    else if ( st == "recover")
703
    {
704
        action = RECOVER_ACTION;
705
    }
706
    else if ( st == "retry")
707
    {
708
        action = RETRY_ACTION;
709
    }
710
    else if ( st == "monitor")
711
    {
712
        action = MONITOR_ACTION;
713
    }
714
    else
715
    {
716
        action = NONE_ACTION;
717
        return -1;
718
    }
719

    
720
    return 0;
721
};