vagrant-kvm 0.1.7 → 0.1.8

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,44 @@
1
+ module VagrantPlugins
2
+ module ProviderKvm
3
+ module Action
4
+ class Customize
5
+ def initialize(app, env, event)
6
+ @app = app
7
+ @event = event
8
+ @logger = Log4r::Logger.new("vagrant::kvm::action::customize")
9
+ end
10
+
11
+ def call(env)
12
+ customizations = []
13
+ env[:machine].provider_config.customizations.each do |event, command|
14
+ if event == @event
15
+ customizations << command
16
+ end
17
+ end
18
+
19
+ if !customizations.empty?
20
+ @logger.info("customize.running")
21
+
22
+ # Execute each customization command.
23
+ customizations.each do |command|
24
+ processed_command = command.collect do |arg|
25
+ arg = env[:machine].id if arg == :id
26
+ arg.to_s
27
+ end
28
+
29
+ result = env[:machine].provider.driver.execute_command(processed_command)
30
+ if result.exit_code != 0
31
+ raise Vagrant::Errors::VMCustomizationFailed, {
32
+ :command => processed_command.inspect,
33
+ :error => result.stderr
34
+ }
35
+ end
36
+ end
37
+ end
38
+
39
+ @app.call(env)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -35,17 +35,53 @@ module VagrantPlugins
35
35
  :cpu_model => provider_config.cpu_model,
36
36
  :machine_type => provider_config.machine_type,
37
37
  :network_model => provider_config.network_model,
38
- :video_model => provider_config.video_model
38
+ :video_model => provider_config.video_model,
39
+ :virtio_rng => provider_config.virtio_rng
39
40
  }.merge(args)
40
41
 
42
+ args[:disk_bus] = provider_config.disk_bus if provider_config.disk_bus
43
+
44
+ # Permission/Security Model detection
45
+ driver = @env[:machine].provider.driver
46
+ # defaults
47
+ args[:userid] = Process.uid.to_s
48
+ args[:groupid] = Process.gid.to_s
49
+ args[:dirmode] = '0775'
50
+ args[:filemode] = '0664'
51
+ args[:label] = 'virt_image_t'
52
+ args[:secmodel] = nil
53
+ # Optional security label
54
+ if provider_config.seclabel == 'on'
55
+ # OS specific
56
+ if driver.host_redhat?
57
+ # on Redhat/Fedora, permission is controlled
58
+ # with only SELinux
59
+ args[:secmodel] = 'selinux'
60
+ args[:dirmode] = '0777'
61
+ args[:filemode] = '0666'
62
+ elsif driver.host_arch?
63
+ # XXX: should be configurable
64
+ args[:secmodel] = 'dac'
65
+ elsif driver.host_ubuntu?
66
+ args[:secmodel] = 'apparmor'
67
+ args[:groupid] = Etc.getgrnam('kvm').gid.to_s
68
+ elsif driver.host_debian?
69
+ # XXX: should be configurable
70
+ args[:secmodel] = 'dac'
71
+ args[:groupid] = Etc.getgrnam('kvm').gid.to_s
72
+ end
73
+ end
74
+
41
75
  # Import the virtual machine
42
- storage_path = File.join(@env[:tmp_path],"/storage-pool")
76
+
77
+ # Get storage pool directory
78
+ storage_path = @env[:machine].provider.driver.storage_pool_path
43
79
  box_file = @env[:machine].box.directory.join("box.xml").to_s
44
80
  raise Errors::KvmBadBoxFormat unless File.file?(box_file)
45
81
 
46
82
  # check pool migration neccesary?
47
83
  if @env[:machine].provider.driver.pool_migrate
48
- @env[:ui].output "Your vagrant-kvm environment should be fixed. see README"
84
+ @env[:ui].output I18n.t("vagrant_kvm.kvm_spool_problem_inform")
49
85
  end
50
86
 
51
87
  # repair directories permission
@@ -92,22 +128,15 @@ module VagrantPlugins
92
128
  box_name = @env[:machine].config.vm.box
93
129
  driver = @env[:machine].provider.driver
94
130
  userid = Process.uid.to_s
95
- groupid = Process.gid.to_s
96
- modes = {:dir => '0775', :file => '0664'}
97
- label = 'virt_image_t'
98
- if driver.host_redhat?
99
- # on Redhat/Fedora, permission is controlled
100
- # with only SELinux
101
- modes = {:dir => '0777',:file => '0666'}
102
- elsif driver.host_debian?
103
- groupid = Etc.getgrnam('kvm').gid.to_s
104
- else
105
- # XXX: default
131
+ begin
132
+ # vagrant 1.5+
133
+ box_version = @env[machine].config.vm.box_version
134
+ pool_name = 'vagrant_' + userid + '_' + box_name + '_' + box_version.to_s
135
+ rescue
136
+ # before varant 1.5
137
+ pool_name = 'vagrant_' + userid + '_' + box_name
106
138
  end
