vagrant-lxd 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 37988b3901f0e99417203fbab0b8c532e631f0c4
4
- data.tar.gz: c39bdfa2e6e7912cd5dc3cad36600bc6d98ff51d
3
+ metadata.gz: fef7b1d0ba6f86c3f621e843abe99b6bfcda266f
4
+ data.tar.gz: 2de77f085615f775deff08f65a10bdd584182647
5
5
  SHA512:
6
- metadata.gz: 1c14feb0f9522935357fe750329e288697bb8dc226218aeeebec74baa8e78afc36689a3972db637db9fa0e507e594dcfc9ae8df0c68a25550ee6359e536f6d35
7
- data.tar.gz: 68cb1f0440026627051a5754e64857b25a78dc5d7a0d155c798304af8676efff555a5e226e01be3daa6d4d258e0d64856fa6195070c8a8366004df987bade911
6
+ metadata.gz: cc3718c25b56973c47858ad5bc7711a23d0ba1a9ae43b9ab55f42dbf10cd2e67d4730948e92dbcb1e0eddbff595eabc815e4dfd952235766a1d8bb5e69c3dca7
7
+ data.tar.gz: c87aa4c96a58bf9162124a6fa910cabeb9ab29c17726ef4403a88a11ec74ff9f11124f49e39ebe13bdcaae38da71427cfcaa31267c3717dc882f5385edc8a9d0
data/Gemfile.lock CHANGED
@@ -27,13 +27,13 @@ GIT
27
27
  PATH
28
28
  remote: .
29
29
  specs:
30
- vagrant-lxd (0.4.0)
30
+ vagrant-lxd (0.4.1)
31
31
  hyperkit (~> 1.2.0)
32
32
 
33
33
  GEM
34
34
  remote: https://rubygems.org/
35
35
  specs:
36
- activesupport (5.2.2)
36
+ activesupport (5.2.3)
37
37
  concurrent-ruby (~> 1.0, >= 1.0.2)
38
38
  i18n (>= 0.7, < 2)
39
39
  minitest (~> 5.1)
data/README.md CHANGED
@@ -191,7 +191,7 @@ In order to run Linux containers on an LXD-backed machine, it must be
191
191
  created with the `nesting` and `privileged` properties set to `true`.
192
192
  These correspond to the `security.nesting` and `security.privileged`
193
193
  configuration items for LXD, respectively. Refer to LXD's [container
194
- configuration documentation][docs] for details.
194
+ configuration documentation][containers] for details.
195
195
 
196
196
  config.vm.provider 'lxd' do |lxd|
197
197
  lxd.nesting = true
@@ -202,7 +202,38 @@ Note that enabling these options will invalidate any user and group ID
202
202
  mappings you may have configured for synced folders, since privileged
203
203
  containers use the same UID and GID space as the host machine.
204
204
 
205
- [docs]: https://lxd.readthedocs.io/en/latest/containers/
205
+ [containers]: https://lxd.readthedocs.io/en/latest/containers/
206
+
207
+ ### Adding Devices
208
+
209
+ You can attach arbitrary devices to the container with the `devices`
210
+ setting. This should be a map of device names to configuration hashes,
211
+ where the hash keys and values are valid [device configuration
212
+ settings][device-config].
213
+
214
+ For example, the following configuration uses a `proxy` device to
215
+ forward local X11 traffic from the container to the host, allowing you
216
+ to run graphical applications transparently from within the guest:
217
+
218
+ # e.g. vagrant ssh -c 'DISPLAY=:0 firefox'
219
+ config.vm.provider 'lxd' do |lxd|
220
+ lxd.devices = {
221
+ x11: {
222
+ type: 'proxy',
223
+ mode: '0777',
224
+ bind: 'container',
225
+ listen: 'unix:/tmp/.X11-unix/X0',
226
+ connect: 'unix:/tmp/.X11-unix/X0',
227
+ 'security.uid': Process.uid.to_s,
228
+ 'security.gid': Process.gid.to_s,
229
+ }
230
+ }
231
+ end
232
+
233
+ Note that disk devices should be configured as [synced
234
+ folders](#synced-folders) rather than ad-hoc devices.
235
+
236
+ [device-config]: https://lxd.readthedocs.io/en/latest/containers/#device-configuration
206
237
 
207
238
  ## Hacking
208
239
 
@@ -227,6 +227,7 @@ module VagrantLXD
227
227
  c.use SetHostname
228
228
  c.use SyncedFolders
229
229
  c.use LXD.action(:resume)
230
+ c.use LXD.action(:reconnect)
230
231
  c.use WaitForCommunicator
231
232
  else
232
233
  c.use Message, :error, "Machine cannot be resumed while #{env[:machine_state]}."
@@ -26,6 +26,7 @@ module VagrantLXD
26
26
  attr_accessor :name
27
27
  attr_accessor :timeout
28
28
  attr_accessor :config
29
+ attr_accessor :devices
29
30
  attr_accessor :environment
30
31
  attr_accessor :ephemeral
31
32
  attr_accessor :nesting
@@ -40,6 +41,7 @@ module VagrantLXD
40
41
  @name = UNSET_VALUE
41
42
  @timeout = UNSET_VALUE
42
43
  @config = UNSET_VALUE
44
+ @devices = UNSET_VALUE
43
45
  @environment = UNSET_VALUE
44
46
  @nesting = UNSET_VALUE
45
47
  @privileged = UNSET_VALUE
@@ -74,15 +76,27 @@ module VagrantLXD
74
76
  if not config.is_a? Hash
75
77
  errors << "Invalid `config' (value must be a hash): #{config.inspect}"
76
78
  elsif not config.keys.all? { |x| x.is_a? Symbol }
77
- errors << "Invalid `config' (hash keys must be symbols): #{config.inspect}"
79
+ errors << "Invalid `config' (keys must be symbols): #{config.inspect}"
80
+ end
81
+
82
+ if not devices.is_a? Hash
83
+ errors << "Invalid `devices' (value must be a hash): #{devices.inspect}"
84
+ elsif not devices.keys.all? { |x| x.is_a? String or x.is_a? Symbol }
85
+ errors << "Invalid `devices' (keys must be strings or symbols): #{devices.inspect}"
86
+ elsif devices.keys.any? { |x| x =~ /^(.*([^a-z0-9.\-_]).*)$/ }
87
+ errors << "Invalid `devices' (device name `#{$1}' contains invalid character '#{$2}'): #{devices.inspect}"
88
+ elsif not devices.values.all? { |x| x.is_a? Hash }
89
+ errors << "Invalid `devices' (values must be hashes): #{devices.inspect}"
90
+ elsif not devices.values.map(&:values).flatten.all? { |x| x.is_a? String }
91
+ errors << "Invalid `devices' (device value must be strings): #{devices.inspect}"
78
92
  end
79
93
 
80
94
  if not environment.is_a? Hash
81
95
  errors << "Invalid `environment' (value must be a hash): #{environment.inspect}"
82
96
  elsif not environment.keys.all? { |x| x.is_a? String or x.is_a? Symbol }
83
- errors << "Invalid `environment' (hash keys must be strings or symbols): #{environment.inspect}"
97
+ errors << "Invalid `environment' (keys must be strings or symbols): #{environment.inspect}"
84
98
  elsif not environment.values.all? { |x| x.is_a? String }
85
- errors << "Invalid `environment' (hash values must be strings): #{environment.inspect}"
99
+ errors << "Invalid `environment' (values must be strings): #{environment.inspect}"
86
100
  end
87
101
 
88
102
  begin
@@ -151,6 +165,10 @@ module VagrantLXD
151
165
  @config = {}
152
166
  end
153
167
 
168
+ if devices == UNSET_VALUE
169
+ @devices = {}
170
+ end
171
+
154
172
  if environment == UNSET_VALUE
155
173
  @environment = {}
156
174
  end
@@ -18,6 +18,7 @@
18
18
  #
19
19
 
20
20
  require 'active_support/core_ext/object/deep_dup'
21
+ require 'active_support/core_ext/hash/except'
21
22
  require 'hyperkit'
22
23
  require 'securerandom'
23
24
  require 'tempfile'
@@ -112,11 +113,21 @@ module VagrantLXD
112
113
  end
113
114
  end
114
115
 
116
+ module Hyperkit::Client::Containers
117
+ alias extract_container_options_without_devices extract_container_options
118
+
119
+ def extract_container_options(name, options)
120
+ opts = extract_container_options_without_devices(name, options)
121
+ options.slice(:devices).merge(opts)
122
+ end
123
+ end
124
+
115
125
  NOT_CREATED = Vagrant::MachineState::NOT_CREATED_ID
116
126
 
117
127
  attr_reader :api_endpoint
118
128
  attr_reader :name
119
129
  attr_reader :timeout
130
+ attr_reader :devices
120
131
  attr_reader :environment
121
132
  attr_reader :ephemeral
122
133
  attr_reader :nesting
@@ -131,7 +142,8 @@ module VagrantLXD
131
142
  @machine = machine
132
143
  @timeout = machine.provider_config.timeout
133
144
  @api_endpoint = machine.provider_config.api_endpoint
134
- @config = @machine.provider_config.config
145
+ @config = machine.provider_config.config
146
+ @devices = machine.provider_config.devices
135
147
  @environment = machine.provider_config.environment
136
148
  @nesting = machine.provider_config.nesting
137
149
  @privileged = machine.provider_config.privileged
@@ -187,9 +199,7 @@ module VagrantLXD
187
199
 
188
200
  def unmount(name, options)
189
201
  container = lxd.container(machine_id)
190
- devices = container[:devices].to_hash
191
- devices.delete(name.to_sym)
192
- container[:devices] = devices
202
+ container[:devices] = container[:devices].to_hash.except(name.to_sym)
193
203
  lxd.update_container(machine_id, container)
194
204
  rescue Hyperkit::BadRequest => e
195
205
  @machine.ui.error 'Failed to unmount synced folder'
@@ -271,7 +281,7 @@ module VagrantLXD
271
281
  end
272
282
  end
273
283
 
274
- container = lxd.create_container(machine_id, ephemeral: ephemeral, fingerprint: fingerprint, config: config, profiles: profiles)
284
+ container = lxd.create_container(machine_id, devices: devices, ephemeral: ephemeral, fingerprint: fingerprint, config: config, profiles: profiles)
275
285
  @logger.debug 'Created container: ' << container.inspect
276
286
 
277
287
  @machine.id = machine_id
@@ -334,12 +344,42 @@ module VagrantLXD
334
344
  def configure
335
345
  container = lxd.container(machine_id)
336
346
  container[:config] = container[:config].to_hash.merge(config)
347
+ container[:devices] = container[:devices].to_hash.merge(devices)
337
348
  lxd.update_container(machine_id, container)
338
349
  rescue Hyperkit::Error => e
339
350
  @machine.ui.error 'Failed to configure container'
340
351
  fail ContainerConfigurationFailure, machine_name: @machine.name, reason: e.reason
341
352
  end
342
353
 
354
+ # When a container is restarted, the `forkproxy` processes that manage
355
+ # its proxy devices will persist but will not reliably recreate
356
+ # container-side listeners for devices that are configured with
357
+ # "bind=container". Removing and re-creating the devices forces the
358
+ # proxy processes to be recreated, ensuring the listeners are as well.
359
+ def reconnect
360
+ # select proxy devices
361
+ container = lxd.container(machine_id)
362
+ devices = container[:devices].to_hash
363
+ proxies = devices.select { |_, d| d[:type] == 'proxy' }
364
+
365
+ # bail if there's nothing to do
366
+ return if proxies.empty?
367
+
368
+ # TODO move messaging into a dedicated action
369
+ @machine.ui.info 'Reconnecting proxy devices...'
370
+
371
+ # remove proxy devices
372
+ container[:devices] = devices.except(*proxies.keys)
373
+ lxd.update_container(machine_id, container)
374
+
375
+ # restore all devices (including proxies)
376
+ container[:devices] = devices.merge(proxies)
377
+ lxd.update_container(machine_id, container)
378
+ rescue Hyperkit::Error => e
379
+ @machine.ui.error 'Failed to connect proxy devices'
380
+ fail ContainerConfigurationFailure, machine_name: @machine.name, reason: e.reason
381
+ end
382
+
343
383
  def info
344
384
  if in_state? :running, :frozen
345
385
  {
@@ -520,6 +560,7 @@ module VagrantLXD
520
560
  lxd_rootfs = lxd_dir / 'rootfs.tar.gz'
521
561
  lxd_metadata = YAML.load(File.read(lxd_dir / 'metadata.yaml')) rescue nil
522
562
 
563
+ # TODO move messaging into a dedicated action
523
564
  if lxd_rootfs.exist? and lxd_metadata.is_a? Hash and lxd_metadata['source_fingerprint'] == lxc_fingerprint
524
565
  @machine.ui.info 'Importing LXC image...'
525
566
  else
@@ -20,7 +20,7 @@
20
20
  module VagrantLXD
21
21
  module Version
22
22
  NAME = 'vagrant-lxd'
23
- VERSION = '0.4.0'
23
+ VERSION = '0.4.1'
24
24
  DESCRIPTION = 'Vagrant LXD provider'
25
25
  end
26
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-lxd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Hanson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-29 00:00:00.000000000 Z
11
+ date: 2019-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hyperkit
@@ -72,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
72
  version: '0'
73
73
  requirements: []
74
74
  rubyforge_project:
75
- rubygems_version: 2.6.8
75
+ rubygems_version: 2.6.12
76
76
  signing_key:
77
77
  specification_version: 4
78
78
  summary: Vagrant LXD provider