Revision b085ae95

View differences:

src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb
55 55
                when "restart"      then self.restart
56 56
                when "saveas"       then self.save_as(action_hash['params'])
57 57
                when "shutdown"     then self.shutdown
58
		when "resubmit"     then self.resubmit
58
                when "resubmit"     then self.resubmit
59
                when "startvnc"     then self.startvnc
60
                when "stopvnc"      then self.stopvnc
59 61
                else
60 62
                    error_msg = "#{action_hash['perform']} action not " <<
61 63
                                " available for this resource"
......
118 120

  
119 121
            super(params['disk_id'].to_i, image.id)
120 122
        end
123
        
124
        def startvnc(port)
125
            result = self.info();
126
            if OpenNebula.is_error?(result)
127
                return result
128
            end
129
            
130
            if self['LCM_STATE'] != "3"
131
                return OpenNebula::Error.new("VM is not running");
132
            end
133
            
134
            if self['TEMPLATE/GRAPHICS/TYPE'] != "vnc"
135
                return OpenNebula::Error.new("VM has no VNC configured");
136
            end
137
                      
138
            if self['TEMPLATE/GRAPHICS/PORT']
139
                vnc_port = self['TEMPLATE/GRAPHICS/PORT']
140
            else
141
                return OpenNebula::Error.new("VM has no VNC port set");
142
            end
143
            
144
            if self['TEMPLATE/GRAPHICS/PASSWD']
145
                vnc_pw = self['TEMPLATE/GRAPHICS/PASSWD']
146
            else
147
                vnc_pw = ""
148
            end
149
            
150
            host = self['HISTORY/HOSTNAME']
151
            
152
            #we are ready for the party
153
            
154
            final_port = 29876+port.to_i;
155
            
156
            # puts "Launch noVNC on #{final_port} listenting to #{host}:#{vnc_port}"
157
            # So here we launch the noVNC server listening on the final_port 
158
            # and serving as proxy for the VM host on the configured VNC port.
159
            # TODO - This path is in public...            
160
            pipe = IO.popen("#{File.dirname(__FILE__)}/../../public/vendor/noVNC/utils/launch.sh --listen #{final_port} --vnc #{host}:#{vnc_port}")
161
            
162
            return {:pipe => pipe, :port => final_port, :password => vnc_pw}
163
            
164
        end
165
        
166
        def stopvnc(pipe)
167
            #am I allowed to do something affecting this machine?
168
            result = self.info();
169
            if OpenNebula.is_error?(result)
170
                return result
171
            end
172
            pid = pipe.pid
173
            # puts "Killing noVNC with pid #{pid}"
174
            Process.kill('KILL',pid)
175
            pipe.close
176
            return
177
        end
178
        
121 179
    end
122 180
end
src/sunstone/models/SunstoneServer.rb
213 213
        end
214 214
    end
215 215

  
216

  
217
    ########################################################################
218
    # VNC
219
    ########################################################################
220

  
221
    def startvnc(id)
222
        rc = retrieve_resource("vm", id)
223
        if OpenNebula.is_error?(rc)
224
            return rc
225
        end
226
        return rc.startvnc(id)
227
    end
228
    
229
    def stopvnc(id,pipe)
230
       rc = retrieve_resource("vm", id)
231
       if OpenNebula.is_error?(rc)
232
           return rc
233
       end
234
       return rc.stopvnc(pipe)
235
       
236
    end
237

  
238

  
216 239
    private
217 240

  
218 241
    def retrieve_resource(kind, id)
src/sunstone/public/js/opennebula.js
1235 1235
                    }
1236 1236
                }
1237 1237
            });
1238
        },
1239
        
1240
        "startvnc" : function(params){
1241
            var callback = params.success;
1242
            var callback_error = params.error;
1243
            var id = params.data.id;
1244
            var resource = OpenNebula.VM.resource;
1245

  
1246
            var method = "startvnc";
1247
            var action = OpenNebula.Helper.action(method);
1248
            var request = OpenNebula.Helper.request(resource,method, id);
1249
            $.ajax({
1250
                url: "vm/"+id+"/startvnc",
1251
                type: "POST",
1252
                dataType: "json",
1253
                success: function(response)
1254
                {
1255
                    if (callback)
1256
                    {
1257
                        callback(request,response);
1258
                    }
1259
                },
1260
                error: function(response)
1261
                {
1262
                    if (callback_error)
1263
                    {
1264
                        callback_error(request, OpenNebula.Error(response));
1265
                    }
1266
                }
1267
            });
1268
        },
