aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2011-01-15 14:40:13 +0100
committerAndreas Schneider <asn@cryptomilk.org>2011-01-15 15:00:50 +0100
commit64cceae169565f186128b62293f51484b0f84552 (patch)
tree98e95146601cfe7a55500788e0c5cd887d6c165c
downloadvmexec-64cceae169565f186128b62293f51484b0f84552.tar.gz
vmexec-64cceae169565f186128b62293f51484b0f84552.tar.xz
vmexec-64cceae169565f186128b62293f51484b0f84552.zip
Initial commit for vmexec.
-rwxr-xr-xvmexec177
1 files changed, 177 insertions, 0 deletions
diff --git a/vmexec b/vmexec
new file mode 100755
index 0000000..7d9967d
--- /dev/null
+++ b/vmexec
@@ -0,0 +1,177 @@
+#!/usr/bin/env ruby
+#
+# vmexec runs a list of commands inside a qemu based virtual machine.
+#
+# Copyright (c) 2011 Andreas Schneider <asn@cryptomilk.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+require 'net/telnet'
+
+require 'optparse'
+require 'ostruct'
+
+class VMExecOpts
+ #
+ # Return a structure describing the options.
+ #
+ def self.parse(argv)
+ @args = {}
+
+ # The options specified on the command line will be collected in *options*.
+ # We set default values here.
+ @options = OpenStruct.new
+
+ @options.cmds = []
+ @options.disk = nil
+
+ @options.user = []
+ @options.mem = 512
+ @options.port = 2222
+ @options.verbose = false
+
+ opts = OptionParser.new do |opts|
+ opts.banner =
+ "Usage: vmexec [options] disk.img command1 command2 ... commandN"
+
+ opts.separator ""
+ opts.separator "Boot the given virtual machine image and wait until it comes up. Run "
+ opts.separator "the list of commands one at a time, aborting on receiving an error."
+ opts.separator "When all commands are run (or one of them failed), shutdown the virtual"
+ opts.separator "machine and exit."
+ opts.separator ""
+ opts.separator "Commands are by default run inside the virtual machine using ssh(1) on"
+ opts.separator "UNIX and telnet(1) on Windows. By prefixing a command with an equals"
+ opts.separator "sign '=', it will instead be run on the host system (for example to"
+ opts.separator "copy files into or out of the virtual machine using scp(1))."
+ opts.separator ""
+ opts.separator "Some care is taken to ensure that the virtual machine is shutdown"
+ opts.separator "gracefully and not left running even in case the controlling tty is"
+ opts.separator "closed or the parent process killed. If a previous virtual machine is"
+ opts.separator "already running on a conflicting port, an attempt is made to shut it"
+ opts.separator "down first. For this purpose, a PID file is created in \$HOME/.vmexec/"
+
+ opts.separator ""
+ opts.separator "Specific options:"
+
+ # Optional argument; multi-line description.
+ opts.on("-p", "--port <PORT>", Integer,
+ "Forward this port on the host side to the ssh port (port",
+ "22) on the guest side. Must be different for each runvm",
+ "instance running in parallel to avoid conflicts. The",
+ "default is $opt_port.",
+ "To copy files in/out of the guest use a command prefixed",
+ "with '=' calling scp(1) with the -P option using the port",
+ "specified here, like this:",
+ " vmexec img.qcow2 \"=scp -P 2222 file.txt localhost:\"") do |port|
+ @options.port = port
+ end
+
+ opts.on("-u", "--user <USER>",
+ "Name of the account to ssh into in the guest. Defaults to",
+ "the name of the user invoking runvm on the host.") do |user|
+ @options.user = user
+ end
+
+ opts.on("-m", "--memory N",
+ "Amount of memory (in megabytes) to allocate to the guest.",
+ "Defaults to options..") do |memory|
+ @options.memory = memory
+ end
+
+ # Boolean switch.
+ opts.on("-v", "--verbose", "Run verbosely") do |v|
+ @options.verbose = v
+ end
+
+ opts.separator ""
+ opts.separator "Common options:"
+
+ # No argument, shows at tail. This will print an options summary.
+ # Try it and see!
+ opts.on_tail("-h", "--help", "Show this message") do
+ puts opts
+ exit
+ end
+
+ # Another typical switch to print the version.
+ opts.on_tail("--version", "Show version") do
+ puts OptionParser::Version.join('.')
+ exit
+ end
+ end # OptionParser.new
+
+ opts.parse!(argv)
+ @args = opts.permute!(argv)
+
+ if @args.size < 2
+ puts opts
+ exit
+ end
+
+ @options.disk = @args.shift
+ @options.cmds = @args
+
+ @options
+ end # parse()
+end # class VMExecOpts
+
+class VMExec
+ VERSION = '0.1'
+
+ attr_reader :options
+
+ def initialize(args)
+ @options = VMExecOpts.parse(args)
+ end # init
+
+ def run
+ p @options
+ p 'Running vmexec'
+ end # run
+
+ protected
+end # class VMExec
+
+vmexec = VMExec.new(ARGV)
+vmexec.run
+
+exit
+
+#host = Net::Telnet::new(
+# "Host" => "localhost", # default: "localhost"
+# "Port" => 2323, # default: 23
+# "Binmode" => false, # default: false
+# "Output_log" => "output.log", # default: nil (no output)
+# "Dump_log" => "dump.log", # default: nil (no output)
+# "Prompt" => /C:.*>/, # default: /[$%#>] \z/n
+# "Telnetmode" => true, # default: true
+# "Timeout" => 10, # default: 10
+# # if ignore timeout then set "Timeout" to false.
+# "Waittime" => 0 # default: 0
+# )
+
+#host.login("libssh", "libssh") { |c| print c }
+
+#host.cmd('echo %HOME%') { |c| print c }
+#host.cmd('set HOME=C:\\Users\\libssh')
+#host.cmd('echo %HOME%') { |c| print c }
+
+#host.cmd('ctest -S workspace/ctest/ctest-vs10-x86-default.cmake') { |c| print c }
+#host.cmd('ctest -S workspace/ctest/ctest-msys-x86-default.cmake') { |c| print c }
+
+#shutdown the machine
+#host.cmd('shutdown /s /f /m \\\\BESPIN') { |c| print c }
+