vmit 0.0.3 → 0.0.3.99

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,31 +20,35 @@
20
20
  #
21
21
  require File.join(File.dirname(__FILE__), "helper")
22
22
  require 'test/unit'
23
- require 'vmit/bootstrap'
24
- require 'tempfile'
23
+ require 'vmit/workspace'
24
+ require 'tmpdir'
25
25
 
26
- class Bootstrap_test < Test::Unit::TestCase
26
+ class Workspace_test < Test::Unit::TestCase
27
27
 
28
- def test_accept_locations
29
- assert Vmit::Bootstrap::FromMedia.accept?('http://www.foof.com/repo')
30
- assert Vmit::Bootstrap::FromMedia.accept?(URI.parse('http://www.foof.com/repo'))
31
- assert Vmit::Bootstrap::FromMedia.accept?('http://www.foof.com/repo/')
32
- assert Vmit::Bootstrap::FromMedia.accept?(URI.parse('http://www.foof.com/repo/'))
28
+ def test_basic
29
+ Dir.mktmpdir do |dir|
30
+ workspace = Vmit::Workspace.new(dir)
31
+ assert_equal '1G', workspace.config.memory
32
+ assert !File.exist?(File.join(dir, 'config.yml'))
33
+ assert_raises RuntimeError do
34
+ workspace.current_image
35
+ end
33
36
 
34
- iso_path = File.expand_path('data/test_vfs.iso', File.dirname(__FILE__))
35
- tmp_raw = Tempfile.new(['vmit-test-', '.raw'])
36
- raw_path = tmp_raw.path
37
+ workspace.save_config!
38
+ assert File.exist?(File.join(dir, 'config.yml'))
37
39
 
38
- assert Vmit::Bootstrap::FromMedia.accept?(iso_path)
39
- assert !Vmit::Bootstrap::FromMedia.accept?('/non/existing/file.iso')
40
- assert !Vmit::Bootstrap::FromMedia.accept?('/non/existing/file.raw')
40
+ assert !File.exist?(File.join(dir, 'base.qcow2'))
41
+ workspace.disk_image_init!
42
+ STDERR.puts Dir.entries(dir)
43
+ assert File.exist?(File.join(dir, 'base.qcow2'))
41
44
 
42
- assert !Vmit::Bootstrap::FromImage.accept?(iso_path)
43
- assert !Vmit::Bootstrap::FromImage.accept?('/non/existing/file.iso')
44
- assert !Vmit::Bootstrap::FromImage.accept?('/non/existing/file.raw')
45
+ assert workspace.current_image
45
46
 
46
- assert !Vmit::Bootstrap::FromMedia.accept?(raw_path)
47
- assert Vmit::Bootstrap::FromImage.accept?(raw_path)
47
+ workspace.disk_image_shift!
48
+ # calling this too fast screws the timestamp
49
+ sleep(1)
50
+ workspace.disk_image_shift!
51
+ end
48
52
  end
49
53
 
50
54
  end
@@ -17,8 +17,9 @@ Gem::Specification.new do |s|
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
+
21
+ s.required_ruby_version = '>= 1.9.2'
20
22
  s.add_dependency('clamp')
21
- s.add_dependency('open4')
22
23
  s.add_dependency('pidfile')
23
24
  s.add_dependency('cheetah')
24
25
  s.add_dependency('ipaddress')
@@ -26,6 +27,8 @@ Gem::Specification.new do |s|
26
27
  s.add_dependency('progressbar')
27
28
  s.add_dependency('activesupport')
28
29
  s.add_dependency('nokogiri')
30
+ s.add_dependency('confstruct')
31
+ s.add_dependency('ruby-libvirt', '>= 0.4')
29
32
 
30
33
  s.add_development_dependency('webmock')
31
34
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vmit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.3.99
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-14 00:00:00.000000000 Z
12
+ date: 2013-05-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: clamp
@@ -28,7 +28,7 @@ dependencies:
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
30
  - !ruby/object:Gem::Dependency
31
- name: open4
31
+ name: pidfile
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
@@ -44,7 +44,7 @@ dependencies:
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
46
  - !ruby/object:Gem::Dependency
47
- name: pidfile
47
+ name: cheetah
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
@@ -60,7 +60,7 @@ dependencies:
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  - !ruby/object:Gem::Dependency
63
- name: cheetah
63
+ name: ipaddress
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  none: false
66
66
  requirements:
@@ -76,7 +76,7 @@ dependencies:
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  - !ruby/object:Gem::Dependency
79
- name: ipaddress
79
+ name: abstract_method
80
80
  requirement: !ruby/object:Gem::Requirement
81
81
  none: false
82
82
  requirements:
@@ -92,7 +92,7 @@ dependencies:
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
94
  - !ruby/object:Gem::Dependency
95
- name: abstract_method
95
+ name: progressbar
96
96
  requirement: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
@@ -108,7 +108,7 @@ dependencies:
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
110
  - !ruby/object:Gem::Dependency
111
- name: progressbar
111
+ name: activesupport
112
112
  requirement: !ruby/object:Gem::Requirement
113
113
  none: false
114
114
  requirements:
@@ -124,7 +124,7 @@ dependencies:
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  - !ruby/object:Gem::Dependency
127
- name: activesupport
127
+ name: nokogiri
128
128
  requirement: !ruby/object:Gem::Requirement
129
129
  none: false
130
130
  requirements:
@@ -140,7 +140,7 @@ dependencies:
140
140
  - !ruby/object:Gem::Version
141
141
  version: '0'
142
142
  - !ruby/object:Gem::Dependency
143
- name: nokogiri
143
+ name: confstruct
144
144
  requirement: !ruby/object:Gem::Requirement
145
145
  none: false
146
146
  requirements:
@@ -155,6 +155,22 @@ dependencies:
155
155
  - - ! '>='
156
156
  - !ruby/object:Gem::Version
157
157
  version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: ruby-libvirt
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0.4'
166
+ type: :runtime
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0.4'
158
174
  - !ruby/object:Gem::Dependency
159
175
  name: webmock
160
176
  requirement: !ruby/object:Gem::Requirement
@@ -176,8 +192,6 @@ email:
176
192
  - dmacvicar@suse.de
177
193
  executables:
178
194
  - vmit
179
- - vmit-ifdown
180
- - vmit-ifup
181
195
  extensions: []
182
196
  extra_rdoc_files: []
183
197
  files:
@@ -187,29 +201,36 @@ files:
187
201
  - README.rdoc
188
202
  - Rakefile
189
203
  - bin/vmit
190
- - bin/vmit-ifdown
191
- - bin/vmit-ifup
192
204
  - lib/vmit.rb
193
205
  - lib/vmit/autoyast.rb
194
- - lib/vmit/bootstrap.rb
195
206
  - lib/vmit/debian_preseed.rb
196
207
  - lib/vmit/ext.rb
208
+ - lib/vmit/install_media.rb
197
209
  - lib/vmit/kickstart.rb
210
+ - lib/vmit/libvirt_vm.rb
198
211
  - lib/vmit/logger.rb
199
212
  - lib/vmit/network.rb
200
213
  - lib/vmit/plugins/bootstrap.rb
201
214
  - lib/vmit/plugins/hello.rb
202
215
  - lib/vmit/refcounted_resource.rb
216
+ - lib/vmit/registry.rb
217
+ - lib/vmit/unattended_install.rb
203
218
  - lib/vmit/utils.rb
204
219
  - lib/vmit/version.rb
205
220
  - lib/vmit/vfs.rb
206
- - lib/vmit/virtual_machine.rb
207
- - test/bootstrap_test.rb
221
+ - lib/vmit/workspace.rb
208
222
  - test/data/dir1/file.txt
223
+ - test/data/registry.yml
224
+ - test/data/registry/key1
225
+ - test/data/registry/key2
226
+ - test/data/registry/key4/key1
209
227
  - test/data/test_vfs.iso
210
228
  - test/helper.rb
229
+ - test/install_media_test.rb
211
230
  - test/refcounted_resource_test.rb
231
+ - test/registry_test.rb
212
232
  - test/vfs_test.rb
233
+ - test/workspace_test.rb
213
234
  - vmit.gemspec
214
235
  homepage: ''
215
236
  licenses: []
@@ -222,7 +243,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
222
243
  requirements:
223
244
  - - ! '>='
224
245
  - !ruby/object:Gem::Version
225
- version: '0'
246
+ version: 1.9.2
226
247
  required_rubygems_version: !ruby/object:Gem::Requirement
227
248
  none: false
228
249
  requirements:
@@ -236,9 +257,15 @@ signing_key:
236
257
  specification_version: 3
237
258
  summary: Virtual machine (kvm) command line tool
238
259
  test_files:
239
- - test/bootstrap_test.rb
240
260
  - test/data/dir1/file.txt
261
+ - test/data/registry.yml
262
+ - test/data/registry/key1
263
+ - test/data/registry/key2
264
+ - test/data/registry/key4/key1
241
265
  - test/data/test_vfs.iso
242
266
  - test/helper.rb
267
+ - test/install_media_test.rb
243
268
  - test/refcounted_resource_test.rb
269
+ - test/registry_test.rb
244
270
  - test/vfs_test.rb
271
+ - test/workspace_test.rb
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env ruby
2
- $: << File.join(File.dirname(__FILE__), "..", "lib")
3
- require 'rubygems'
4
- require 'vmit'
5
- require 'drb'
6
-
7
- DRb.start_service
8
- vmit = DRbObject.new nil, ENV['VMIT_SERVER']
9
-
10
- vmit.ifdown(ARGV[0])
@@ -1,18 +0,0 @@
1
- #!/usr/bin/env ruby
2
- $: << File.join(File.dirname(__FILE__), "..", "lib")
3
-
4
- #/sbin/brctl setfd ${switch} 0
5
- #/sbin/brctl stp ${switch} off
6
-
7
- require 'rubygems'
8
- require 'vmit'
9
- require 'drb'
10
-
11
- DRb.start_service
12
- vmit = DRbObject.new nil, ENV['VMIT_SERVER']
13
-
14
- vmit.ifup(ARGV[0])
15
-
16
-
17
-
18
-
@@ -1,273 +0,0 @@
1
- #
2
- # Copyright (C) 2013 Duncan Mac-Vicar P. <dmacvicar@suse.de>
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
- # this software and associated documentation files (the "Software"), to deal in
6
- # the Software without restriction, including without limitation the rights to
7
- # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
- # the Software, and to permit persons to whom the Software is furnished to do so,
9
- # subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
- # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
- # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
- # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
- # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
- #
21
- require 'vmit'
22
- require 'vmit/autoyast'
23
- require 'vmit/kickstart'
24
- require 'vmit/debian_preseed'
25
-
26
- module Vmit
27
-
28
- module Bootstrap
29
-
30
- def self.arch
31
- Cheetah.run('arch', :stdout => :capture).strip
32
- end
33
-
34
- def self.bootstrapper_for(location)
35
- case
36
- when local_iso
37
- end
38
- end
39
-
40
- module MethodDebianPreseed
41
- # @param [Hash] args Arguments for 1st stage
42
- def execute_autoinstall(args)
43
- auto_install_args = {}
44
- preseed = Vmit::DebianPreseed.new
45
-
46
- Dir.mktmpdir do |floppy_dir|
47
- qemu_args = {:floppy => floppy_dir,
48
- :append => "preseed/file=/floppy/preseed.cfg auto=true priority=critical",
49
- :reboot => false}
50
- qemu_args.merge!(auto_install_args)
51
- # transform duplicates into an array
52
- qemu_args.merge!(args) do |key, oldv, newv|
53
- case key
54
- when :append then [oldv, newv].flatten
55
- else newv
56
- end
57
- end
58
-
59
- # Configure the autoinstallation profile to persist eth0
60
- # for the current MAC address
61
- # The interface will be setup with DHCP by default.
62
- # TODO: make this more flexible in the future?
63
- #autoyast.name_network_device(vm[:mac_address], 'eth0')
64
- File.write(File.join(floppy_dir, 'preseed.cfg'), preseed.to_txt)
65
- Vmit.logger.info "Preseed: 1st stage."
66
- vm.run(qemu_args)
67
- Vmit.logger.info "Preseed: 2st stage."
68
- # 2nd stage
69
- vm.run(:reboot => false)
70
- end
71
- end
72
- end
73
-
74
- module MethodKickstart
75
- # @param [Hash] args Arguments for 1st stage
76
- def execute_autoinstall(args)
77
- auto_install_args = {}
78
- kickstart = Vmit::Kickstart.new
79
-
80
- case media
81
- when Vmit::VFS::URI
82
- kickstart.install = location
83
- when Vmit::VFS::ISO
84
- kickstart.install = :cdrom
85
- auto_install_args.merge!(:cdrom => location.to_s)
86
- else raise ArgumentError.new("Unsupported autoinstallation: #{location}")
87
- end
88
-
89
- Dir.mktmpdir do |floppy_dir|
90
- qemu_args = {:floppy => floppy_dir,
91
- :append => "ks=floppy repo=#{kickstart.install}",
92
- :reboot => false}
93
- qemu_args.merge!(auto_install_args)
94
- # transform duplicates into an array
95
- qemu_args.merge!(args) do |key, oldv, newv|
96
- case key
97
- when :append then [oldv, newv].flatten
98
- else newv
99
- end
100
- end
101
-
102
- File.write(File.join(floppy_dir, 'ks.cfg'), kickstart.to_ks_script)
103
- Vmit.logger.info "Kickstart: 1st stage."
104
- vm.run(qemu_args)
105
- end
106
- end
107
- end
108
-
109
- module MethodAutoYaST
110
- # @param [Hash] args Arguments for 1st stage
111
- def execute_autoinstall(args)
112
- auto_install_args = {}
113
- auto_install_args.merge!(args)
114
- kernel_append_arg = case media
115
- when Vmit::VFS::URI then "install=#{location}"
116
- when Vmit::VFS::ISO then 'install=cdrom'
117
- else raise ArgumentError.new("Unsupported autoinstallation: #{location}")
118
- end
119
- auto_install_args.merge!(:append => kernel_append_arg)
120
- if media.is_a?(Vmit::VFS::ISO)
121
- auto_install_args.merge!(:cdrom => location.to_s)
122
- end
123
-
124
- Dir.mktmpdir do |floppy_dir|
125
- qemu_args = {:floppy => floppy_dir,
126
- :append => "autoyast=device://fd0/autoinst.xml",
127
- :reboot => false}
128
- # transform duplicates into an array
129
- qemu_args.merge!(auto_install_args) do |key, oldv, newv|
130
- case key
131
- when :append then [oldv, newv].flatten
132
- else newv
133
- end
134
- end
135
-
136
- autoyast = Vmit::AutoYaST.new
137
-
138
- # WTF SLE and openSUSE have different
139
- # base pattern names
140
- media.open('/content') do |content_file|
141
- content_file.each_line do |line|
142
- case line
143
- when /^DISTRIBUTION (.+)$/
144
- case $1
145
- when /SUSE_SLE/ then autoyast.minimal_sle!
146
- when /openSUSE/ then autoyast.minimal_opensuse!
147
- end
148
- end
149
- end
150
- end
151
-
152
- # Configure the autoinstallation profile to persist eth0
153
- # for the current MAC address
154
- # The interface will be setup with DHCP by default.
155
- # TODO: make this more flexible in the future?
156
- #autoyast.name_network_device(vm[:mac_address], 'eth0')
157
- File.write(File.join(floppy_dir, 'autoinst.xml'), autoyast.to_xml)
158
- Vmit.logger.info "AutoYaST: 1st stage."
159
- vm.run(qemu_args)
160
- Vmit.logger.info "AutoYaST: 2st stage."
161
- # 2nd stage
162
- vm.run(:reboot => false)
163
- end
164
- end
165
- end
166
-
167
- module SUSEMedia
168
- include MethodAutoYaST
169
-
170
- def get_initrd
171
- media.open("/boot/#{Vmit::Bootstrap.arch}/loader/initrd")
172
- end
173
-
174
- def get_kernel
175
- media.open("/boot/#{Vmit::Bootstrap.arch}/loader/linux")
176
- end
177
- end
178
-
179
- module FedoraMedia
180
- include MethodKickstart
181
-
182
- def get_initrd
183
- media.open("/images/pxeboot/initrd.img")
184
- end
185
-
186
- def get_kernel
187
- media.open("/images/pxeboot/vmlinuz")
188
- end
189
- end
190
-
191
- module DebianMedia
192
- include MethodDebianPreseed
193
-
194
- def get_initrd
195
- arch = Vmit::Bootstrap.arch.gsub(/x86_64/, 'amd64')
196
- media.open("/main/installer-#{arch}/current/images/netboot/debian-installer/#{arch}/initrd.gz")
197
- end
198
-
199
- def get_kernel
200
- arch = Vmit::Bootstrap.arch.gsub(/x86_64/, 'amd64')
201
- media.open("/main/installer-#{arch}/current/images/netboot/debian-installer/#{arch}/linux")
202
- end
203
- end
204
-
205
- # Boostraps a vm from a SUSE repository
206
- class FromMedia
207
-
208
- attr_reader :vm
209
- attr_reader :media
210
- attr_reader :location
211
-
212
- # @param [URI] location
213
- def self.accept?(location)
214
- # either a local ISO or a remote repository
215
- # (and not a remote file, but we don't have
216
- # a good way to check)
217
- Vmit::VFS::ISO.accept?(location) ||
218
- (Vmit::VFS::URI.accept?(location) &&
219
- File.extname(location.to_s) == '')
220
- end
221
-
222
- def initialize(vm, location)
223
- @location = location
224
- @vm = vm
225
- @media = Vmit::VFS.from(location)
226
-
227
- # TODO FIXME we need a clever way to detect the
228
- # location distro type. I could uname the kernel, but
229
- # I need the type to know the location.
230
- media_handler = case location.to_s.downcase
231
- when /fedora|redhat|centos/ then FedoraMedia
232
- when /suse/ then SUSEMedia
233
- when /debian/ then DebianMedia
234
- else
235
- raise "Don't know how to bootstrap media #{location}"
236
- end
237
- self.extend media_handler
238
-
239
- @boot_kernel = get_kernel
240
- @boot_initrd = get_initrd
241
- end
242
-
243
- def execute
244
- args = {}
245
- args.merge!({:kernel => @boot_kernel.path, :initrd => @boot_initrd.path})
246
- execute_autoinstall(args)
247
- end
248
- end
249
-
250
- class FromImage
251
-
252
- # @param [URI] location
253
- def self.accept?(location)
254
- uri = case location
255
- when ::URI then location
256
- else ::URI.parse(location.to_s)
257
- end
258
- return false unless ['.raw', '.qcow2'].include?(File.extname(uri.to_s))
259
- uri.scheme == 'http' || File.exist?(uri.to_s)
260
- end
261
-
262
- def initialize(vm, location)
263
- @location = location
264
- #http://download.suse.de/ibs/Devel:/Galaxy:/Manager:/1.7:/Appliance/images/SUSE_Manager_Server_pg_Devel.x86_64-1.7.0-Build3.126.raw.xz
265
- end
266
-
267
- def execute
268
- Vmit.logger.info "From media!!!"
269
- end
270
- end
271
-
272
- end
273
- end