107
- pool_name = 'vagrant_' + userid + '_' + box_name
108
- driver.init_storage_directory(
109
- :pool_path => File.dirname(old_path), :pool_name => pool_name,
110
- :owner => userid, :group => groupid, :mode => modes[:dir])
139
+ driver.init_storage_pool(pool_name, File.dirname(old_path), args[:dirmode])
111
140
  driver.create_volume(
112
141
  :disk_name => new_disk,
113
142
  :capacity => box.capacity,
@@ -116,10 +145,10 @@ module VagrantPlugins
116
145
  :box_pool => pool_name,
117
146
  :box_path => old_path,
118
147
  :backing => args[:image_backing],
119
- :owner => userid,
120
- :group => groupid,
121
- :mode => modes[:file],
122
- :label => label)
148
+ :owner => args[:userid],
149
+ :group => args[:groupid],
150
+ :mode => args[:filemode],
151
+ :label => args[:label])
123
152
  driver.free_storage_pool(pool_name)
124
153
  else
125
154
  @logger.info "Image type #{args[:image_type]} is not supported"
@@ -139,7 +168,7 @@ module VagrantPlugins
139
168
  # check pathes
140
169
  [home_path, boxes_path].each do |d|
141
170
  s = File::Stat.new(d)
142
- @logger.debug("#{d} permission: #{s.mode}")
171
+ @logger.debug("#{d} permission: #{s.mode.to_s(8)}")
143
172
  if (s.mode & 1 == 0)
144
173
  @env[:ui].info I18n.t("vagrant_kvm.repair_permission",:directory => d,
145
174
  :old_mode => sprintf("%o",s.mode), :new_mode => sprintf("%o", s.mode|1))
@@ -8,10 +8,11 @@ module VagrantPlugins
8
8
  end
9
9
 
10
10
  def call(env)
11
- # Create a storage pool in tmp_path if it doesn't exist
12
- userid = Process.uid.to_s
13
- groupid = Process.gid.to_s
14
- Driver::Driver.new.init_storage(env[:tmp_path], userid, groupid)
11
+ # Create the storage pool in tmp_path if it doesn't exist
12
+ pool = env[:machine].provider_config.storage_pool
13
+ pool_path = File.join(env[:tmp_path], "/storage-pool")
14
+ env[:machine].provider.driver.init_storage_pool(pool, pool_path)
15
+ env[:machine].provider.driver.activate_storage_pool(pool)
15
16
 
16
17
  @app.call(env)
17
18
  end
@@ -9,51 +9,148 @@ module VagrantPlugins
9
9
  def initialize(app, env)
10
10
  @logger = Log4r::Logger.new("vagrant::plugins::kvm::network")
11
11
  @app = app
12
+ @hosts = []
12
13
  end
13
14
 
14
15
  def call(env)
15
- # TODO: Validate network configuration prior to anything below
16
16
  @env = env
17
17
 
18
- options= {}
19
- env[:machine].config.vm.networks.each do |type, network_options|
20
- options = network_options if type == :private_network
18
+ @env[:ui].info I18n.t("vagrant.actions.vm.network.preparing")
19
+ create_or_start_default_network!
20
+ create_or_update_private_network!
21
+
22
+ @app.call(env)
23
+ end
24
+
25
+ private
26
+
27
+ def create_or_start_default_network!
28
+ # default NAT network/nic
29
+ @env[:machine_ip] = select_default_ip
30
+ @env[:machine].provider.driver.create_network(
31
+ :name => get_network_name(@env[:machine_ip]),
32
+ :hosts => [{
33
+ :mac => @env[:machine].provider.driver.read_mac_address,
34
+ :name => get_host_name,
35
+ :ip => @env[:machine_ip]
36
+ }]
37
+ )
38
+ end
39
+
40
+ def create_or_update_private_network!
41
+ # enumerate private network options
42
+ private_network_options = []
43
+ @env[:machine].config.vm.networks.each do |type, network_options|
44
+ private_network_options << network_options if type == :private_network
21
45
  end
22
46
 