1269
        
1270
        "stopvnc" : function(params){
1271
            var callback = params.success;
1272
            var callback_error = params.error;
1273
            var id = params.data.id;
1274
            var resource = OpenNebula.VM.resource;
1275

  
1276
            var method = "stopvnc";
1277
            var action = OpenNebula.Helper.action(method);
1278
            var request = OpenNebula.Helper.request(resource,method, id);
1279
            $.ajax({
1280
                url: "vm/"+id+"/stopvnc",
1281
                type: "POST",
1282
                success: function()
1283
                {
1284
                    if (callback)
1285
                    {
1286
                        callback(request);
1287
                    }
1288
                },
1289
                error: function(response)
1290
                {
1291
                    if (callback_error)
1292
                    {
1293
                        callback_error(request, OpenNebula.Error(response));
1294
                    }
1295
                }
1296
            });
1238 1297
        }
1298
        
1239 1299
    },
1240 1300

  
1241 1301
    "Cluster": {
src/sunstone/public/js/plugins/vms-tab.js
741 741
            $("#vm_log pre").html('');
742 742
            onError(request,error_json);
743 743
        }
744
    },
745
    
746
    "VM.startvnc" : {
747
        type: "single",
748
        call: OpenNebula.VM.startvnc,
749
        callback: vncCallback,
750
        error: onError
751
    },
752
    
753
    "VM.stopvnc" : {
754
        type: "single",
755
        call: OpenNebula.VM.stopvnc,
756
        callback: null,
757
        error: onError,
758
        notify: true
744 759
    }
745 760
}
746 761

  
......
1947 1962
	},INTERVAL+someTime()); //so that not all refreshing is done at the same time
1948 1963
}
1949 1964

  
1950
//setups VNC application
1951
function setupVNC(){
1952 1965

  
1953
    var updateVNCState = function updateState(rfb, state, oldstate, msg) {
1966
function updateVNCState(rfb, state, oldstate, msg) {
1954 1967
            var s, sb, cad, klass;
1955 1968
            s = $D('VNC_status');
1956 1969
            sb = $D('VNC_status_bar');
......
1983 1996
            }
1984 1997
        }
1985 1998

  
1999
//setups VNC application
2000
function setupVNC(){
2001

  
1986 2002
    //Append to DOM
1987 2003
    $('div#dialogs').append('<div id="vnc_dialog" title="VNC connection"></div>');
1988 2004
    
......
2014 2030
        resizable:true,
2015 2031
    });
2016 2032
    
2033
    $( "#vnc_dialog" ).bind( "dialogclose", function(event, ui) {
2034
        var id = $("#vnc_dialog").attr("vm_id");
2035
        Sunstone.runAction("VM.stopvnc",id);
2036
            
2037
    });
2038
    
2017 2039
    $('.vnc').live("click",function(){
2040
        //Which VM is it?
2041
        var id = $(this).attr("vm_id");
2042
        //Set attribute to dialog
2043
        $('#vnc_dialog').attr("vm_id",id);
2044
        //Request proxy server start
2045
        Sunstone.runAction("VM.startvnc",id);
2046
    });
2047

  
2048
}
2049

  
2050
function vncCallback(request,response){
2018 2051
        rfb = new RFB({'target':       $D('VNC_canvas'),
2019 2052
                        'encrypt':      false,
2020 2053
                        'true_color':   true,
......
2022 2055
                        'shared':       true,
2023 2056
                        'updateState':  updateVNCState});
2024 2057
        //fetch things from clicked element host - port - password
2025
        var port=$(this).attr("vnc_port");
2026
        var pw=$(this).attr("vnc_pw");
2027
        rfb.connect(host, port, pw);
2028

  
2029
        $('#vnc_dialog').dialog('open');
2058
        var port = response["port"];
2030 2059
        
2060
        //Hopefully this is returning sunstone server address, where
2061
        //the proxy is running
2062
        var host = window.location.hostname;
2063
        var pw = response["password"];
2031 2064
        
2032
    });
