vagrant-kvm 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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