23
- options[:ip] = "192.168.123.10" unless options.has_key?(:ip)
24
- addr = options[:ip].split(".")
25
- addr[3] = "1"
26
- base_ip = addr.join(".")
27
- addr[3] = "100"
28
- start_ip = addr.join(".")
29
- addr[3] = "200"
30
- end_ip = addr.join(".")
31
- range = {
47
+ private_network_options.each_with_index do |option,index|
48
+ option = set_private_network_options(option)
49
+ if check_private_network_segment(option)
50
+ add_private_network_host(option, index)
51
+ else
52
+ @logger.info ("Ignore invalid private network definition.")
53
+ end
54
+ end
55
+ end
56
+
57
+ def get_host_name
58
+ if @env[:machine].provider.driver.name
59
+ @env[:machine].provider.driver.name
60
+ elsif @env[:machine].provider_config.name
61
+ @env[:machine].provider_config.name
62
+ else
63
+ "nic-"+Time.now.to_i.to_s
64
+ end
65
+ end
66
+
67
+ def get_network_name(ip)
68
+ subnet = ip.split(".")[2].to_s
69
+ default_subnet = @env[:machine].provider.driver.get_default_ip.split(".")[2].to_s
70
+ if subnet == default_subnet
71
+ "vagrant"
72
+ else
73
+ "vagrant-"+subnet
74
+ end
75
+ end
76
+
77
+ def add_private_network_host(option, index)
78
+ mac = random_mac
79
+ option[:hosts]= [{
80
+ :mac => mac,
81
+ :name => get_host_name,
82
+ :ip => option[:ip]
83
+ }]
84
+ addr = option[:ip].split(".")
85
+ nic = { :mac => mac,
86
+ :name=> "eth"+(index+1).to_s,
87
+ :network => "vagrant-"+addr[2].to_s,
88
+ :type => 'network',
89
+ :model => 'virtio'}
90
+ @env[:machine].provider.driver.add_nic(nic)
91
+ @env[:machine].provider.driver.create_network(option)
92
+ end
93
+
94
+ def select_default_ip
95
+ ip_addresses = @env[:machine].provider.driver.list_default_network_ips
96
+ candidate = ""
97
+ loop do
98
+ candidate = 2 + Random.rand(253)
99
+ candidate = "192.168.123.%d" % candidate
100
+ break unless ip_addresses.include?(candidate)
101
+ end
102
+ @logger.info("select #{candidate} as default ip address for nic")
103
+ candidate
104
+ end
105
+
106
+ # check options[:ip] is not reserved?
107
+ def check_private_network_segment(options)
108
+ if options.has_key?(:ip)
109
+ addr = options[:ip].split(".")
110
+ # except for virbr{0|1} and hostonly network
111
+ if @env[:machine].provider.driver.host_ubuntu?
112
+ return false if addr[2] == '122' || addr[2] == '100' || addr[2] == '123'
113
+ else
114
+ return false if addr[2] == '123'
115
+ end
116
+ end
117
+ true
118
+ end
119
+
120
+ def set_private_network_options(options)
121
+ if options.has_key?(:ip)
122
+ addr = options[:ip].split(".")
123
+ addr[3] = "1"
124
+ base_ip = addr.join(".")
125
+ addr[3] = "100"
126
+ start_ip = addr.join(".")
127
+ addr[3] = "200"
128
+ end_ip = addr.join(".")
129
+ range = {
32
130
  :start => start_ip,
33
131
  :end => end_ip }
34
- options = {
132
+ options = {
35
133
  :base_ip => base_ip,
36
134
  :netmask => "255.255.255.0",
37
- :range => range
38
- }.merge(options)
39
-
40
- hosts = []
41
- name = env[:machine].provider_config.name ?
42
- env[:machine].provider_config.name : "default"
43
- hosts << {
44
- :mac => format_mac(env[:machine].config.vm.base_mac),
45
- :name => name,
46
- :ip => options[:ip]
47
- }
48
- options[:hosts] = hosts
49
-
50
- env[:ui].info I18n.t("vagrant.actions.vm.network.preparing")
51
- env[:machine].provider.driver.create_network(options)
135
+ :range => range,
136
+ :name => "vagrant-" + addr[2].to_s,
137
+ :domain_name => "vagrant.local"
138
+ }.merge(options)
139
+ end
140
+ options
141
+ end
52
142
 
53
- @app.call(env)
143
+ def random_mac
144
+ rng = Random.new(Time.now.to_i)
145
+ mac = [0x00, 0x16, 0x3e,
146
+ rng.rand(128),
147
+ rng.rand(256),
148
+ rng.rand(256)]
149
+ mac.map {|x| "%02x" % x}.join(":")
54
150
  end
55
151
 
56
152
  def format_mac(mac)
153
+ return nil unless mac
57
154
  if mac.length == 12
58
155
  mac = mac[0..1] + ":" + mac[2..3] + ":" +
59
156
  mac[4..5] + ":" + mac[6..7] + ":" +
@@ -1,7 +1,7 @@
1
1
  module VagrantPlugins
2
2
  module ProviderKvm
3
3
  module Action
4
- class PrepareGui
4
+ class PrepareKvmConfig
5
5
  def initialize(app, env)
6
6
  @app = app
7
7
  end
@@ -12,6 +12,9 @@ module VagrantPlugins
12
12
  driver = env[:machine].provider.driver
13
13
  driver.set_gui(config.vnc_port, config.vnc_autoport, config.vnc_password)
14
14
  end
15
+ # set disk_bus customize
16
+ disk_bus = env[:machine].provider_config.disk_bus
17
+ env[:machine].provider.driver.set_diskbus(disk_bus) if disk_bus
15
18
  @app.call(env)
16
19
  end
17
20
  end
@@ -11,42 +11,35 @@ module VagrantPlugins
11
11
  @app.call(env)
12
12
  @machine = env[:machine]
13
13
 
14
- env[:nfs_host_ip] = read_host_ip(env[:machine])
15
- env[:nfs_machine_ip] = read_machine_ip(env[:machine])
14
+ if using_nfs?
15
+ env[:nfs_host_ip] = read_host_ip
16
+ env[:nfs_machine_ip] = read_machine_ip
17
+ end
18
+ end
16
19
 
20
+ def using_nfs?
21
+ @machine.config.vm.synced_folders.any? { |_, opts| opts[:type] == :nfs }
17
22
  end
18
23
 
19
- # Returns the IP address of the first host only network adapter
24
+ # Returns the IP address of the host
20
25
  #
21
26
  # @param [Machine] machine
22
27
  # @return [String]
23
- def read_host_ip(machine)
24
- ip = read_machine_ip(machine)
25
- if ip
26
- base_ip = ip.split(".")
27
- base_ip[3] = "1"
28
- return base_ip.join(".")
29
- end
30
-
31
- # If no private network configuration, return default ip
32
- "192.168.123.1"
28
+ def read_host_ip
29
+ ip = read_machine_ip
30
+ base_ip = ip.split(".")
31
+ base_ip[3] = "1"
32
+ base_ip.join(".")
33
33
  end
34
34
 
35
35
  # Returns the IP address of the guest by looking at the first
36
36
  # enabled host only network.
37
37
  #
38
38
  # @return [String]
39
- def read_machine_ip(machine)
40
- machine.config.vm.networks.each do |type, options|
41
- if type == :private_network && options[:ip].is_a?(String)
42
- return options[:ip]
43
- end
44
- end
45
-
46
- # XXX duplicated with network.rb default
47
- # If no private network configuration, return default ip
48
- "192.168.123.10"
39
+ def read_machine_ip
40
+ @machine.provider.driver.read_machine_ip
49
41
  end
42
+
50
43
  end
51
44
  end
52
45
  end
@@ -10,18 +10,42 @@ module VagrantPlugins
10
10
  def call(env)
11
11
  name = env[:machine].provider_config.name
12
12
 
13
+ # If we already set the name before, then don't do anything
14
+ sentinel = env[:machine].data_dir.join("action_set_name")
15
+ if !name && sentinel.file?
16
+ @logger.info("Default name was already set before, not doing it again.")
17
+ return @app.call(env)
18
+ end
19
+
20
+ # If no name was manually set, then use a default
13
21
  if !name
14
- prefix = env[:root_path].basename.to_s
22
+ prefix = "#{env[:root_path].basename.to_s}_#{env[:machine].name}"
15
23
  prefix.gsub!(/[^-a-z0-9_]/i, "")
16
- name = prefix + "_#{Time.now.to_i}"
24
+ name = prefix + "_#{(Time.now.to_f * 1000.0).to_i}_#{rand(100000)}"
17
25
  end
18
26
 
19
27
  # @todo raise error if name is taken in kvm
20
- # @todo don't set the name if the vm already has a name
28
+ # Verify the name is not taken
29
+ # vms = env[:machine].provider.driver.read_vms
30
+ #raise Vagrant::Errors::VMNameExists, :name => name if \
31
+ # vms.has_key?(name) && vms[name] != env[:machine].id
32
+ #
33
+ #if vms.has_key?(name)
34
+ # @logger.info("Not setting the name because our name is already set.")
35
+ #else
36
+ # env[:ui].info(I18n.t(
37
+ # "vagrant.actions.vm.set_name.setting_name", name: name))
38
+ # env[:machine].provider.driver.set_name(name)
39
+ #end
21
40
 
22
41
  @logger.info("Setting the name of the VM: #{name}")
23
42
  env[:machine].provider.driver.set_name(name)
24
43
 
44
+ # Create the sentinel
45
+ sentinel.open("w") do |f|
46
+ f.write(Time.now.to_i.to_s)
47
+ end
48
+
25
49
  @app.call(env)
26
50
  end
27
51