2065
        rfb.connect(host, port, pw);
2033 2066

  
2067
        //And voilĂ , we can open the dialog
2068
        $('#vnc_dialog').dialog('open');
2069
    
2034 2070
}
2035 2071

  
2036 2072
function vncIcon(vm){
2037 2073
    var graphics = vm.TEMPLATE.GRAPHICS;
2038 2074
    var state = OpenNebula.Helper.resource_state("vm",vm.STATE);
2039
    var gr_icon, host, port, password;
2040
    if (graphics && graphics.TYPE == "vnc" && state == "ACTIVE" && vm.HISTORY.HOSTNAME){
2041
        host = vm.HISTORY.HOSTNAME;
2042
        port = graphics.PORT ? graphics.PORT : "";
2043
        password = graphics.PASSWD ? graphics.PASSWD : "";
2044
        gr_icon = '<a class="vnc" href="#" vnc_host="'+host+'" vnc_port="'+port+'" vnc_pw="'+password+'">';
2075
    var gr_icon;
2076
    if (graphics && graphics.TYPE == "vnc" && state == "ACTIVE"){
2077
        gr_icon = '<a class="vnc" href="#" vm_id="'+vm.ID+'">';
2045 2078
        gr_icon += '<img src="images/vnc_on.png" alt="Open VNC Session" /></a>';
2046 2079
    }
2047 2080
    else {
src/sunstone/public/js/sunstone-util.js
185 185
    $.jGrowl(msg, {theme: "jGrowl-notify-error", sticky: true });
186 186
}
187 187

  
188
function notifyMessage(msg){
189
    msg = "<h1>Info</h1>" + msg;
190

  
191
    $.jGrowl(msg, {theme: "jGrowl-notify-submit"});
192
}
193

  
188 194
// Returns an HTML string with the json keys and values in the form
189 195
// key: value<br />
190 196
// It recursively explores objects, and flattens their contents in
src/sunstone/sunstone-server.rb
163 163
    @SunstoneServer.create_resource(params[:pool], request.body.read)
164 164
end
165 165

  
166
post '/vm/:id/stopvnc' do
167
    vm = params[:id]
168
    vnc_hash = session['vnc']
169
    
170
    if !vnc_hash
171
        msg = "Ups, no VNC sessions information found. Cannot stop VNC"
172
        return [500, OpenNebula::Error.new(msg).to_json]
173
    elsif !vnc_hash[vm]
174
        msg = "It seems there is no VNC proxy running for this machine"
175
        return [500, OpenNebula::Error.new(msg).to_json]
176
    end
177
    
178
    pipe = session['vnc'][vm]
179
    rc = @SunstoneServer.stopvnc(vm,pipe)
180
    
181
    if (OpenNebula.is_error?(rc))
182
        return [500, rc.to_json]
183
    else
184
        session['vnc'].delete(vm)
185
        return    
186
    end
187
    
188
end
189

  
190
post '/vm/:id/startvnc' do
191
    vm = params[:id]
192
    info = @SunstoneServer.startvnc(vm)
193
    
194
    if OpenNebula.is_error?(info)
195
        return [500,info.to_json]
196
    end
197
    
198
    port = info[:port] #port to connect to
199
    pw = info[:password]
200
    pipe = info[:pipe]
201
    
202
    vnc_hash = session['vnc']
203
    
204
    if !vnc_hash 
205
        session['vnc']= {}
206
    elsif vnc_hash and vnc_hash[vm]
207
        return [500, OpenNebula::Error.new("There is a VNC server running for this VM").to_json]
208
    end
209
    
210
    session['vnc'][vm]=pipe;
211
    return {:port => port, :password => pw }.to_json
212
    
213
end
214

  
166 215
##############################################################################
167 216
# Perform an action on a Resource
168 217
##############################################################################

Also available in: Unified diff