Revision 1e882dd7 snf-cyclades-app/synnefo/ui/static/snf/js/models.js

b/snf-cyclades-app/synnefo/ui/static/snf/js/models.js
123 123
        changedKeys: function() {
124 124
            return _.keys(this.changedAttributes() || {});
125 125
        },
126
            
127
        // return list of changed attributes that included in passed list
128
        // argument
129
        getKeysChanged: function(keys) {
130
            return _.intersection(keys, this.changedKeys());
131
        },
132
        
133
        // boolean check of keys changed
134
        keysChanged: function(keys) {
135
            return this.getKeysChanged(keys).length > 0;
136
        },
126 137

  
138
        // check if any of the passed attribues has changed
127 139
        hasOnlyChange: function(keys) {
128 140
            var ret = false;
129 141
            _.each(keys, _.bind(function(key) {
......
680 692
            // initialize interval
681 693
            this.init_stats_intervals(this.stats_update_interval);
682 694
            
683
            this.bind("change:progress", _.bind(this.update_building_progress, this));
684
            this.update_building_progress();
685

  
695
            // handle progress message on instance change
696
            this.bind("change", _.bind(this.update_status_message, this));
697
            // force update of progress message
698
            this.update_status_message(true);
699
            
686 700
            // default values
687 701
            this.bind("change:state", _.bind(function(){
688 702
                if (this.state() == "DESTROY") { 
......
717 731
            };
718 732
            return st;
719 733
        },
734
            
735
        get_diagnostics: function(success) {
736
            this.__make_api_call(this.get_diagnostics_url(),
737
                                 "read", // create so that sync later uses POST to make the call
738
                                 null, // payload
739
                                 function(data) {
740
                                     success(data);
741
                                 },  
742
                                 null, 'diagnostics');
743
        },
720 744

  
721
        update_building_progress: function() {
722
            if (this.is_building()) {
723
                var progress = this.get("progress");
724
                if (progress == 0) {
725
                    this.state("BUILD_INIT");
726
                    this.set({progress_message: BUILDING_MESSAGES['INIT']});
745
        has_diagnostics: function() {
746
            return this.get("diagnostics") && this.get("diagnostics").length;
747
        },
748

  
749
        get_progress_info: function() {
750
            // details about progress message
751
            // contains a list of diagnostic messages
752
            return this.get("status_messages");
753
        },
754

  
755
        get_status_message: function() {
756
            return this.get('status_message');
757
        },
758
        
759
        // extract status message from diagnostics
760
        status_message_from_diagnostics: function(diagnostics) {
761
            var valid_sources_map = synnefo.config.diagnostics_status_messages_map;
762
            var valid_sources = valid_sources_map[this.get('status')];
763
            if (!valid_sources) { return null };
764
            
765
            // filter messsages based on diagnostic source
766
            var messages = _.filter(diagnostics, function(diag) {
767
                return valid_sources.indexOf(diag.source) > -1;
768
            });
769

  
770
            var msg = messages[0];
771
            if (msg) {
772
              var message = msg.message;
773
              var message_tpl = snf.config.diagnostic_messages_tpls[msg.source];
774

  
775
              if (message_tpl) {
776
                  message = message_tpl.replace('MESSAGE', msg.message);
777
              }
778
              return message;
779
            }
780
            
781
            // no message to display, but vm in build state, display
782
            // finalizing message.
783
            if (this.is_building() == 'BUILD') {
784
                return synnefo.config.BUILDING_MESSAGES['FINAL'];
785
            }
786
            return null;
787
        },
788

  
789
        update_status_message: function(force) {
790
            // update only if one of the specified attributes has changed
791
            if (
792
              !this.keysChanged(['diagnostics', 'progress', 'status', 'state'])
793
                && !force
794
            ) { return };
795
            
796
            // if user requested to destroy the vm set the appropriate 
797
            // message.
798
            if (this.get('state') == "DESTROY") { 
799
                message = "Terminating..."
800
                this.set({status_message: message})
801
                return;
802
            }
803
            
804
            // set error message, if vm has diagnostic message display it as
805
            // progress message
806
            if (this.in_error_state()) {
807
                var d = this.get('diagnostics');
808
                if (d && d.length) {
809
                    var message = this.status_message_from_diagnostics(d);
810
                    this.set({status_message: message});
811
                } else {
812
                    this.set({status_message: null});
727 813
                }
728
                if (progress > 0 && progress < 99) {
729
                    this.state("BUILD_COPY");
730
                    this.get_copy_details(true, undefined, _.bind(function(details){
731
                        this.set({
732
                            progress_message: BUILDING_MESSAGES['COPY'].format(details.copy, 
733
                                                                               details.size, 
734
                                                                               details.progress)
735
                        });
736
                    }, this));
814
                return;
815
            }
816
            
817
            // identify building status message
818
            if (this.is_building()) {
819
                var self = this;
820
                var success = function(msg) {
821
                    self.set({status_message: msg});
737 822
                }
738
                if (progress == 100) {
739
                    this.state("BUILD_FINAL");
740
                    this.set({progress_message: BUILDING_MESSAGES['FINAL']});
823
                this.get_building_status_message(success);
824
                return;
825
            }
826

  
827
            this.set({status_message:null});
828
        },
829
            
830
        // get building status message. Asynchronous function since it requires
831
        // access to vm image.
832
        get_building_status_message: function(callback) {
833
            // no progress is set, vm is in initial build status
834
            var progress = this.get("progress");
835
            if (progress == 0 || !progress) {
836
                return callback(BUILDING_MESSAGES['INIT']);
837
            }
838
            
839
            // vm has copy progress, display copy percentage
840
            if (progress > 0 && progress <= 99) {
841
                this.get_copy_details(true, undefined, _.bind(
842
                    function(details){
843
                        callback(BUILDING_MESSAGES['COPY'].format(details.copy, 
844
                                                           details.size, 
845
                                                           details.progress));
846
                }, this));
847
                return;
848
            }
849

  
850
            // copy finished display FINAL message or identify status message
851
            // from diagnostics.
852
            if (progress >= 100) {
853
                if (!this.has_diagnostics()) {
854
                        callback(BUILDING_MESSAGES['FINAL']);
855
                } else {
856
                        var d = this.get("diagnostics");
857
                        var msg = this.status_message_from_diagnostics(d);
858
                        if (msg) {
859
                              callback(msg);
860
                        }
741 861
                }
742
            } else {
743 862
            }
744 863
        },
745 864

  
......
1094 1213
        },
1095 1214

  
1096 1215
        get_public_nic: function() {
1097
            return this.get_nics(function(n){ return n.get('network_id') == 'public'})[0];
1216
            return this.get_nics(function(n){ return n.get_network().is_public() })[0];
1098 1217
        },
1099 1218

  
1100 1219
        get_nic: function(net_id) {
......
1272 1391
            return this.url() + "/action";
1273 1392
        },
1274 1393

  
1394
        get_diagnostics_url: function() {
1395
            return this.url() + "/diagnostics";
1396
        },
1397

  
1275 1398
        get_connection_info: function(host_os, success, error) {
1276 1399
            var url = "/machines/connect";
1277 1400
            params = {
......
1689 1812
            return data;
1690 1813
        },
1691 1814

  
1815
        parse_vm_api_data: function(data) {
1816
            // do not add non existing DELETED entries
1817
            if (data.status && data.status == "DELETED") {
1818
                if (!this.get(data.id)) {
1819
                    return false;
1820
                }
1821
            }
1822

  
1823
            // OS attribute
1824
            if (this.has_meta(data)) {
1825
                data['OS'] = data.metadata.values.OS || "okeanos";
1826
            }
1827
            
1828
            if (!data.diagnostics) {
1829
                data.diagnostics = [];
1830
            }
1831

  
1832
            // network metadata
1833
            data['firewalls'] = {};
1834
            data['nics'] = {};
1835
            data['linked_to'] = [];
1836

  
1837
            if (data['attachments'] && data['attachments'].values) {
1838
                var nics = data['attachments'].values;
1839
                _.each(nics, function(nic) {
1840
                    var net_id = nic.network_id;
1841
                    var index = parseInt(NIC_REGEX.exec(nic.id)[2]);
1842
                    if (data['linked_to'].indexOf(net_id) == -1) {
1843
                        data['linked_to'].push(net_id);
1844
                    }
1845

  
1846
                    data['nics'][nic.id] = nic;
1847
                })
1848
            }
1849
            
1850
            // if vm has no metadata, no metadata object
1851
            // is in json response, reset it to force
1852
            // value update
1853
            if (!data['metadata']) {
1854
                data['metadata'] = {values:{}};
1855
            }
1856

  
1857
            return data;
1858
        },
1859

  
1692 1860
        add: function() {
1693 1861
            ret = models.VMS.__super__.add.apply(this, arguments);
1694 1862
            ret.each(function(r){
......
1751 1919
            return vm_data.metadata && vm_data.metadata.values
1752 1920
        },
1753 1921

  
1754
        parse_vm_api_data: function(data) {
1755
            // do not add non existing DELETED entries
1756
            if (data.status && data.status == "DELETED") {
1757
                if (!this.get(data.id)) {
1758
                    return false;
1759
                }
1760
            }
1761

  
1762
            // OS attribute
1763
            if (this.has_meta(data)) {
1764
                data['OS'] = data.metadata.values.OS || "okeanos";
1765
            }
1766
            
1767

  
1768
            // network metadata
1769
            data['firewalls'] = {};
1770
            data['nics'] = {};
1771
            data['linked_to'] = [];
1772

  
1773
            if (data['attachments'] && data['attachments'].values) {
1774
                var nics = data['attachments'].values;
1775
                _.each(nics, function(nic) {
1776
                    var net_id = nic.network_id;
1777
                    var index = parseInt(NIC_REGEX.exec(nic.id)[2]);
1778
                    if (data['linked_to'].indexOf(net_id) == -1) {
1779
                        data['linked_to'].push(net_id);
1780
                    }
1781

  
1782
                    data['nics'][nic.id] = nic;
1783
                })
1784
            }
1785
            
1786
            // if vm has no metadata, no metadata object
1787
            // is in json response, reset it to force
1788
            // value update
1789
            if (!data['metadata']) {
1790
                data['metadata'] = {values:{}};
1791
            }
1792

  
1793
            return data;
1794
        },
1795

  
1796 1922
        create: function (name, image, flavor, meta, extra, callback) {
1797 1923
            if (this.copy_image_meta) {
1798 1924
                if (image.get("OS")) {
......
1818 1944
                nic.get_network().update_state();
1819 1945
            });
1820 1946
            this.get_vm().bind("remove", function(){
1947
              try {
1821 1948
                this.collection.remove(this);
1949
              } catch (err) {};
1822 1950
            }, this);
1823 1951
            this.get_network().bind("remove", function(){
1824 1952
                try {

Also available in: Unified diff