qemu 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *~
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in qemu.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Alban Peignier
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # QEMU
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'qemu'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install qemu
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ FileList['tasks/**/*.rake'].each { |task| import task }
@@ -0,0 +1,10 @@
1
+ module QEMU
2
+
3
+ end
4
+
5
+ require 'qemu/version'
6
+
7
+ require 'qemu/image'
8
+ require 'qemu/daemon'
9
+ require 'qemu/command'
10
+ require 'qemu/monitor'
@@ -0,0 +1,116 @@
1
+ module QEMU
2
+ class Command
3
+
4
+ attr_accessor :name
5
+
6
+ def name
7
+ @name ||= "qemu"
8
+ end
9
+
10
+ attr_accessor :memory
11
+
12
+ attr_reader :disks
13
+ def disks
14
+ @disks ||= Disks.new
15
+ end
16
+
17
+ class Disks < Array
18
+
19
+ def push(*args)
20
+ super Disk.new(*args)
21
+ end
22
+ alias_method :<<, :push
23
+ alias_method :add, :push
24
+
25
+ end
26
+
27
+ class Disk
28
+
29
+ attr_accessor :file, :options
30
+
31
+ def initialize(file, options = {})
32
+ self.file = file
33
+ self.options = { :media => "disk" }.merge options
34
+ end
35
+
36
+ def qemu_drive(index)
37
+ {
38
+ :file => File.expand_path(file),
39
+ :index => index,
40
+ }.merge(options).map { |k,v| "#{k}=#{v}" }.join(',')
41
+ end
42
+
43
+ end
44
+
45
+ attr_accessor :mac_address
46
+
47
+ attr_accessor :vde_options
48
+ def vde_options
49
+ @vde_options ||= { :sock => "/var/run/vde2/tap0.ctl" }
50
+ end
51
+
52
+ attr_accessor :vnc
53
+
54
+ attr_accessor :monitor
55
+ attr_accessor :telnet_port
56
+
57
+ def telnet_port=(telnet_port)
58
+ @telnet_port = telnet_port
59
+ self.monitor = "telnet::#{telnet_port},server,nowait,nodelay"
60
+ end
61
+
62
+ def qemu_monitor
63
+ @qemu_monitor ||= QEMU::Monitor.new :port => telnet_port if telnet_port
64
+ end
65
+
66
+ attr_accessor :sound_hardware
67
+ attr_accessor :audio_driver
68
+ def audio_driver
69
+ @audio_driver ||= "alsa"
70
+ end
71
+
72
+ attr_accessor :alsa_dac_dev, :alsa_adc_dev
73
+
74
+ def command_arguments
75
+ [].tap do |args|
76
+ args << "-m" << "#{memory}m" if memory
77
+ disks.each_with_index do |disk, index|
78
+ args << "-drive" << disk.qemu_drive(index)
79
+ end
80
+ args << "-net" << "nic,macaddr=#{mac_address}"
81
+ unless vde_options.empty?
82
+ args << "-net" << "vde," + vde_options.map { |k,v| "#{k}=#{v}" }.join(',')
83
+ end
84
+ if vnc
85
+ args << "-vnc" << vnc
86
+ else
87
+ args << "-nographic"
88
+ end
89
+ args << "-monitor" << monitor if monitor
90
+ args << "-soundhw" << sound_hardware if sound_hardware
91
+ end
92
+ end
93
+
94
+ def command_env
95
+ {}.tap do |env|
96
+ env["QEMU_AUDIO_DRV"] = audio_driver
97
+ env["QEMU_ALSA_DAC_DEV"] = alsa_dac_dev if alsa_dac_dev
98
+ env["QEMU_ALSA_ADC_DEV"] = alsa_adc_dev if alsa_adc_dev
99
+ end
100
+ end
101
+
102
+ def command
103
+ "/usr/bin/kvm"
104
+ end
105
+
106
+ def run
107
+ shell_env = command_env.map { |k,v| "#{k}=#{v}" }.join(' ')
108
+ system "#{shell_env} #{command} #{command_arguments.join(' ')}"
109
+ end
110
+
111
+ def daemon
112
+ @daemon ||= Daemon.new :command => command, :name => name, :arguments => command_arguments, :env => command_env
113
+ end
114
+
115
+ end
116
+ end
@@ -0,0 +1,56 @@
1
+ require "daemons"
2
+
3
+ module QEMU
4
+ class Daemon
5
+
6
+ @@log_directory = "log"
7
+ def self.log_directory
8
+ @@log_directory
9
+ end
10
+
11
+ @@run_directory = "tmp"
12
+ def self.run_directory
13
+ @@run_directory
14
+ end
15
+
16
+ attr_accessor :command, :arguments, :name, :run_dir, :log_dir, :env
17
+
18
+ def initialize(attributes = {})
19
+ attributes = attributes.merge(:name => "qemu", :run_dir => self.class.run_directory, :log_dir => self.class.log_directory)
20
+ attributes.each { |k,v| send "#{k}=", v }
21
+ end
22
+
23
+ def run_dir=(directory)
24
+ @run_dir = File.expand_path(directory)
25
+ end
26
+
27
+ def log_dir=(directory)
28
+ @log_dir = File.expand_path(directory)
29
+ end
30
+
31
+ def options
32
+ { :app_name => name, :dir_mode => :normal, :dir => run_dir, :mode => :exec, :log_dir => log_dir, :log_output => true }
33
+ end
34
+
35
+ def arguments_to(command)
36
+ [ command.to_s, "--", *arguments ]
37
+ end
38
+
39
+ def options_to(command)
40
+ options.merge :ARGV => arguments_to(command)
41
+ end
42
+
43
+ def start
44
+ fork do
45
+ env.each { |k,v| ENV[k] = v } if env
46
+ Daemons.run command, options_to(:start)
47
+ end
48
+ end
49
+
50
+ def stop
51
+ Daemons.run command, options_to(:stop)
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,22 @@
1
+ module QEMU
2
+ class Image
3
+
4
+ attr_accessor :file, :size, :format
5
+
6
+ def initialize(file, options = {})
7
+ self.file = file
8
+ options = options.merge :format => "raw"
9
+ options.each { |k,v| send "#{k}=", v }
10
+ end
11
+
12
+ def create
13
+ system "qemu-img create -f #{format} #{file} #{size}"
14
+ end
15
+
16
+ def convert(format, output_file = nil)
17
+ output_file ||= "#{file}.#{format}"
18
+ system "qemu-img convert -O #{format} #{file} #{output_file}" and output_file
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,34 @@
1
+ require 'net/telnet'
2
+
3
+ module QEMU
4
+ class Monitor
5
+
6
+ attr_accessor :host, :port, :timeout
7
+
8
+ def initialize(attributes = {})
9
+ attributes = { :host => "localhost", :timeout => 5 }.merge(attributes)
10
+ attributes.each { |k,v| send "#{k}=", v }
11
+ end
12
+
13
+ def telnet
14
+ @telnet ||= Net::Telnet::new "Host" => host, "Port" => port, "Timeout" => timeout, "Prompt" => /\(qemu\) /
15
+ end
16
+
17
+ def command(command)
18
+ telnet.cmd command
19
+ end
20
+
21
+ def reset
22
+ command "system_reset"
23
+ end
24
+
25
+ def savevm(name = "default")
26
+ command "savevm #{name}"
27
+ end
28
+
29
+ def loadvm(name = "default")
30
+ command "loadvm #{name}"
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module QEMU
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'qemu/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "qemu"
8
+ spec.version = QEMU::VERSION
9
+ spec.authors = ["Alban Peignier", "Florent Peyraud"]
10
+ spec.email = ["alban@tryphon.eu", "florent@tryphon.eu"]
11
+ spec.description = %q{Create QEMU command lines, start and stop daemon, send monitor commands to a qemu instances, create or convert QEMU disks, etc .. in Ruby}
12
+ spec.summary = %q{Manage QEMU from Ruby}
13
+ spec.homepage = "http://projects.tryphon.eu/projects/ruby-qemu"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_development_dependency "simplecov"
25
+ spec.add_development_dependency "rspec"
26
+ spec.add_development_dependency "guard"
27
+ spec.add_development_dependency "guard-rspec"
28
+ spec.add_development_dependency "rdoc"
29
+
30
+ spec.add_runtime_dependency "daemons"
31
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe QEMU::Command do
4
+
5
+ describe "#name" do
6
+
7
+ it "should be 'qemu' by default" do
8
+ subject.name.should == "qemu"
9
+ end
10
+
11
+ it "should be the given name" do
12
+ subject.name = "test"
13
+ subject.name.should == "test"
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+
11
+ require 'simplecov'
12
+ SimpleCov.start do
13
+ add_filter "/spec/"
14
+ end
15
+
16
+ require 'qemu'
17
+
18
+ Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
@@ -0,0 +1,2 @@
1
+ require 'rspec/core/rake_task'
2
+ RSpec::Core::RakeTask.new('spec')
metadata ADDED
@@ -0,0 +1,195 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: qemu
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Alban Peignier
14
+ - Florent Peyraud
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2013-05-19 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ type: :development
23
+ version_requirements: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 9
29
+ segments:
30
+ - 1
31
+ - 3
32
+ version: "1.3"
33
+ requirement: *id001
34
+ prerelease: false
35
+ name: bundler
36
+ - !ruby/object:Gem::Dependency
37
+ type: :development
38
+ version_requirements: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ requirement: *id002
48
+ prerelease: false
49
+ name: rake
50
+ - !ruby/object:Gem::Dependency
51
+ type: :development
52
+ version_requirements: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ requirement: *id003
62
+ prerelease: false
63
+ name: simplecov
64
+ - !ruby/object:Gem::Dependency
65
+ type: :development
66
+ version_requirements: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ requirement: *id004
76
+ prerelease: false
77
+ name: rspec
78
+ - !ruby/object:Gem::Dependency
79
+ type: :development
80
+ version_requirements: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ requirement: *id005
90
+ prerelease: false
91
+ name: guard
92
+ - !ruby/object:Gem::Dependency
93
+ type: :development
94
+ version_requirements: &id006 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ requirement: *id006
104
+ prerelease: false
105
+ name: guard-rspec
106
+ - !ruby/object:Gem::Dependency
107
+ type: :development
108
+ version_requirements: &id007 !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ hash: 3
114
+ segments:
115
+ - 0
116
+ version: "0"
117
+ requirement: *id007
118
+ prerelease: false
119
+ name: rdoc
120
+ - !ruby/object:Gem::Dependency
121
+ type: :runtime
122
+ version_requirements: &id008 !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ requirement: *id008
132
+ prerelease: false
133
+ name: daemons
134
+ description: Create QEMU command lines, start and stop daemon, send monitor commands to a qemu instances, create or convert QEMU disks, etc .. in Ruby
135
+ email:
136
+ - alban@tryphon.eu
137
+ - florent@tryphon.eu
138
+ executables: []
139
+
140
+ extensions: []
141
+
142
+ extra_rdoc_files: []
143
+
144
+ files:
145
+ - .gitignore
146
+ - Gemfile
147
+ - LICENSE.txt
148
+ - README.md
149
+ - Rakefile
150
+ - lib/qemu.rb
151
+ - lib/qemu/command.rb
152
+ - lib/qemu/daemon.rb
153
+ - lib/qemu/image.rb
154
+ - lib/qemu/monitor.rb
155
+ - lib/qemu/version.rb
156
+ - qemu.gemspec
157
+ - spec/qemu/command_spec.rb
158
+ - spec/spec_helper.rb
159
+ - tasks/rspec.rake
160
+ homepage: http://projects.tryphon.eu/projects/ruby-qemu
161
+ licenses:
162
+ - MIT
163
+ post_install_message:
164
+ rdoc_options: []
165
+
166
+ require_paths:
167
+ - lib
168
+ required_ruby_version: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ hash: 3
174
+ segments:
175
+ - 0
176
+ version: "0"
177
+ required_rubygems_version: !ruby/object:Gem::Requirement
178
+ none: false
179
+ requirements:
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ hash: 3
183
+ segments:
184
+ - 0
185
+ version: "0"
186
+ requirements: []
187
+
188
+ rubyforge_project:
189
+ rubygems_version: 1.8.24
190
+ signing_key:
191
+ specification_version: 3
192
+ summary: Manage QEMU from Ruby
193
+ test_files:
194
+ - spec/qemu/command_spec.rb
195
+ - spec/spec_helper.rb