mirror of https://github.com/BOINC/boinc.git
- VBOX: Enable remote desktop functionality for a VM that has
<enable_remotedesktop/> specified in its vbox_job.xml file. NOTE: It does require the VirtualBox extension pack, but that is freely available on the VirtualBox download page. samples/vboxwrapper vbox.cpp, .h vboxwrapper.cpp, .h svn path=/trunk/boinc/; revision=25034
This commit is contained in:
parent
d4a91e5877
commit
fea602b6e6
|
@ -391,3 +391,14 @@ David 12 Jan 2012
|
|||
boinc_db.inc
|
||||
user/
|
||||
lammps.php
|
||||
|
||||
Rom 12 Jan 2012
|
||||
- VBOX: Enable remote desktop functionality for a VM that has
|
||||
<enable_remotedesktop/> specified in its vbox_job.xml file.
|
||||
|
||||
NOTE: It does require the VirtualBox extension pack, but that
|
||||
is freely available on the VirtualBox download page.
|
||||
|
||||
samples/vboxwrapper
|
||||
vbox.cpp, .h
|
||||
vboxwrapper.cpp, .h
|
||||
|
|
|
@ -648,6 +648,35 @@ int VBOX_VM::get_port_forwarding_port() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int VBOX_VM::get_remote_desktop_port() {
|
||||
struct sockaddr_in addr;
|
||||
BOINC_SOCKLEN_T addrsize;
|
||||
int sock;
|
||||
int retval;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(0);
|
||||
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
|
||||
addrsize = sizeof(addr);
|
||||
|
||||
retval = boinc_socket(sock);
|
||||
if (retval) return retval;
|
||||
|
||||
retval = bind(sock, (struct sockaddr *)&addr, addrsize);
|
||||
if (retval < 0) {
|
||||
boinc_close_socket(sock);
|
||||
return ERR_BIND;
|
||||
}
|
||||
|
||||
getsockname(sock, (struct sockaddr *)&addr, &addrsize);
|
||||
rd_host_port = addr.sin_port;
|
||||
|
||||
boinc_close_socket(sock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VBOX_VM::register_vm() {
|
||||
string command;
|
||||
string output;
|
||||
|
@ -839,18 +868,55 @@ int VBOX_VM::register_vm() {
|
|||
//
|
||||
if (enable_network) {
|
||||
set_network_access(true);
|
||||
|
||||
// If the VM wants to open up a port through the VirtualBox virtual
|
||||
// network firewall/nat do that here.
|
||||
//
|
||||
if (pf_guest_port) {
|
||||
if (!pf_host_port) {
|
||||
retval = get_port_forwarding_port();
|
||||
if (retval) return retval;
|
||||
}
|
||||
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Enabling virtual machine firewall rules.\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf))
|
||||
);
|
||||
|
||||
// Add new firewall rule
|
||||
//
|
||||
sprintf(buf, "vboxwrapper,tcp,127.0.0.1,%d,,%d", pf_host_port, pf_guest_port);
|
||||
command = "modifyvm \"" + vm_name + "\" ";
|
||||
command += "--natpf1 \"" + string(buf) + "\" ";
|
||||
|
||||
retval = vbm_popen(command, output, "add updated port forwarding rule");
|
||||
if(retval) return retval;
|
||||
}
|
||||
}
|
||||
|
||||
// If the app wants to open up a port through the VirtualBox virtual
|
||||
// network firewall/nat do that here.
|
||||
// If the VM wants to enable remote desktop for the VM do it here
|
||||
//
|
||||
if (pf_guest_port) {
|
||||
if (!pf_host_port) {
|
||||
retval = get_port_forwarding_port();
|
||||
if (retval) return retval;
|
||||
}
|
||||
retval = register_vm_firewall_rules();
|
||||
if (enable_remotedesktop) {
|
||||
retval = get_remote_desktop_port();
|
||||
if (retval) return retval;
|
||||
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Enabling remote desktop for virtual machine.\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf))
|
||||
);
|
||||
|
||||
sprintf(buf, "%d", rd_host_port);
|
||||
command = "modifyvm \"" + vm_name + "\" ";
|
||||
command += "--vrde on ";
|
||||
command += "--vrdeextpack default ";
|
||||
command += "--vrdeauthlibrary default ";
|
||||
command += "--vrdeauthtype null ";
|
||||
command += "--vrdeport " + string(buf) + " ";
|
||||
|
||||
retval = vbm_popen(command, output, "remote desktop");
|
||||
if(retval) return retval;
|
||||
}
|
||||
|
||||
// Enable the shared folder if a shared folder is specified.
|
||||
|
@ -872,33 +938,6 @@ int VBOX_VM::register_vm() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int VBOX_VM::register_vm_firewall_rules() {
|
||||
string command;
|
||||
string output;
|
||||
string virtual_machine_slot_directory;
|
||||
char buf[256];
|
||||
int retval;
|
||||
|
||||
get_slot_directory(virtual_machine_slot_directory);
|
||||
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Registering virtual machine firewall rules.\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf))
|
||||
);
|
||||
|
||||
// Add new firewall rule
|
||||
//
|
||||
sprintf(buf, "vboxwrapper,tcp,127.0.0.1,%d,,%d", pf_host_port, pf_guest_port);
|
||||
command = "modifyvm \"" + vm_name + "\" ";
|
||||
command += "--natpf1 \"" + string(buf) + "\" ";
|
||||
|
||||
retval = vbm_popen(command, output, "add updated port forwarding rule");
|
||||
if(retval) return retval;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VBOX_VM::deregister_vm() {
|
||||
string command;
|
||||
string output;
|
||||
|
|
|
@ -1,114 +1,119 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2010-2012 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
// as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// BOINC is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
// Provide cross-platform interfaces for making changes to VirtualBox
|
||||
|
||||
#ifndef _VBOX_H_
|
||||
#define _VBOX_H_
|
||||
|
||||
// raw floppy drive device
|
||||
class FloppyIO;
|
||||
|
||||
// represents a VirtualBox VM
|
||||
struct VBOX_VM {
|
||||
VBOX_VM();
|
||||
~VBOX_VM();
|
||||
|
||||
// Floppy IO abstraction
|
||||
FloppyIO* pFloppy;
|
||||
|
||||
// name of the OS the VM runs
|
||||
std::string os_name;
|
||||
// size of the memory allocation for the VM, in megabytes
|
||||
std::string memory_size_mb;
|
||||
// name of the virtual machine disk image file
|
||||
std::string image_filename;
|
||||
// name of the virtual machine floppy disk image file
|
||||
std::string floppy_image_filename;
|
||||
// unique name for the VM
|
||||
std::string vm_name;
|
||||
// required CPU core count
|
||||
std::string vm_cpu_count;
|
||||
// maximum amount of wall-clock time this VM is allowed to run before
|
||||
// considering itself done.
|
||||
double job_duration;
|
||||
// is the VM suspended?
|
||||
bool suspended;
|
||||
// is network access temporarily suspended?
|
||||
bool network_suspended;
|
||||
// is VM even online?
|
||||
bool online;
|
||||
// Has the VM crashed?
|
||||
bool crashed;
|
||||
// whether to use CERN specific data structures
|
||||
bool enable_cern_dataformat;
|
||||
// whether to use shared directory infrastructure at all
|
||||
bool enable_shared_directory;
|
||||
// whether to use floppy io infrastructure at all
|
||||
bool enable_floppyio;
|
||||
// whether we were instructed to only register the VM.
|
||||
// useful for debugging VMs.
|
||||
bool register_only;
|
||||
// whether to allow network access at all
|
||||
bool enable_network;
|
||||
// the following for optional port forwarding
|
||||
int pf_host_port;
|
||||
// specified in config file
|
||||
int pf_guest_port;
|
||||
// specified in config file
|
||||
|
||||
int run();
|
||||
int stop();
|
||||
int pause();
|
||||
int resume();
|
||||
void cleanup();
|
||||
void poll(bool log_state = true);
|
||||
bool is_running();
|
||||
bool is_paused();
|
||||
|
||||
int register_vm();
|
||||
int register_vm_firewall_rules();
|
||||
bool is_hdd_registered();
|
||||
bool is_registered();
|
||||
int deregister_stale_vm();
|
||||
int deregister_vm();
|
||||
int start();
|
||||
int set_network_access(bool enabled);
|
||||
int set_cpu_usage_fraction(double);
|
||||
int set_network_max_bytes_sec(double);
|
||||
int get_process_id(int& process_id);
|
||||
int get_network_bytes_sent(double& sent);
|
||||
int get_network_bytes_received(double& received);
|
||||
int get_system_log(std::string& log);
|
||||
int get_vm_log(std::string& log);
|
||||
int read_floppy(std::string& data);
|
||||
int write_floppy(std::string& data);
|
||||
int get_port_forwarding_port();
|
||||
|
||||
int initialize();
|
||||
int get_install_directory(std::string& dir);
|
||||
int get_slot_directory(std::string& dir);
|
||||
int vbm_popen(
|
||||
std::string& command, std::string& output, const char* item, bool log_error = true, bool retry_failures = true
|
||||
);
|
||||
int vbm_popen_raw(
|
||||
std::string& command, std::string& output
|
||||
);
|
||||
};
|
||||
|
||||
#endif
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
// as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// BOINC is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
// Provide cross-platform interfaces for making changes to VirtualBox
|
||||
|
||||
#ifndef _VBOX_H_
|
||||
#define _VBOX_H_
|
||||
|
||||
// raw floppy drive device
|
||||
class FloppyIO;
|
||||
|
||||
// represents a VirtualBox VM
|
||||
struct VBOX_VM {
|
||||
VBOX_VM();
|
||||
~VBOX_VM();
|
||||
|
||||
// Floppy IO abstraction
|
||||
FloppyIO* pFloppy;
|
||||
|
||||
// name of the OS the VM runs
|
||||
std::string os_name;
|
||||
// size of the memory allocation for the VM, in megabytes
|
||||
std::string memory_size_mb;
|
||||
// name of the virtual machine disk image file
|
||||
std::string image_filename;
|
||||
// name of the virtual machine floppy disk image file
|
||||
std::string floppy_image_filename;
|
||||
// unique name for the VM
|
||||
std::string vm_name;
|
||||
// required CPU core count
|
||||
std::string vm_cpu_count;
|
||||
// maximum amount of wall-clock time this VM is allowed to run before
|
||||
// considering itself done.
|
||||
double job_duration;
|
||||
// is the VM suspended?
|
||||
bool suspended;
|
||||
// is network access temporarily suspended?
|
||||
bool network_suspended;
|
||||
// is VM even online?
|
||||
bool online;
|
||||
// Has the VM crashed?
|
||||
bool crashed;
|
||||
// whether to use CERN specific data structures
|
||||
bool enable_cern_dataformat;
|
||||
// whether to use shared directory infrastructure at all
|
||||
bool enable_shared_directory;
|
||||
// whether to use floppy io infrastructure at all
|
||||
bool enable_floppyio;
|
||||
// whether to enable remote desktop functionality
|
||||
bool enable_remotedesktop;
|
||||
// whether we were instructed to only register the VM.
|
||||
// useful for debugging VMs.
|
||||
bool register_only;
|
||||
// whether to allow network access at all
|
||||
bool enable_network;
|
||||
// the following for optional port forwarding
|
||||
int pf_host_port;
|
||||
// specified in config file
|
||||
int pf_guest_port;
|
||||
// specified in config file
|
||||
// the following for optional remote desktop
|
||||
int rd_host_port;
|
||||
// dynamically assigned
|
||||
|
||||
int run();
|
||||
int stop();
|
||||
int pause();
|
||||
int resume();
|
||||
void cleanup();
|
||||
void poll(bool log_state = true);
|
||||
bool is_running();
|
||||
bool is_paused();
|
||||
|
||||
int register_vm();
|
||||
bool is_hdd_registered();
|
||||
bool is_registered();
|
||||
int deregister_stale_vm();
|
||||
int deregister_vm();
|
||||
int start();
|
||||
int set_network_access(bool enabled);
|
||||
int set_cpu_usage_fraction(double);
|
||||
int set_network_max_bytes_sec(double);
|
||||
int get_process_id(int& process_id);
|
||||
int get_network_bytes_sent(double& sent);
|
||||
int get_network_bytes_received(double& received);
|
||||
int get_system_log(std::string& log);
|
||||
int get_vm_log(std::string& log);
|
||||
int read_floppy(std::string& data);
|
||||
int write_floppy(std::string& data);
|
||||
int get_port_forwarding_port();
|
||||
int get_remote_desktop_port();
|
||||
|
||||
int initialize();
|
||||
int get_install_directory(std::string& dir);
|
||||
int get_slot_directory(std::string& dir);
|
||||
int vbm_popen(
|
||||
std::string& command, std::string& output, const char* item, bool log_error = true, bool retry_failures = true
|
||||
);
|
||||
int vbm_popen_raw(
|
||||
std::string& command, std::string& output
|
||||
);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -109,6 +109,7 @@ int parse_job_file(VBOX_VM& vm) {
|
|||
else if (xp.parse_bool("enable_network", vm.enable_network)) continue;
|
||||
else if (xp.parse_bool("enable_shared_directory", vm.enable_shared_directory)) continue;
|
||||
else if (xp.parse_bool("enable_floppyio", vm.enable_floppyio)) continue;
|
||||
else if (xp.parse_bool("enable_remotedesktop", vm.enable_remotedesktop)) continue;
|
||||
else if (xp.parse_int("pf_guest_port", vm.pf_guest_port)) continue;
|
||||
else if (xp.parse_int("pf_host_port", vm.pf_host_port)) continue;
|
||||
fprintf(stderr, "%s parse_job_file(): unexpected tag %s\n",
|
||||
|
@ -238,6 +239,37 @@ void set_port_forwarding_info(APP_INIT_DATA& /* aid */, VBOX_VM& vm) {
|
|||
}
|
||||
}
|
||||
|
||||
// set remote desktop information if needed
|
||||
//
|
||||
void set_remote_desktop_info(APP_INIT_DATA& /* aid */, VBOX_VM& vm) {
|
||||
char buf[256];
|
||||
|
||||
if (vm.rd_host_port) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s remote desktop enabled on port '%d'.\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)), vm.rd_host_port
|
||||
);
|
||||
|
||||
// Write info to disk
|
||||
//
|
||||
MIOFILE mf;
|
||||
FILE* f = boinc_fopen(REMOTEDESKTOP_FILENAME, "w");
|
||||
mf.init_file(f);
|
||||
|
||||
mf.printf(
|
||||
"<remote_desktop>\n"
|
||||
" <rule>\n"
|
||||
" <host_port>%d</host_port>\n"
|
||||
" </rule>\n"
|
||||
"</remote_desktop>\n",
|
||||
vm.rd_host_port
|
||||
);
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int retval;
|
||||
BOINC_OPTIONS boinc_options;
|
||||
|
@ -446,6 +478,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
set_floppy_image(aid, vm);
|
||||
set_port_forwarding_info(aid, vm);
|
||||
set_remote_desktop_info(aid, vm);
|
||||
set_throttles(aid, vm);
|
||||
|
||||
while (1) {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#define JOB_FILENAME "vbox_job.xml"
|
||||
#define CHECKPOINT_FILENAME "vbox_checkpoint.txt"
|
||||
#define PORTFORWARD_FILENAME "vbox_port_forward.xml"
|
||||
#define REMOTEDESKTOP_FILENAME "vbox_remote_desktop.xml"
|
||||
#define POLL_PERIOD 1.0
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue