Statistics
| Branch: | Tag: | Revision:

one / src / lcm / LifeCycleActions.cc @ d5837dcb

History | View | Annotate | Download (33.2 KB)

1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs        */
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 "LifeCycleManager.h"
18
#include "Nebula.h"
19

    
20
void  LifeCycleManager::deploy_action(int vid)
21
{
22
    VirtualMachine *    vm;
23
    ostringstream       os;
24

    
25
    vm = vmpool->get(vid,true);
26

    
27
    if ( vm == 0 )
28
    {
29
        return;
30
    }
31

    
32
    if ( vm->get_state() == VirtualMachine::ACTIVE )
33
    {
34
        Nebula&           nd = Nebula::instance();
35
        TransferManager * tm = nd.get_tm();
36
        time_t            thetime = time(0);
37
        int               cpu,mem,disk;
38

    
39
        VirtualMachine::LcmState vm_state;
40
        TransferManager::Actions tm_action;
41

    
42
        //----------------------------------------------------
43
        //                 PROLOG STATE
44
        //----------------------------------------------------
45

    
46
        vm->get_requirements(cpu,mem,disk);
47

    
48
        if (hpool->add_capacity(vm->get_hid(),vm->get_oid(),cpu,mem,disk) == -1)
49
        {
50
            //The host has been deleted, move VM to FAILURE
51

    
52
            vm->log("LCM", Log::ERROR, "deploy_action, Host has been removed.");
53

    
54
            vm->set_state(VirtualMachine::FAILURE);
55

    
56
            vm->set_resched(false);
57

    
58
            map<string, string> empty;
59
            vm->update_info(0, 0, -1, -1, empty);
60

    
61
            vmpool->update(vm);
62

    
63
            vm->set_stime(thetime);
64
            vm->set_etime(thetime);
65

    
66
            vm->set_vm_info();
67

    
68
            vm->set_reason(History::ERROR);
69

    
70
            vmpool->update_history(vm);
71

    
72
            vm->unlock();
73

    
74
            nd.get_dm()->trigger(DispatchManager::FAILED, vid);
75

    
76
            return;
77
        }
78

    
79
        vm_state  = VirtualMachine::PROLOG;
80
        tm_action = TransferManager::PROLOG;
81

    
82
        if (vm->hasPreviousHistory())
83
        {
84
            if (vm->get_previous_action() == History::STOP_ACTION)
85
            {
86
                vm_state  = VirtualMachine::PROLOG_RESUME;
87
                tm_action = TransferManager::PROLOG_RESUME;
88
            }
89
            else if (vm->get_previous_action() == History::UNDEPLOY_ACTION ||
90
                     vm->get_previous_action() == History::UNDEPLOY_HARD_ACTION)
91
            {
92
                vm_state  = VirtualMachine::PROLOG_UNDEPLOY;
93
                tm_action = TransferManager::PROLOG_RESUME;
94
            }
95
        }
96

    
97
        vm->set_state(vm_state);
98

    
99
        vmpool->update(vm);
100

    
101
        vm->set_stime(thetime);
102

    
103
        vm->set_prolog_stime(thetime);
104

    
105
        vmpool->update_history(vm);
106

    
107
        vm->log("LCM", Log::INFO, "New VM state is PROLOG.");
108

    
109
        //----------------------------------------------------
110

    
111
        tm->trigger(tm_action,vid);
112
    }
113
    else
114
    {
115
        vm->log("LCM", Log::ERROR, "deploy_action, VM in a wrong state.");
116
    }
117

    
118
    vm->unlock();
119

    
120
    return;
121
}
122

    
123
/* -------------------------------------------------------------------------- */
124
/* -------------------------------------------------------------------------- */
125

    
126
void  LifeCycleManager::suspend_action(int vid)
127
{
128
    VirtualMachine *    vm;
129

    
130
    vm = vmpool->get(vid,true);
131

    
132
    if ( vm == 0 )
133
    {
134
        return;
135
    }
136

    
137
    if (vm->get_state()     == VirtualMachine::ACTIVE &&
138
        vm->get_lcm_state() == VirtualMachine::RUNNING)
139
    {
140
        Nebula&                 nd = Nebula::instance();
141
        VirtualMachineManager * vmm = nd.get_vmm();
142

    
143
        //----------------------------------------------------
144
        //                SAVE_SUSPEND STATE
145
        //----------------------------------------------------
146

    
147
        vm->set_state(VirtualMachine::SAVE_SUSPEND);
148

    
149
        vm->set_resched(false);
150

    
151
        vmpool->update(vm);
152

    
153
        vm->set_action(History::SUSPEND_ACTION);
154

    
155
        vmpool->update_history(vm);
156

    
157
        vm->log("LCM", Log::INFO, "New VM state is SAVE_SUSPEND");
158

    
159
        //----------------------------------------------------
160

    
161
        vmm->trigger(VirtualMachineManager::SAVE,vid);
162
    }
163
    else
164
    {
165
        vm->log("LCM", Log::ERROR, "suspend_action, VM in a wrong state.");
166
    }
167

    
168
    vm->unlock();
169

    
170
    return;
171
}
172

    
173
/* -------------------------------------------------------------------------- */
174
/* -------------------------------------------------------------------------- */
175

    
176
void  LifeCycleManager::stop_action(int vid)
177
{
178
    VirtualMachine *    vm;
179

    
180
    vm = vmpool->get(vid,true);
181

    
182
    if ( vm == 0 )
183
    {
184
        return;
185
    }
186

    
187
    if (vm->get_state()     == VirtualMachine::ACTIVE &&
188
        vm->get_lcm_state() == VirtualMachine::RUNNING)
189
    {
190
        Nebula&                 nd = Nebula::instance();
191
        VirtualMachineManager * vmm = nd.get_vmm();
192

    
193
        //----------------------------------------------------
194
        //                SAVE_STOP STATE
195
        //----------------------------------------------------
196

    
197
        vm->set_state(VirtualMachine::SAVE_STOP);
198

    
199
        vm->set_resched(false);
200

    
201
        vmpool->update(vm);
202

    
203
        vm->set_action(History::STOP_ACTION);
204

    
205
        vmpool->update_history(vm);
206

    
207
        vm->log("LCM", Log::INFO, "New VM state is SAVE_STOP");
208

    
209
        //----------------------------------------------------
210

    
211
        vmm->trigger(VirtualMachineManager::SAVE,vid);
212
    }
213
    else
214
    {
215
        vm->log("LCM", Log::ERROR, "stop_action, VM in a wrong state.");
216
    }
217

    
218
    vm->unlock();
219

    
220
    return;
221
}
222

    
223
/* -------------------------------------------------------------------------- */
224
/* -------------------------------------------------------------------------- */
225

    
226
void  LifeCycleManager::migrate_action(int vid)
227
{
228
    VirtualMachine *    vm;
229

    
230
    vm = vmpool->get(vid,true);
231

    
232
    if ( vm == 0 )
233
    {
234
        return;
235
    }
236

    
237
    if (vm->get_state()     == VirtualMachine::ACTIVE &&
238
        vm->get_lcm_state() == VirtualMachine::RUNNING)
239
    {
240
        Nebula&                 nd  = Nebula::instance();
241
        VirtualMachineManager * vmm = nd.get_vmm();
242
        int                     cpu,mem,disk;
243

    
244
        //----------------------------------------------------
245
        //                SAVE_MIGRATE STATE
246
        //----------------------------------------------------
247

    
248
        vm->set_state(VirtualMachine::SAVE_MIGRATE);
249

    
250
        vm->set_resched(false);
251

    
252
        vmpool->update(vm);
253

    
254
        vm->set_stime(time(0));
255

    
256
        vm->set_previous_action(History::MIGRATE_ACTION);
257

    
258
        vmpool->update_history(vm);
259

    
260
        vm->get_requirements(cpu,mem,disk);
261

    
262
        hpool->add_capacity(vm->get_hid(), vm->get_oid(), cpu, mem, disk);
263

    
264
        vm->log("LCM", Log::INFO, "New VM state is SAVE_MIGRATE");
265

    
266
        //----------------------------------------------------
267

    
268
        vmm->trigger(VirtualMachineManager::SAVE,vid);
269
    }
270
    else
271
    {
272
        vm->log("LCM", Log::ERROR, "migrate_action, VM in a wrong state.");
273
    }
274

    
275
    vm->unlock();
276

    
277
    return;
278
}
279

    
280
/* -------------------------------------------------------------------------- */
281
/* -------------------------------------------------------------------------- */
282

    
283
void  LifeCycleManager::live_migrate_action(int vid)
284
{
285
    VirtualMachine *    vm;
286
    ostringstream        os;
287

    
288
    vm = vmpool->get(vid,true);
289

    
290
    if ( vm == 0 )
291
    {
292
        return;
293
    }
294

    
295
    if (vm->get_state()     == VirtualMachine::ACTIVE &&
296
        vm->get_lcm_state() == VirtualMachine::RUNNING)
297
    {
298
        Nebula&                 nd = Nebula::instance();
299
        VirtualMachineManager * vmm = nd.get_vmm();
300
        int                     cpu,mem,disk;
301

    
302
        //----------------------------------------------------
303
        //                   MIGRATE STATE
304
        //----------------------------------------------------
305

    
306
        vm->set_state(VirtualMachine::MIGRATE);
307

    
308
        vm->set_resched(false);
309

    
310
        vmpool->update(vm);
311

    
312
        vm->set_stime(time(0));
313

    
314
        vm->set_previous_action(History::LIVE_MIGRATE_ACTION);
315

    
316
        vmpool->update_history(vm);
317

    
318
        vm->get_requirements(cpu,mem,disk);
319

    
320
        hpool->add_capacity(vm->get_hid(), vm->get_oid(), cpu, mem, disk);
321

    
322
        vm->log("LCM",Log::INFO,"New VM state is MIGRATE");
323

    
324
        //----------------------------------------------------
325

    
326
        vmm->trigger(VirtualMachineManager::MIGRATE,vid);
327
    }
328
    else
329
    {
330
        vm->log("LCM", Log::ERROR, "live_migrate_action, VM in a wrong state.");
331
    }
332

    
333
    vm->unlock();
334

    
335
    return;
336
}
337

    
338
/* -------------------------------------------------------------------------- */
339
/* -------------------------------------------------------------------------- */
340

    
341
void  LifeCycleManager::shutdown_action(int vid)
342
{
343
    VirtualMachine *    vm;
344

    
345
    vm = vmpool->get(vid,true);
346

    
347
    if ( vm == 0 )
348
    {
349
        return;
350
    }
351

    
352
    if (vm->get_state()     == VirtualMachine::ACTIVE &&
353
        (vm->get_lcm_state() == VirtualMachine::RUNNING ||
354
         vm->get_lcm_state() == VirtualMachine::UNKNOWN))
355
    {
356
        Nebula&                 nd = Nebula::instance();
357
        VirtualMachineManager * vmm = nd.get_vmm();
358

    
359
        //----------------------------------------------------
360
        //                  SHUTDOWN STATE
361
        //----------------------------------------------------
362

    
363
        vm->set_state(VirtualMachine::SHUTDOWN);
364

    
365
        vm->set_resched(false);
366

    
367
        vmpool->update(vm);
368

    
369
        vm->set_action(History::SHUTDOWN_ACTION);
370

    
371
        vmpool->update_history(vm);
372

    
373
        vm->log("LCM",Log::INFO,"New VM state is SHUTDOWN");
374

    
375
        //----------------------------------------------------
376

    
377
        vmm->trigger(VirtualMachineManager::SHUTDOWN,vid);
378
    }
379
    else
380
    {
381
        vm->log("LCM", Log::ERROR, "shutdown_action, VM in a wrong state.");
382
    }
383

    
384
    vm->unlock();
385

    
386
    return;
387
}
388

    
389
/* -------------------------------------------------------------------------- */
390
/* -------------------------------------------------------------------------- */
391

    
392
void  LifeCycleManager::undeploy_action(int vid, bool hard)
393
{
394
    VirtualMachine *    vm;
395

    
396
    vm = vmpool->get(vid,true);
397

    
398
    if ( vm == 0 )
399
    {
400
        return;
401
    }
402

    
403
    if (vm->get_state()     == VirtualMachine::ACTIVE &&
404
        (vm->get_lcm_state() == VirtualMachine::RUNNING ||
405
         vm->get_lcm_state() == VirtualMachine::UNKNOWN))
406
    {
407
        Nebula&                 nd = Nebula::instance();
408
        VirtualMachineManager * vmm = nd.get_vmm();
409

    
410
        //----------------------------------------------------
411
        //             SHUTDOWN_UNDEPLOY STATE
412
        //----------------------------------------------------
413

    
414
        vm->set_state(VirtualMachine::SHUTDOWN_UNDEPLOY);
415

    
416
        vm->set_resched(false);
417

    
418
        vmpool->update(vm);
419

    
420
        vm->log("LCM",Log::INFO,"New VM state is SHUTDOWN_UNDEPLOY");
421

    
422
        //----------------------------------------------------
423

    
424
        if (hard)
425
        {
426
            vm->set_action(History::UNDEPLOY_HARD_ACTION);
427

    
428
            vmm->trigger(VirtualMachineManager::CANCEL,vid);
429
        }
430
        else
431
        {
432
            vm->set_action(History::UNDEPLOY_ACTION);
433

    
434
            vmm->trigger(VirtualMachineManager::SHUTDOWN,vid);
435
        }
436

    
437
        vmpool->update_history(vm);
438
    }
439
    else
440
    {
441
        vm->log("LCM", Log::ERROR, "undeploy_action, VM in a wrong state.");
442
    }
443

    
444
    vm->unlock();
445

    
446
    return;
447
}
448

    
449

    
450
/* -------------------------------------------------------------------------- */
451
/* -------------------------------------------------------------------------- */
452

    
453
void  LifeCycleManager::poweroff_action(int vid)
454
{
455
    poweroff_action(vid, false);
456
}
457

    
458
/* -------------------------------------------------------------------------- */
459
/* -------------------------------------------------------------------------- */
460

    
461
void  LifeCycleManager::poweroff_hard_action(int vid)
462
{
463
    poweroff_action(vid, true);
464
}
465

    
466
/* -------------------------------------------------------------------------- */
467
/* -------------------------------------------------------------------------- */
468

    
469
void  LifeCycleManager::poweroff_action(int vid, bool hard)
470
{
471
    VirtualMachine *    vm;
472

    
473
    vm = vmpool->get(vid,true);
474

    
475
    if ( vm == 0 )
476
    {
477
        return;
478
    }
479

    
480
    if (vm->get_state()     == VirtualMachine::ACTIVE &&
481
        (vm->get_lcm_state() == VirtualMachine::RUNNING ||
482
         vm->get_lcm_state() == VirtualMachine::UNKNOWN))
483
    {
484
        Nebula&                 nd = Nebula::instance();
485
        VirtualMachineManager * vmm = nd.get_vmm();
486

    
487
        //----------------------------------------------------
488
        //             SHUTDOWN_POWEROFF STATE
489
        //----------------------------------------------------
490

    
491
        vm->set_state(VirtualMachine::SHUTDOWN_POWEROFF);
492

    
493
        vm->set_resched(false);
494

    
495
        vmpool->update(vm);
496

    
497
        vm->log("LCM",Log::INFO,"New VM state is SHUTDOWN_POWEROFF");
498

    
499
        //----------------------------------------------------
500

    
501
        if (hard)
502
        {
503
            vm->set_action(History::POWEROFF_HARD_ACTION);
504

    
505
            vmm->trigger(VirtualMachineManager::CANCEL,vid);
506
        }
507
        else
508
        {
509
            vm->set_action(History::POWEROFF_ACTION);
510

    
511
            vmm->trigger(VirtualMachineManager::SHUTDOWN,vid);
512
        }
513

    
514
        vmpool->update_history(vm);
515
    }
516
    else
517
    {
518
        vm->log("LCM", Log::ERROR, "poweroff_action, VM in a wrong state.");
519
    }
520

    
521
    vm->unlock();
522

    
523
    return;
524
}
525

    
526
/* -------------------------------------------------------------------------- */
527
/* -------------------------------------------------------------------------- */
528

    
529
void  LifeCycleManager::restore_action(int vid)
530
{
531
    VirtualMachine *    vm;
532
    ostringstream       os;
533

    
534
    vm = vmpool->get(vid,true);
535

    
536
    if ( vm == 0 )
537
    {
538
        return;
539
    }
540

    
541
    if (vm->get_state() == VirtualMachine::SUSPENDED)
542
    {
543
        Nebula&                 nd  = Nebula::instance();
544
        VirtualMachineManager * vmm = nd.get_vmm();
545
        time_t                  the_time = time(0);
546

    
547
        vm->log("LCM", Log::INFO, "Restoring VM");
548

    
549
        //----------------------------------------------------
550
        //            BOOT STATE (FROM SUSPEND)
551
        //----------------------------------------------------
552
        vm->set_state(VirtualMachine::ACTIVE);
553

    
554
        vm->set_state(VirtualMachine::BOOT_SUSPENDED);
555

    
556
        vm->cp_history();
557

    
558
        vmpool->update(vm); //update last_seq & state
559

    
560
        vm->set_stime(the_time);
561

    
562
        vm->set_running_stime(the_time);
563

    
564
        vmpool->update_history(vm);
565

    
566
        vm->log("LCM", Log::INFO, "New state is BOOT_SUSPENDED");
567

    
568
        //----------------------------------------------------
569

    
570
        vmm->trigger(VirtualMachineManager::RESTORE,vid);
571
    }
572
    else
573
    {
574
        vm->log("LCM", Log::ERROR, "restore_action, VM in a wrong state.");
575
    }
576

    
577
    vm->unlock();
578

    
579
    return;
580
}
581

    
582
/* -------------------------------------------------------------------------- */
583
/* -------------------------------------------------------------------------- */
584

    
585
void  LifeCycleManager::cancel_action(int vid)
586
{
587
    VirtualMachine *    vm;
588

    
589
    vm = vmpool->get(vid,true);
590

    
591
    if ( vm == 0 )
592
    {
593
        return;
594
    }
595

    
596
    if (vm->get_state()     == VirtualMachine::ACTIVE &&
597
        (vm->get_lcm_state() == VirtualMachine::RUNNING ||
598
         vm->get_lcm_state() == VirtualMachine::UNKNOWN))
599
    {
600
        Nebula&                 nd = Nebula::instance();
601
        VirtualMachineManager * vmm = nd.get_vmm();
602

    
603
        //----------------------------------------------------
604
        //                  CANCEL STATE
605
        //----------------------------------------------------
606

    
607
        vm->set_state(VirtualMachine::CANCEL);
608

    
609
        vm->set_resched(false);
610

    
611
        vmpool->update(vm);
612

    
613
        vm->set_action(History::SHUTDOWN_HARD_ACTION);
614

    
615
        vmpool->update_history(vm);
616

    
617
        vm->log("LCM", Log::INFO, "New state is CANCEL");
618

    
619
        //----------------------------------------------------
620

    
621
        vmm->trigger(VirtualMachineManager::CANCEL,vid);
622
    }
623
    else
624
    {
625
        vm->log("LCM", Log::ERROR, "cancel_action, VM in a wrong state.");
626
    }
627

    
628
    vm->unlock();
629

    
630
    return;
631
}
632

    
633
/* -------------------------------------------------------------------------- */
634
/* -------------------------------------------------------------------------- */
635

    
636
void  LifeCycleManager::restart_action(int vid)
637
{
638
    VirtualMachine *    vm;
639

    
640
    vm = vmpool->get(vid,true);
641

    
642
    if ( vm == 0 )
643
    {
644
        return;
645
    }
646

    
647
    if ((vm->get_state() == VirtualMachine::ACTIVE &&
648
        (vm->get_lcm_state() == VirtualMachine::UNKNOWN ||
649
         vm->get_lcm_state() == VirtualMachine::BOOT ||
650
         vm->get_lcm_state() == VirtualMachine::BOOT_UNKNOWN ||
651
         vm->get_lcm_state() == VirtualMachine::BOOT_POWEROFF ||
652
         vm->get_lcm_state() == VirtualMachine::BOOT_SUSPENDED ||
653
         vm->get_lcm_state() == VirtualMachine::BOOT_STOPPED ||
654
         vm->get_lcm_state() == VirtualMachine::BOOT_UNDEPLOY))
655
       ||vm->get_state() == VirtualMachine::POWEROFF)
656
    {
657
        Nebula&                 nd = Nebula::instance();
658
        VirtualMachineManager * vmm = nd.get_vmm();
659

    
660
        //----------------------------------------------------
661
        //       RE-START THE VM IN THE SAME HOST
662
        //----------------------------------------------------
663

    
664
        if (vm->get_state() == VirtualMachine::ACTIVE &&
665
            (vm->get_lcm_state() == VirtualMachine::BOOT ||
666
             vm->get_lcm_state() == VirtualMachine::BOOT_UNKNOWN ||
667
             vm->get_lcm_state() == VirtualMachine::BOOT_POWEROFF ||
668
             vm->get_lcm_state() == VirtualMachine::BOOT_SUSPENDED ||
669
             vm->get_lcm_state() == VirtualMachine::BOOT_STOPPED ||
670
             vm->get_lcm_state() == VirtualMachine::BOOT_UNDEPLOY))
671
        {
672
            vm->log("LCM", Log::INFO, "Sending BOOT command to VM again");
673
        }
674
        else if (vm->get_state() == VirtualMachine::ACTIVE &&
675
                 vm->get_lcm_state() == VirtualMachine::UNKNOWN)
676
        {
677
            vm->set_state(VirtualMachine::BOOT_UNKNOWN);
678

    
679
            vmpool->update(vm);
680

    
681
            vm->log("LCM", Log::INFO, "New VM state is BOOT_UNKNOWN");
682
        }
683
        else // if ( vm->get_state() == VirtualMachine::POWEROFF )
684
        {
685
            time_t the_time = time(0);
686

    
687
            vm->set_state(VirtualMachine::ACTIVE); // Only needed by poweroff
688
            vm->set_state(VirtualMachine::BOOT_POWEROFF);
689

    
690
            vm->cp_history();
691

    
692
            vmpool->update(vm);
693

    
694
            vm->set_stime(the_time);
695

    
696
            vm->set_running_stime(the_time);
697

    
698
            vmpool->update_history(vm);
699

    
700
            vm->log("LCM", Log::INFO, "New VM state is BOOT_POWEROFF");
701
        }
702

    
703
        vmm->trigger(VirtualMachineManager::DEPLOY,vid);
704
    }
705
    else
706
    {
707
        vm->log("LCM", Log::ERROR, "restart_action, VM in a wrong state.");
708
    }
709

    
710
    vm->unlock();
711

    
712
    return;
713
}
714

    
715
/* -------------------------------------------------------------------------- */
716
/* -------------------------------------------------------------------------- */
717

    
718
void LifeCycleManager::delete_action(int vid)
719
{
720
    VirtualMachine * vm;
721

    
722
    Nebula&           nd = Nebula::instance();
723
    DispatchManager * dm = nd.get_dm();
724
    TransferManager * tm = nd.get_tm();
725

    
726
    int image_id = -1;
727

    
728
    vm = vmpool->get(vid,true);
729

    
730
    if ( vm == 0 )
731
    {
732
        return;
733
    }
734

    
735

    
736
    if ( vm->get_state() != VirtualMachine::ACTIVE )
737
    {
738
        vm->log("LCM", Log::ERROR, "clean_action, VM in a wrong state.");
739
        vm->unlock();
740

    
741
        return;
742
    }
743

    
744
    switch(vm->get_lcm_state())
745
    {
746
        case VirtualMachine::CLEANUP_RESUBMIT:
747
        case VirtualMachine::CLEANUP_DELETE:
748
            vm->set_state(VirtualMachine::CLEANUP_DELETE);
749
            vmpool->update(vm);
750

    
751
            dm->trigger(DispatchManager::DONE, vid);
752
        break;
753

    
754
        case VirtualMachine::FAILURE:
755
            vm->set_state(VirtualMachine::CLEANUP_DELETE);
756
            vmpool->update(vm);
757

    
758
            tm->trigger(TransferManager::EPILOG_DELETE,vid);
759
            dm->trigger(DispatchManager::DONE, vid);
760
        break;
761

    
762
        default:
763
            clean_up_vm(vm, true, image_id);
764
            dm->trigger(DispatchManager::DONE, vid);
765
        break;
766
    }
767

    
768
    vm->unlock();
769

    
770
    if ( image_id != -1 )
771
    {
772
        ImagePool* ipool = nd.get_ipool();
773
        Image*     image = ipool->get(image_id, true);
774

    
775
        if ( image != 0 )
776
        {
777
            image->set_state(Image::ERROR);
778

    
779
            ipool->update(image);
780

    
781
            image->unlock();
782
        }
783
    }
784
}
785

    
786
/* -------------------------------------------------------------------------- */
787
/* -------------------------------------------------------------------------- */
788

    
789
void  LifeCycleManager::clean_action(int vid)
790
{
791
    VirtualMachine * vm;
792

    
793
    Nebula&           nd = Nebula::instance();
794
    DispatchManager * dm = nd.get_dm();
795
    TransferManager * tm = nd.get_tm();
796

    
797
    int image_id = -1;
798

    
799
    vm = vmpool->get(vid,true);
800

    
801
    if ( vm == 0 )
802
    {
803
        return;
804
    }
805

    
806
    if ( vm->get_state() != VirtualMachine::ACTIVE )
807
    {
808
        vm->log("LCM", Log::ERROR, "clean_action, VM in a wrong state.");
809
        vm->unlock();
810

    
811
        return;
812
    }
813

    
814
    switch(vm->get_lcm_state())
815
    {
816
        case VirtualMachine::CLEANUP_DELETE:
817
            vm->log("LCM", Log::ERROR, "clean_action, VM in a wrong state.");
818
        break;
819

    
820
        case VirtualMachine::CLEANUP_RESUBMIT:
821
            dm->trigger(DispatchManager::RESUBMIT, vid);
822
        break;
823

    
824
        case VirtualMachine::FAILURE:
825
            vm->set_state(VirtualMachine::CLEANUP_RESUBMIT);
826
            vmpool->update(vm);
827

    
828
            tm->trigger(TransferManager::EPILOG_DELETE,vid);
829
        break;
830

    
831
        default:
832
            clean_up_vm(vm, false, image_id);
833
        break;
834
    }
835

    
836
    vm->unlock();
837

    
838
    if ( image_id != -1 )
839
    {
840
        ImagePool* ipool = nd.get_ipool();
841
        Image*     image = ipool->get(image_id, true);
842

    
843
        if ( image != 0 )
844
        {
845
            image->set_state(Image::ERROR);
846

    
847
            ipool->update(image);
848

    
849
            image->unlock();
850
        }
851
    }
852
}
853

    
854
/* -------------------------------------------------------------------------- */
855
/* -------------------------------------------------------------------------- */
856

    
857
void  LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& image_id)
858
{
859
    int    cpu, mem, disk;
860
    time_t the_time = time(0);
861

    
862
    Nebula& nd = Nebula::instance();
863

    
864
    TransferManager *       tm  = nd.get_tm();
865
    VirtualMachineManager * vmm = nd.get_vmm();
866

    
867
    VirtualMachine::LcmState state = vm->get_lcm_state();
868
    int                      vid   = vm->get_oid();
869

    
870
    vm->log("LCM", Log::INFO, "New VM state is CLEANUP.");
871

    
872
    if (dispose)
873
    {
874
        vm->set_state(VirtualMachine::CLEANUP_DELETE);
875
        vm->set_action(History::DELETE_ACTION);
876
    }
877
    else
878
    {
879
        vm->set_state(VirtualMachine::CLEANUP_RESUBMIT);
880
        vm->set_action(History::DELETE_RECREATE_ACTION);
881
    }
882

    
883
    vm->set_resched(false);
884

    
885
    vm->delete_snapshots();
886

    
887
    map<string, string> empty;
888
    vm->update_info(0, 0, -1, -1, empty);
889

    
890
    vmpool->update(vm);
891

    
892
    vm->set_etime(the_time);
893
    vm->set_vm_info();
894
    vm->set_reason(History::USER);
895

    
896
    vm->get_requirements(cpu,mem,disk);
897
    hpool->del_capacity(vm->get_hid(), vm->get_oid(), cpu, mem, disk);
898

    
899
    switch (state)
900
    {
901
        case VirtualMachine::PROLOG:
902
        case VirtualMachine::PROLOG_RESUME:
903
        case VirtualMachine::PROLOG_UNDEPLOY:
904
            vm->set_prolog_etime(the_time);
905
            vmpool->update_history(vm);
906

    
907
            tm->trigger(TransferManager::DRIVER_CANCEL,vid);
908
            tm->trigger(TransferManager::EPILOG_DELETE,vid);
909
        break;
910

    
911
        case VirtualMachine::BOOT:
912
        case VirtualMachine::BOOT_UNKNOWN:
913
        case VirtualMachine::BOOT_POWEROFF:
914
        case VirtualMachine::BOOT_SUSPENDED:
915
        case VirtualMachine::BOOT_STOPPED:
916
        case VirtualMachine::BOOT_UNDEPLOY:
917
        case VirtualMachine::RUNNING:
918
        case VirtualMachine::UNKNOWN:
919
        case VirtualMachine::SHUTDOWN:
920
        case VirtualMachine::SHUTDOWN_POWEROFF:
921
        case VirtualMachine::CANCEL:
922
        case VirtualMachine::HOTPLUG_SNAPSHOT:
923
            vm->set_running_etime(the_time);
924
            vmpool->update_history(vm);
925

    
926
            vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
927
            vmm->trigger(VirtualMachineManager::CLEANUP,vid);
928
        break;
929

    
930
        case VirtualMachine::HOTPLUG:
931
            vm->clear_attach_disk();
932

    
933
            vm->set_running_etime(the_time);
934
            vmpool->update_history(vm);
935

    
936
            vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
937
            vmm->trigger(VirtualMachineManager::CLEANUP,vid);
938
        break;
939

    
940
        case VirtualMachine::HOTPLUG_NIC:
941
            vm->clear_attach_nic();
942

    
943
            vm->set_running_etime(the_time);
944
            vmpool->update_history(vm);
945

    
946
            vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
947
            vmm->trigger(VirtualMachineManager::CLEANUP,vid);
948
        break;
949

    
950
        case VirtualMachine::HOTPLUG_SAVEAS:
951
        case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF:
952
        case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
953
            tm->trigger(TransferManager::DRIVER_CANCEL, vid);
954

    
955
            vm->cancel_saveas_disk(image_id);
956

    
957
            vm->set_running_etime(the_time);
958
            vmpool->update_history(vm);
959

    
960
            vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
961
            vmm->trigger(VirtualMachineManager::CLEANUP,vid);
962
        break;
963

    
964
        case VirtualMachine::MIGRATE:
965
            vm->set_running_etime(the_time);
966
            vmpool->update_history(vm);
967

    
968
            vm->set_previous_etime(the_time);
969
            vm->set_previous_vm_info();
970
            vm->set_previous_running_etime(the_time);
971
            vm->set_previous_reason(History::USER);
972
            vmpool->update_previous_history(vm);
973

    
974
            hpool->del_capacity(vm->get_previous_hid(), vm->get_oid(), cpu, mem, disk);
975

    
976
            vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
977
            vmm->trigger(VirtualMachineManager::CLEANUP_BOTH,vid);
978
        break;
979

    
980
        case VirtualMachine::SAVE_STOP:
981
        case VirtualMachine::SAVE_SUSPEND:
982
            vm->set_running_etime(the_time);
983
            vmpool->update_history(vm);
984

    
985
            vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
986
            vmm->trigger(VirtualMachineManager::CLEANUP,vid);
987
        break;
988

    
989
        case VirtualMachine::SAVE_MIGRATE:
990
            vm->set_running_etime(the_time);
991
            vmpool->update_history(vm);
992

    
993
            vm->set_previous_etime(the_time);
994
            vm->set_previous_vm_info();
995
            vm->set_previous_running_etime(the_time);
996
            vm->set_previous_reason(History::USER);
997
            vmpool->update_previous_history(vm);
998

    
999
            hpool->del_capacity(vm->get_previous_hid(), vm->get_oid(), cpu, mem, disk);
1000

    
1001
            vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
1002
            vmm->trigger(VirtualMachineManager::CLEANUP_PREVIOUS,vid);
1003
        break;
1004

    
1005
        case VirtualMachine::PROLOG_MIGRATE:
1006
            vm->set_prolog_etime(the_time);
1007
            vmpool->update_history(vm);
1008

    
1009
            tm->trigger(TransferManager::DRIVER_CANCEL,vid);
1010
            tm->trigger(TransferManager::EPILOG_DELETE_BOTH,vid);
1011
        break;
1012

    
1013
        case VirtualMachine::EPILOG_STOP:
1014
        case VirtualMachine::EPILOG_UNDEPLOY:
1015
        case VirtualMachine::EPILOG:
1016
            vm->set_epilog_etime(the_time);
1017
            vmpool->update_history(vm);
1018

    
1019
            tm->trigger(TransferManager::DRIVER_CANCEL,vid);
1020
            tm->trigger(TransferManager::EPILOG_DELETE,vid);
1021
        break;
1022

    
1023
        default: //LCM_INIT,CLEANUP_RESUBMIT, CLEANUP_DELETE, FAILURE
1024
        break;
1025
    }
1026
}
1027

    
1028
/* -------------------------------------------------------------------------- */
1029
/* -------------------------------------------------------------------------- */
1030

    
1031
void  LifeCycleManager::recover(VirtualMachine * vm, bool success)
1032
{
1033
    LifeCycleManager::Actions lcm_action = LifeCycleManager::FINALIZE;
1034

    
1035
    Nebula&           nd = Nebula::instance();
1036
    DispatchManager * dm = nd.get_dm();
1037

    
1038
    switch (vm->get_lcm_state())
1039
    {
1040
        //----------------------------------------------------------------------
1041
        // Direct recovery states
1042
        //----------------------------------------------------------------------
1043
        case VirtualMachine::LCM_INIT:
1044
        case VirtualMachine::RUNNING:
1045
            return;
1046

    
1047
        case VirtualMachine::CLEANUP_DELETE:
1048
            dm->trigger(DispatchManager::DONE, vm->get_oid());
1049
            return;
1050

    
1051
        case VirtualMachine::CLEANUP_RESUBMIT:
1052
            dm->trigger(DispatchManager::RESUBMIT, vm->get_oid());
1053
            return;
1054

    
1055
        case VirtualMachine::UNKNOWN:
1056
            vm->set_state(VirtualMachine::RUNNING);
1057
            vmpool->update(vm);
1058
            return;
1059

    
1060
        case VirtualMachine::FAILURE:
1061
            dm->trigger(DispatchManager::FAILED,vm->get_oid());
1062
            return;
1063

    
1064
        //----------------------------------------------------------------------
1065
        // Recover through re-triggering LCM events
1066
        //----------------------------------------------------------------------
1067
        case VirtualMachine::PROLOG:
1068
        case VirtualMachine::PROLOG_MIGRATE:
1069
        case VirtualMachine::PROLOG_RESUME:
1070
        case VirtualMachine::PROLOG_UNDEPLOY:
1071
            if (success)
1072
            {
1073
                lcm_action = LifeCycleManager::PROLOG_SUCCESS;
1074
            }
1075
            else
1076
            {
1077
                lcm_action = LifeCycleManager::PROLOG_FAILURE;
1078
            }
1079
        break;
1080

    
1081
        case VirtualMachine::EPILOG:
1082
        case VirtualMachine::EPILOG_STOP:
1083
        case VirtualMachine::EPILOG_UNDEPLOY:
1084
            if (success)
1085
            {
1086
                lcm_action = LifeCycleManager::EPILOG_SUCCESS;
1087
            }
1088
            else
1089
            {
1090
                lcm_action = LifeCycleManager::EPILOG_FAILURE;
1091
            }
1092
        break;
1093

    
1094
        case VirtualMachine::HOTPLUG_SAVEAS:
1095
        case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF:
1096
        case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
1097
            if (success)
1098
            {
1099
                lcm_action = LifeCycleManager::SAVEAS_HOT_SUCCESS;
1100
            }
1101
            else
1102
            {
1103
                lcm_action = LifeCycleManager::SAVEAS_HOT_FAILURE;
1104
            }
1105
        break;
1106

    
1107
        case VirtualMachine::BOOT:
1108
        case VirtualMachine::BOOT_UNKNOWN:
1109
        case VirtualMachine::BOOT_POWEROFF:
1110
        case VirtualMachine::BOOT_SUSPENDED:
1111
        case VirtualMachine::BOOT_STOPPED:
1112
        case VirtualMachine::BOOT_UNDEPLOY:
1113
        case VirtualMachine::MIGRATE:
1114
            if (success)
1115
            {
1116
                //Auto-generate deploy-id it'll work for Xen, KVM and VMware
1117
                if (vm->get_deploy_id().empty())
1118
                {
1119
                    ostringstream oss;
1120

    
1121
                    oss << "one-" << vm->get_oid();
1122

    
1123
                    vm->update_info(oss.str());
1124
                }
1125

    
1126
                lcm_action = LifeCycleManager::DEPLOY_SUCCESS;
1127
            }
1128
            else
1129
            {
1130
                lcm_action = LifeCycleManager::DEPLOY_FAILURE;
1131
            }
1132
        break;
1133

    
1134
        case VirtualMachine::SHUTDOWN:
1135
        case VirtualMachine::SHUTDOWN_POWEROFF:
1136
        case VirtualMachine::SHUTDOWN_UNDEPLOY:
1137
            if (success)
1138
            {
1139
                lcm_action = LifeCycleManager::SHUTDOWN_SUCCESS;
1140
            }
1141
            else
1142
            {
1143
                lcm_action = LifeCycleManager::SHUTDOWN_FAILURE;
1144
            }
1145
        break;
1146

    
1147
        case VirtualMachine::CANCEL:
1148
            if (success)
1149
            {
1150
                lcm_action = LifeCycleManager::CANCEL_SUCCESS;
1151
            }
1152
            else
1153
            {
1154
                lcm_action = LifeCycleManager::CANCEL_FAILURE;
1155
            }
1156
        break;
1157

    
1158
        case VirtualMachine::SAVE_STOP:
1159
        case VirtualMachine::SAVE_SUSPEND:
1160
        case VirtualMachine::SAVE_MIGRATE:
1161
            if (success)
1162
            {
1163
                lcm_action = LifeCycleManager::SAVE_SUCCESS;
1164
            }
1165
            else
1166
            {
1167
                lcm_action = LifeCycleManager::SAVE_FAILURE;
1168
            }
1169
        break;
1170

    
1171
        case VirtualMachine::HOTPLUG:
1172
            if (success)
1173
            {
1174
                lcm_action = LifeCycleManager::ATTACH_SUCCESS;
1175
            }
1176
            else
1177
            {
1178
                lcm_action = LifeCycleManager::ATTACH_FAILURE;
1179
            }
1180
        break;
1181

    
1182
        case VirtualMachine::HOTPLUG_NIC:
1183
            if (success)
1184
            {
1185
                lcm_action = LifeCycleManager::ATTACH_NIC_SUCCESS;
1186
            }
1187
            else
1188
            {
1189
                lcm_action = LifeCycleManager::ATTACH_NIC_FAILURE;
1190
            }
1191
        break;
1192

    
1193
        //This is for all snapshot actions (create, delete & revert)
1194
        case VirtualMachine::HOTPLUG_SNAPSHOT:
1195
            lcm_action = LifeCycleManager::SNAPSHOT_CREATE_FAILURE;
1196
        break;
1197
    }
1198

    
1199
    if (lcm_action != LifeCycleManager::FINALIZE)
1200
    {
1201
        trigger(lcm_action, vm->get_oid());
1202
    }
1203
}
1204