Merge branch 'stable' into devel
[tails.git] / features / scripts / vm-file
blob72a4c8135f33847094d38852584a481e485c3231
1 #!/usr/bin/env ruby
3 require 'libvirt'
4 require 'optparse'
5 require 'rexml/document'
6 begin
7 top_level_dir = `git rev-parse --show-toplevel`.chomp
8 require "#{top_level_dir}/features/support/helpers/remote_shell.rb"
9 require "#{top_level_dir}/features/support/helpers/misc_helpers.rb"
10 rescue LoadError
11 raise "This script must be run from within Tails' Git directory."
12 end
13 $config = {}
15 VIRTIO_REMOTE_SHELL = 'org.tails.remote_shell.0'.freeze
17 def debug_log(*args); end
19 # Implements the subset of the VM class that we need here
20 class FakeVM
21 def initialize
22 @domain_xml = ''
23 begin
24 virt = Libvirt.open('qemu:///system')
25 domain = virt.lookup_domain_by_name('TailsToaster')
26 @domain_xml = domain.xml_desc
27 rescue StandardError
28 raise 'There was a problem with the TailsToaster VM (is it running?)'
29 ensure
30 virt.close
31 end
32 end
34 def virtio_channel_socket_path(channel)
35 rexml = REXML::Document.new(@domain_xml)
36 rexml.elements.each('domain/devices/channel') do |e|
37 target = e.elements['target']
38 if target.attribute('name').to_s == channel
39 return e.elements['source'].attribute('path').to_s
40 end
41 end
42 raise 'The running TailsToaster has no remote shell channel!'
43 end
44 end
46 cmd_opts = {
47 upload: true,
48 src: nil,
49 dst: nil,
52 opt_parser = OptionParser.new do |opts|
53 opts.banner = 'Usage: features/scripts/vm-file [opts]'
54 opts.separator ''
55 opts.separator 'Copies file to/from VM'
56 opts.separator ''
57 opts.separator 'Options:'
59 opts.on_tail('-h', '--help', 'Show this message') do
60 puts opts
61 exit
62 end
64 opts.on('--upload=LOCAL', 'Upload file to the VM') do |src|
65 cmd_opts[:upload] = true
66 cmd_opts[:src] = src
67 end
69 opts.on('--download=REMOTE', 'Download file from the VM') do |src|
70 cmd_opts[:upload] = false
71 cmd_opts[:src] = src
72 end
74 opts.on('--to=DESTINATION', 'File destination') do |dest|
75 cmd_opts[:dst] = dest
76 end
77 end
79 opt_parser.parse!(ARGV)
81 if cmd_opts[:upload]
82 content = File.read(cmd_opts[:src])
83 f = RemoteShell::File.new(FakeVM.new, cmd_opts[:dst])
84 f.write(content)
85 else
86 f = RemoteShell::File.new(FakeVM.new, cmd_opts[:src])
87 File.write(cmd_opts[:dst], f.read)
88 end
89 exit 0