Statistics
| Branch: | Tag: | Revision:

root / ui / static / snf / js / ui / web / ui_icon_view.js @ 643de8c0

History | View | Annotate | Download (26.6 kB)

1
;(function(root){
2

    
3
    // root
4
    var root = root;
5
    
6
    // setup namepsaces
7
    var snf = root.synnefo = root.synnefo || {};
8
    var models = snf.models = snf.models || {}
9
    var storage = snf.storage = snf.storage || {};
10
    var ui = snf.ui = snf.ui || {};
11
    var util = snf.util = snf.util || {};
12

    
13
    var views = snf.views = snf.views || {}
14

    
15
    // shortcuts
16
    var bb = root.Backbone;
17
    
18
    // handle extended info toggler
19
    views.VMActionErrorView = views.View.extend({
20
    
21
        initialize: function (vm, view) {
22
            this.vm = vm;
23
            this.view = view;
24
            this.vm_view = this.view.vm(vm);
25

    
26
            this.has_error = false;
27
            
28
            this.error = this.vm_view.find(".action-error");
29
            this.close = this.vm_view.find(".close-action-error");
30
            this.show_btn = this.vm_view.find(".show-action-error");
31

    
32
            this.init_handlers();
33
            this.update_layout();
34
        },
35

    
36
        init_handlers: function() {
37
            // action call failed notify the user
38
            this.vm.bind("action:fail", _.bind(function(args){
39
                if (this.vm.action_error) {
40
                    this.has_error = true;
41
                    var action = "undefined";
42
                    try {
43
                        action = args[0].ajax.error_params.extra_details['Action'];
44
                    } catch (err) {console.log(err)};
45
                    
46
                    this.error.find(".action").text(action);
47
                    this.error.show();
48
                }
49
            }, this));
50
            
51
            // show error overlay
52
            this.show_btn.click(_.bind(function() {
53
                this.show_error_overlay(this.vm.action_error);
54
                this.vm.reset_action_error();
55
            }, this));
56
            
57
            // user requests to forget about the error
58
            this.close.click(_.bind(_.bind(function() {
59
                this.error.hide();
60
                this.vm.reset_action_error();
61
            }, this)));
62
            
63
            // hide error message if action fail get reset
64
            this.vm.bind("action:fail:reset", _.bind(function(){
65
                this.error.hide();
66
            }, this));
67
        },
68

    
69
        show_error_overlay: function(arguments) {
70
            var xhr = arguments[0];
71
            var args = util.parse_api_error(arguments);
72
            
73
            // force logout if UNAUTHORIZED request arrives
74
            if (args.code == 401) { snf.ui.logout(); return };
75

    
76
            var error_entry = [args.ns, args.code, args.message, args.type, args.details, args];
77
            ui.main.error_view.show_error.apply(ui.main.error_view, error_entry);
78
        },
79

    
80
        update_layout: function() {
81
            if (this.vm.action_error) {
82
                this.error.show();
83
            }
84
        }
85
    });
86

    
87
    // handle extended info toggler
88
    views.IconInfoView = views.View.extend({
89
    
90
        initialize: function (vm, view) {
91
            this.vm = vm;
92
            this.view = view;
93
            this.vm_view = this.view.vm(vm);
94
            
95
            this.info_link = $(".toggler", this.vm_view);
96
            this.el = $("div.info-content", this.vm_view);
97
            this.toggler = $(".toggler", this.vm_view);
98
            this.label = $(".label", this.vm_view);
99

    
100
            this.set_handlers();
101
        },
102

    
103
        set_handlers: function() {
104
            this.info_link.click(_.bind(function(){
105
                this.el.slideToggle();
106
                this.view.vm(this.vm).toggleClass("light-background");
107

    
108
                if (this.toggler.hasClass("open")) {
109
                    this.toggler.removeClass("open");
110
                    this.vm.do_update_stats = false;
111
                } else {
112
                    this.toggler.addClass("open");
113
                    this.vm.do_update_stats = true;
114
                }
115
                
116
                var self = this;
117
                window.setTimeout(function() {$(self.view).trigger("resize")}, 300);
118
            }, this));
119

    
120
            this.$(".stats-report").click(_.bind(function(){
121
                snf.ui.main.show_vm_details(this.vm);
122
            }, this))
123
        }
124
    
125
    })
126

    
127
    // rename handler view
128
    // only icon view contains rename capability
129
    views.IconRenameView = views.View.extend({
130
        
131
        initialize: function(vm, view) {
132
            this.vm = vm;
133
            this.view = view;
134
            // name container
135
            this.el = $('div#' + this.view.id_tpl + vm.id + " div.name").get(0);
136
            // name inline element
137
            this.name = this.$('span.name');
138
            // rename button
139
            this.rename = this.$('span.rename');
140
            // save button
141
            this.save = this.$('.save');
142
            // cancel rename button
143
            this.cancel = this.$('.cancel');
144
            // where to place the input field
145
            this.edit_cont = this.$(".namecontainer");
146
            // buttons container
147
            this.buttons = this.$(".editbuttons");
148
            // current state
149
            this.renaming = false;
150
            // init event handlers
151
            this.set_handlers();
152
            // paint
153
            this.update_layout();
154
            views.IconRenameView.__super__.initialize.call(this);
155
        },
156
        
157
        // update elements visibility/state
158
        update_layout: function() {
159
            // if in renaming state
160
            if (this.renaming) {
161
                // if name is hidden we are already in renaming state
162
                // dont do nothing
163
                if (this.name.is(":hidden")){return}
164
                
165
                // hide name element to make space for the 
166
                // text input
167
                this.name.hide();
168
                this.rename.hide();
169
                // show confirm/cancel buttons
170
                this.buttons.show();
171
                // create text element
172
                this.create_input();
173
            } else {
174
                // name is visible not in edit mode
175
                if (this.name.is(":visible")){return}
176

    
177
                this.name.show();
178
                this.rename.show();
179
                this.buttons.hide();
180
                this.remove_input();
181
            }
182
        },
183
        
184
        // create rename input field and set appropriate 
185
        // event handlers
186
        create_input: function() {
187
            var self = this;
188
            this.edit_cont.append('<input class="vm-rename nametextbox" type="text" />');
189
            this.$('input').val(this.vm.get('name'));
190
            // give edit focus
191
            this.$('input').focus();
192
            // handle enter press
193
            this.$('input').keypress(function(ev){
194
                if (ev.charCode == 13) {
195
                    self.submit();
196
                }
197
            })
198
        },
199
        
200
        // remove input element
201
        remove_input: function() {
202
            this.$('input').remove();
203
        },
204
        
205
        // initialize event handlers
206
        set_handlers: function() {
207
            var self = this;
208
            // start rename when rename button is pressed
209
            this.rename.click(function() {
210
                self.renaming = true;
211
                self.update_layout();
212
            });
213
            
214
            // double click on name
215
            $(this.el).dblclick(function() {
216
                self.renaming = true;
217
                self.update_layout();
218
            });
219

    
220
            // cancel rename
221
            this.cancel.click(function() {
222
                self.renaming = false;
223
                self.update_layout();
224
            })
225
            
226
            // apply the rename
227
            // TODO: check if name is equal than the previous value
228
            this.save.click(function() {
229
                self.submit();
230
            })
231
        },
232

    
233
        submit: function() {
234
            var value = _(self.$('input').val()).trim();
235
            if (value == "") { return };
236
            this.renaming = false;
237
            this.vm.rename(self.$('input').val());
238
            this.update_layout();
239
        }
240
    });
241
    
242
    // VM connect interaction view
243
    views.IconVMConnectView = views.View.extend({
244
        
245
        initialize: function(vm, view) {
246
            // parent view (single, icon, list)
247
            this.parent = view;
248
            this.vm = vm;
249
            this.el = view.vm(vm);
250
            this.set_handlers();
251
            views.IconVMConnectView.__super__.initialize.call(this);
252
        },
253
        
254
        // set the appropriate handlers
255
        set_handlers: function() {
256
            // setup connect handler on vm icon interaction
257
            var el = this.el;
258
            var vm = this.vm;
259

    
260
            // element that triggers the connect handler
261
            var connect = el.find("div.connect-arrow, .logo");
262
            // connect status handler
263
            var handler = _.bind(this.connect_handler, {vm:vm, el:el, view:this.parent});
264
            $(connect).bind({'mouseover': handler, 'mouseleave': handler, 
265
                            'mousedown': handler, 'mouseup': handler,
266
                            'click': handler });
267
            
268
            // setup connect arrow display handlers 
269
            // while hovering vm container
270
            el.bind("mouseover", function(){
271
                if (vm.is_connectable()) {
272
                    el.find(".connect-border").show();
273
                    el.find(".connect-arrow").show();
274
                    el.find(".logo").css({cursor:"pointer"});
275
                } else {
276
                    el.find(".connect-border").hide();
277
                    el.find(".connect-arrow").hide();
278
                    el.find(".logo").css({cursor: "default"});
279
                }
280
            }).bind("mouseleave", function(){
281
                el.find(".connect-border").hide();
282
                el.find(".connect-arrow").hide();
283
            });
284
        },
285
        
286
        // connect arrow interaction handlers
287
        // BEWARE, this function has different context
288
        // than the View object itself, see set_vm_handlers
289
        connect_handler: function(event) {
290
            // nothing to do if we cannot connect to the vm
291
            if (!this.vm.is_connectable()) {return}
292
            
293
            var logo = this.el.find(".logo");
294
            var arrow = this.el.find(".connect-arrow");
295
            var border = this.el.find(".connect-border");
296
            
297
            // clear icon states
298
            logo.removeClass('single-image-state1 single-image-state2 single-image-state3 single-image-state4');
299
            
300
            // append the appropriate state class
301
            switch (event.type) {
302
                case "mouseover":       
303
                    logo.addClass('single-image-state4');
304
                    arrow.addClass('border-hover');
305
                    break;
306
                
307
                case "mouseleave":
308
                    logo.addClass('single-image-state1');
309
                    arrow.removeClass('border-hover');
310
                    break;
311

    
312
                case "mouseup":
313
                    logo.addClass('single-image-state4');
314
                    this.view.connect_overlay.show(this.vm);
315
                    break;
316

    
317
                case "mousedown":
318
                    logo.addClass('single-image-state2');
319
                    break;
320

    
321
                case "click":
322
                    //logo.addCLass('single-image-state4');
323
                    //this.view.connect_to_console(vm);
324
                    this.view.connect_overlay.show(this.vm);
325
                    break;
326

    
327
                default:
328
                    ;
329
            }
330
        },
331
        
332
        update_layout: function() {
333
        }
334

    
335
    });
336
    
337
    // vm metadata subview for icon and single view
338
    views.VMTagsView = views.View.extend({
339
        view_id: 'vm_tags',
340
        // metadata container selector
341
        el_sel: '.vm-metadata',
342
        // metadata row template
343
        tag_tpl: '<span class="tag-item"><span class="key">{0}</span><span class="value">{1}</span></span>',
344
        // how many tags to show
345
        tag_limit: 4,
346
        // truncate options (because container has different size on icon/single views)
347
        tag_key_truncate: 7,
348
        tag_value_truncate: 15,
349

    
350
        initialize: function(vm, view, toggle, limit, tag_key_truncate, tag_value_truncate) {
351
            this.tag_limit = limit || this.tag_limit;
352

    
353
            this.tag_key_truncate = tag_key_truncate || this.tag_key_truncate;
354
            this.tag_value_truncate = tag_value_truncate || this.tag_value_truncate;
355

    
356
            // does the view toggles the metadata container (single view)
357
            this.toggle = toggle || false;
358
            // parent view
359
            this.parent = view;
360
            this.vm = vm;
361
            this.el = this.parent.vm(vm);
362
            this.view_id = this.view_id + "_" + vm.id;
363

    
364
            // link to raise the metadata manager overlay
365
            this.link = this.$('a.manage-metadata');
366

    
367
            views.VMTagsView.__super__.initialize.call(this);
368
            this.set_handlers();
369
            this.update_layout();
370
        },
371
        
372
        // set the appropriate handlers
373
        set_handlers: function() {
374
            var self = this;
375
            // show the metadata editor overlay
376
            this.link.click(_.bind(function(ev) {
377
                ev.preventDefault();
378
                this.parent.metadata_view.show(this.vm);
379
            }, this));
380

    
381
            // tags have show/hide control ? bind events for them
382
            var self = this;
383
            if (this.toggle) {
384
                $(this.el).find(".tags-header").click(_.bind(function(){
385
                    $(self.el).find(".tags-content").slideToggle(600);
386
                    var toggler = $(this.el).find(".tags-header .cont-toggler");
387
                    
388
                    if (toggler.hasClass("open")) {
389
                        toggler.removeClass("open");
390
                    } else {
391
                        toggler.addClass("open");
392
                    }
393
                }, this));
394
                $(self.el).find(".tags-content").hide();
395
            }
396
        },
397
        
398
        // update metadata container and data
399
        update_layout: function() {
400

    
401
            // api metadata object
402
            var meta =  this.vm.get_meta();
403

    
404
            var i = 0;
405
            var cont = $(this.el).find(".items");
406

    
407
            // clear existing items
408
            cont.find(".tag-item").remove();
409
            
410
            // create tag elements
411
            _.each(meta, function(value, key){
412
                // respect the limit
413
                if (i > this.tag_limit) {
414
                    return;
415
                }
416
                
417
                // create element
418
                var new_el = $(this.tag_tpl.format(util.truncate(key, this.tag_key_truncate), 
419
                                                 util.truncate(": " + value, this.tag_value_truncate)));
420

    
421
                // add title attributes, improve accesibility
422
                // truncated values
423
                new_el.find("span.key").attr("title", key);
424
                new_el.find("span.value").attr("title", value);
425

    
426
                cont.append(new_el);
427
            }, this);
428
        }
429
    });
430
    
431

    
432
    // stats subview for single/icon views
433
    views.VMStatsView = views.View.extend({
434

    
435
        initialize: function(vm, view, options) {
436
            if (!options) {options = {}};
437
            this.vm = vm;
438
            this.parent = view;
439
            this.sel = options.el || this.el_sel || ".lower";
440
            this.el = this.parent.vm(vm).find(this.sel);
441
            
442
            // elements shortcuts
443
            this.cpu_loading = this.el.find(".cpu-graph .stat-busy");
444
            this.cpu_error = this.el.find(".cpu-graph .stat-error");
445
            this.cpu_img = this.el.find(".cpu-graph .stat-img");
446
            this.net_loading = this.el.find(".network-graph .stat-busy");
447
            this.net_error = this.el.find(".network-graph .stat-error");
448
            this.net_img = this.el.find(".network-graph .stat-img");
449

    
450
            this.loading = this.el.find(".stat-busy");
451
            this.error = this.el.find(".stat-error");
452
            this.img = this.el.find(".stat-img");
453
            
454
            // initial state paremeters
455
            this.stats = this.vm.get("stats");
456

    
457
            // timeseries or bar images ?
458
            this.stats_type = options.stats_type || "bar";
459

    
460
            views.VMStatsView.__super__.initialize.apply(this, arguments);
461
            this.set_handlers();
462
            this.update_layout();
463

    
464
            this.net_loading.show();
465
            this.net_error.hide();
466
            this.cpu_loading.show();
467
            this.cpu_error.hide();
468

    
469
            this.net_img.hide();
470
            this.cpu_img.hide();
471
        },
472

    
473
        
474
        set_handlers: function() {
475
            // update view state when vm stats update gets triggered
476
            this.vm.bind("stats:update", _.bind(function(){
477
                // update the layout
478
                this.update_layout();
479
            }, this));
480
        },
481
        
482
        get_images: function (type) {
483
            if (type == "bar") {
484
                return {'cpu': this.stats.cpuBar, 'net': this.stats.netBar };
485
            } else {
486
                return {'cpu': this.stats.cpuTimeSeries, 'net': this.stats.netTimeSeries };
487
            }
488
        },
489

    
490
        update_layout: function() {
491
            if (!this.vm.stats_available) {
492
                this.loading.show();
493
                this.img.hide();
494
                this.error.hide();
495
            } else {
496
                this.loading.hide();
497
                this.stats = this.vm.get("stats");
498
                var images = this.get_images(this.stats_type);
499

    
500
                if (images.cpu) {
501
                    this.cpu_img.attr({src:images.cpu}).show();
502
                    this.cpu_error.hide();
503
                } else {
504
                    this.cpu_img.hide();
505
                    this.cpu_error.show();
506
                }
507

    
508
                if (images.net) {
509
                    this.net_img.attr({src:images.net}).show();
510
                    this.net_error.hide();
511
                } else {
512
                    this.net_img.hide();
513
                    this.net_error.show();
514
                }
515
            }
516
            $(window).trigger("resize");
517
        }
518
    });
519

    
520
    views.VMDetailsView = views.View.extend({
521
        view_id: "vm_details",
522
        el_sel: '.vm-details',
523
        
524

    
525
        selectors: {
526
            'cpu': '.cpu-data',
527
            'ram': '.ram-data',
528
            'disk': '.disk-data',
529
            'image_name': '.image-data',
530
            'image_size': '.image-size-data'
531
        },
532

    
533
        initialize: function(vm, view) {
534
            this.parent = view;
535
            this.vm = vm;
536
            this.el = $(this.parent.vm(vm)).find(this.el_sel).get(0);
537
            this.view_id = "vm_{0}_details".format(vm.id);
538

    
539
            views.VMDetailsView.__super__.initialize.call(this);
540
            this.update_layout();
541
        },
542

    
543
        update_layout: function() {
544
            var image = this.vm.get_image();
545
            var flavor = this.vm.get_flavor();
546
            if (!flavor || !image) {
547
                return;
548
            }
549

    
550
            this.sel('image_name').text(util.truncate(image.get('name'), 13)).attr("title", image.get('name'));
551
            this.sel('image_size').text(image.get('metadata').values.size).attr('title', image.get('metadata').values.size);
552

    
553
            this.sel('cpu').text(flavor.get('cpu'));
554
            this.sel('ram').text(flavor.get('ram'));
555
            this.sel('disk').text(flavor.get('disk'));
556
        }
557
    });
558
    
559
    // VMs icon view
560
    views.IconView = views.VMListView.extend({
561
        
562
        // view id (this could be used to identify 
563
        // the view object from global context
564
        view_id: 'vm_icon',
565

    
566
        el: '#machinesview-icon',
567
        id_tpl: 'icon-vm-',
568

    
569
        selectors: {
570
            'vms': '.machine-container',
571
            'vm': '#icon-vm-{0}',
572
            'view': '#machinesview-icon',
573
            'tpl': '#machinesview-icon.standard #machine-container-template',
574
            'spinner': '.large-spinner',
575
            'vm_spinner': '.machine-container#icon-vm-{0} .state .spinner',
576
            'vm_wave': '.machine-container#icon-vm-{0} .wave',
577
            'vm_cont_active': '#machinesview-icon.standard .running',
578
            'vm_cont_terminated': '#machinesview-icon.standard .terminated'
579
        },
580
            
581
        reset: function() {},
582
        // overload show function
583
        show_view: function() {
584
            $(this.el).show();
585
            this.__update_layout();
586
        },
587

    
588
        post_update_vm: function(vm) {
589
        },
590

    
591
        // identify vm model instance id based on DOM element
592
        vm_id_for_element: function(el) {
593
            return el.attr('id').replace("icon-vm-","");
594
        },
595
        
596
        // set generic view handlers
597
        set_handlers: function() {
598
        },  
599
        
600
        // stuff to do when a new vm has been created.
601
        // - create vm subviews
602
        post_add: function(vm) {
603
            // rename views index
604
            this.rename_views = this.rename_views || {};
605
            this.stats_views = this.stats_views || {};
606
            this.connect_views = this.connect_views || {};
607
            this.tags_views = this.tags_views || {};
608
            this.details_views = this.details_views || {};
609
            this.info_views = this.info_views || {};
610
            this.action_error_views = this.action_error_views || {};
611
            this.action_views = this.action_views || {};
612

    
613
            this.action_views[vm.id] = new views.VMActionsView(vm, this, this.vm(vm), this.hide_actions);
614
            this.rename_views[vm.id] = new views.IconRenameView(vm, this);
615
            this.stats_views[vm.id] = new views.VMStatsView(vm, this, {el:'.vm-stats'});
616
            this.connect_views[vm.id] = new views.IconVMConnectView(vm, this);
617
            this.tags_views[vm.id] = new views.VMTagsView(vm, this);
618
            this.details_views[vm.id] = new views.VMDetailsView(vm, this);
619
            this.info_views[vm.id] = new views.IconInfoView(vm, this);
620
            this.action_error_views[vm.id] = new views.VMActionErrorView(vm, this);
621
        },
622
        
623
        // vm specific event handlers
624
        set_vm_handlers: function(vm) {
625
            var el = this.vm(vm);
626

    
627
        },
628

    
629
        check_terminated_is_empty: function() {
630
            // hide/show terminated container
631
            if (this.$(".terminated .machine-container").length == 0) {
632
                this.$(".terminated").hide()
633
            } else {
634
                this.$(".terminated").show()
635
            }
636

    
637
            $(window).trigger("resize");
638
        },
639
        
640
        // generic stuff to do on each view update
641
        // called once after each vm has been updated
642
        update_layout: function() {
643
            // TODO: why do we do this ??
644
            if (storage.vms.models.length > 0) {
645
                this.$(".running").removeClass("disabled");
646
            } else {
647
                this.$(".running").addClass("disabled");
648
            }
649
            
650
            this.check_terminated_is_empty();
651
    
652
            // FIXME: code from old js api
653
            this.$("div.separator").show();
654
            this.$("div.machine-container:last-child").find("div.separator").hide();
655
            fix_v6_addresses();
656
        },
657

    
658
        // update vm details
659
        update_details: function(vm) {
660
            var el = this.vm(vm);
661
            // truncate name
662
            el.find("span.name").text(util.truncate(vm.get("name"), 40));
663
            // set ips
664
            el.find(".ipv4-text").text(vm.get_addresses().ip4 || "undefined");
665
            // TODO: fix ipv6 truncates and tooltip handler
666
            el.find(".ipv6-text").text(vm.get_addresses().ip6 || "undefined");
667
            // set the state (i18n ??)
668
            el.find(".status").text(STATE_TEXTS[vm.state()]);
669
            // set state class
670
            el.find(".state").removeClass().addClass(views.IconView.STATE_CLASSES[vm.state()].join(" "));
671
            // os icon
672
            el.find(".logo").css({'background-image': "url(" + this.get_vm_icon_path(vm, "medium") + ")"});
673
            
674
            el.removeClass("connectable");
675
            if (vm.is_connectable()) {
676
                el.addClass("connectable");
677
            }
678
            
679
            if (vm.get('status') == 'BUILD') {
680
                // update bulding progress
681
                el.find(".machine-ips").hide();
682
                el.find(".build-progress").show().text(vm.get('progress_message'));
683
            } else {
684
                // hide building progress
685
                el.find(".machine-ips").show()
686
                el.find(".build-progress").hide();
687
            }
688

    
689
            if (vm.state() == "DESTROY") {
690
                el.find(".machine-ips").hide();
691
                el.find(".build-progress").show().text("Terminating...");
692
            }
693

    
694
            icon_state = vm.is_active() ? "on" : "off";
695
            set_machine_os_image(el, "icon", icon_state, this.get_vm_icon_os(vm));
696
            
697
            // update subviews
698
            this.rename_views[vm.id].update_layout();
699
            this.stats_views[vm.id].update_layout();
700
            this.connect_views[vm.id].update_layout();
701
            this.tags_views[vm.id].update_layout();
702
            this.details_views[vm.id].update_layout();
703
        },
704

    
705
        post_remove_vm: function(vm) {
706
            this.check_terminated_is_empty();
707
            $(window).trigger("resize");
708
        },
709
            
710
        get_vm_icon_os: function(vm) {
711
            var os = vm.get_os();
712
            var icons = window.os_icons || views.IconView.VM_OS_ICONS;
713

    
714
            if (icons.indexOf(os) == -1) {
715
                os = "unknown";
716
            }
717

    
718
            return os;
719
        },
720

    
721
        // TODO: move to views.utils (the method and the VM_OS_ICON vars)
722
        get_vm_icon_path: function(vm, icon_type) {
723
            var os = vm.get_os();
724
            var icons = window.os_icons || views.IconView.VM_OS_ICONS;
725

    
726
            if (icons.indexOf(os) == -1) {
727
                os = "unknown";
728
            }
729

    
730
            return views.IconView.VM_OS_ICON_TPLS[icon_type].format(os);
731
        }
732
    })
733

    
734
    views.IconView.VM_OS_ICON_TPLS = {
735
        "medium": "/static/icons/machines/medium/{0}-sprite.png"
736
    }
737

    
738
    views.IconView.VM_OS_ICONS = window.os_icons || [];
739

    
740
    views.IconView.STATE_CLASSES = {
741
        'UNKNOWN':          ['state', 'error-state'],
742
        'BUILD':            ['state', 'build-state'],
743
        'REBOOT':           ['state', 'rebooting-state'],
744
        'STOPPED':          ['state', 'terminated-state'],
745
        'ACTIVE':           ['state', 'running-state'],
746
        'ERROR':            ['state', 'error-state'],
747
        'DELETED':           ['state', 'destroying-state'],
748
        'DESTROY':          ['state', 'destroying-state'],
749
        'BUILD_INIT':       ['state', 'build-state'], 
750
        'BUILD_COPY':       ['state', 'build-state'],
751
        'BUILD_FINAL':      ['state', 'build-state'],
752
        'SHUTDOWN':         ['state', 'shutting-state'],
753
        'START':            ['state', 'starting-state'],
754
        'CONNECT':          ['state', 'connecting-state'],
755
        'DISCONNECT':       ['state', 'disconnecting-state']
756
    };
757

    
758
})(this);