vagrant-lxc 1.0.0.alpha.2 → 1.0.0.alpha.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f16ecc96c3d6f94a025db26d4fa9acfdbd29f153
4
- data.tar.gz: 67475bf75d68f60d9a45f913258fc08e4d3d57c9
3
+ metadata.gz: bd50ec26aecfabf94b58e9f16ff0a996fc6d7598
4
+ data.tar.gz: ae1c22bb9caf6b7b233d0acc100437619f3b5728
5
5
  SHA512:
6
- metadata.gz: 43322e18345da08c92c6beb2a0a8c38cf33dacd4b6b2f05c4222333a23c2e6a39ad25a4fa61d022355d8ab3b6e57de7bbfe0b7d83958a56b5c71d5131038a30c
7
- data.tar.gz: ee9ed4e6f30c100a21a07e57bc7eb9ee83f88aa12d8e8d8927e0dff8b26bf5f9bdeb5f05cf72e8c3ffc8f0bc7763531342fd5de660ef38326a61acbcd26aaa40
6
+ metadata.gz: 1235a0aa274186d0181eadda1f1491ecde4484f96dfc1f50a6b313621da5cd35ce06f75d43dc4a74281c27e55aabc65949187c7abe3f484a9e574f191b8fe536
7
+ data.tar.gz: 91a879e4104ea0c7e2104c36e91147037ba76f0a3c37e79e7cc9f2e4e3a5ec279b39d6b99f84f12399bae2c24ec38ed8a2dab47957f4dc356b0bb8d36e075f85
data/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ ## [1.0.0.alpha.3](https://github.com/fgrehm/vagrant-lxc/compare/v1.0.0.alpha.2...v1.0.0.alpha.3) (Aug 9, 2014)
2
+
3
+ IMPROVEMENTS:
4
+
5
+ - Remove `lxc-shutdown` usage in favor of Vagrant's built in graceful halt
6
+ - Add fallback mechanism for platforms without `lxc-attach` support [[GH-294]]
7
+
8
+ [GH-294]: https://github.com/fgrehm/vagrant-lxc/pull/294
9
+
10
+ BUG FIXES:
11
+
12
+ - Figure out the real executable paths for whitelisted commands on the sudo
13
+ wrapper script instead of hardcoding Ubuntu paths [[GH-304]] / [[GH-305]]
14
+ - Attach to containers using the `MOUNT` namespace when attempting to fetch
15
+ container's IP [[GH-300]]
16
+ - Escape space characters for synced folders [[GH-291]]
17
+ - Use Vagrant's ruby on the sudoers file so that it works on systems that don't
18
+ have a global ruby installation [[GH-289]]
19
+
20
+ [GH-304]: https://github.com/fgrehm/vagrant-lxc/issues/304
21
+ [GH-305]: https://github.com/fgrehm/vagrant-lxc/issues/305
22
+ [GH-300]: https://github.com/fgrehm/vagrant-lxc/issues/300
23
+ [GH-291]: https://github.com/fgrehm/vagrant-lxc/issues/291
24
+ [GH-289]: https://github.com/fgrehm/vagrant-lxc/issues/289
25
+
26
+
1
27
  ## [1.0.0.alpha.2](https://github.com/fgrehm/vagrant-lxc/compare/v1.0.0.alpha.1...v1.0.0.alpha.2) (May 13, 2014)
2
28
 
3
29
  BACKWARDS INCOMPATIBILITIES:
data/Gemfile CHANGED
@@ -9,7 +9,7 @@ end
9
9
 
10
10
  group :development, :test do
11
11
  gem 'rake'
12
- gem 'rspec', '2.99.0.beta2'
12
+ gem 'rspec', '2.99.0'
13
13
  gem 'coveralls', require: (ENV['COVERAGE'] == 'true')
14
14
  gem 'vagrant-spec', git: 'https://github.com/mitchellh/vagrant-spec.git'
15
15
  end
data/Gemfile.lock CHANGED
@@ -1,6 +1,6 @@
1
1
  GIT
2
2
  remote: https://github.com/fgrehm/vagrant-cachier.git
3
- revision: 6e160ba4cbfc197f8fff1db385fb9d6b9463eba1
3
+ revision: 6f275353b82ab57ada04c79f6fb2befce0395c77
4
4
  specs:
5
5
  vagrant-cachier (0.7.2)
6
6
 
@@ -22,9 +22,9 @@ GIT
22
22
 
23
23
  GIT
24
24
  remote: https://github.com/mitchellh/vagrant.git
25
- revision: 9475ed9a50650b88db444ac07a7034775d3b814e
25
+ revision: 0a5f6bb77e6a61b56c96057de94f5f8c6868e27c
26
26
  specs:
27
- vagrant (1.6.2)
27
+ vagrant (1.6.4.dev)
28
28
  bundler (>= 1.5.2, < 1.7.0)
29
29
  childprocess (~> 0.5.0)
30
30
  erubis (~> 2.7.0)
@@ -40,7 +40,7 @@ GIT
40
40
  PATH
41
41
  remote: .
42
42
  specs:
43
- vagrant-lxc (1.0.0.alpha.2)
43
+ vagrant-lxc (1.0.0.alpha.3)
44
44
 
45
45
  GEM
46
46
  remote: https://rubygems.org/
@@ -51,9 +51,6 @@ GEM
51
51
  builder (3.2.2)
52
52
  celluloid (0.15.2)
53
53
  timers (~> 1.1.0)
54
- celluloid-io (0.15.0)
55
- celluloid (>= 0.15.0)
56
- nio4r (>= 0.5.0)
57
54
  childprocess (0.5.3)
58
55
  ffi (~> 1.0, >= 1.0.11)
59
56
  coderay (1.1.0)
@@ -67,7 +64,7 @@ GEM
67
64
  docile (1.1.3)
68
65
  erubis (2.7.0)
69
66
  ffi (1.9.3)
70
- formatador (0.2.4)
67
+ formatador (0.2.5)
71
68
  gssapi (1.0.3)
72
69
  ffi (>= 1.0.1)
73
70
  guard (2.6.1)
@@ -81,13 +78,12 @@ GEM
81
78
  rspec (>= 2.14, < 4.0)
82
79
  gyoku (1.1.1)
83
80
  builder (>= 2.1.2)
84
- httpclient (2.3.4.1)
81
+ httpclient (2.4.0)
85
82
  httpi (0.9.7)
86
83
  rack
87
84
  i18n (0.6.9)
88
- listen (2.7.4)
85
+ listen (2.7.7)
89
86
  celluloid (>= 0.15.2)
90
- celluloid-io (>= 0.15.0)
91
87
  rb-fsevent (>= 0.9.3)
92
88
  rb-inotify (>= 0.9)
93
89
  little-plugger (1.1.3)
@@ -95,39 +91,38 @@ GEM
95
91
  logging (1.8.2)
96
92
  little-plugger (>= 1.1.3)
97
93
  multi_json (>= 1.8.4)
98
- lumberjack (1.0.5)
94
+ lumberjack (1.0.6)
99
95
  method_source (0.8.2)
100
- mime-types (2.2)
101
- mini_portile (0.5.3)
102
- multi_json (1.10.0)
96
+ mime-types (2.3)
97
+ mini_portile (0.6.0)
98
+ multi_json (1.10.1)
103
99
  net-scp (1.1.2)
104
100
  net-ssh (>= 2.6.5)
105
- net-ssh (2.9.0)
106
- nio4r (1.0.0)
107
- nokogiri (1.6.2)
108
- mini_portile (~> 0.5.2)
101
+ net-ssh (2.9.1)
102
+ nokogiri (1.6.2.1)
103
+ mini_portile (= 0.6.0)
109
104
  nori (1.1.5)
110
105
  pry (0.9.12.6)
111
106
  coderay (~> 1.0)
112
107
  method_source (~> 0.8)
113
108
  slop (~> 3.4)
114
109
  rack (1.5.2)
115
- rake (10.3.1)
110
+ rake (10.3.2)
116
111
  rb-fsevent (0.9.4)
117
- rb-inotify (0.9.4)
112
+ rb-inotify (0.9.5)
118
113
  ffi (>= 0.5.0)
119
- rb-kqueue (0.2.2)
114
+ rb-kqueue (0.2.3)
120
115
  ffi (>= 0.5.0)
121
116
  rest-client (1.6.7)
122
117
  mime-types (>= 1.16)
123
- rspec (2.99.0.beta2)
124
- rspec-core (= 2.99.0.beta2)
125
- rspec-expectations (= 2.99.0.beta2)
126
- rspec-mocks (= 2.99.0.beta2)
127
- rspec-core (2.99.0.beta2)
128
- rspec-expectations (2.99.0.beta2)
118
+ rspec (2.99.0)
119
+ rspec-core (~> 2.99.0)
120
+ rspec-expectations (~> 2.99.0)
121
+ rspec-mocks (~> 2.99.0)
122
+ rspec-core (2.99.0)
123
+ rspec-expectations (2.99.0)
129
124
  diff-lcs (>= 1.1.3, < 2.0)
130
- rspec-mocks (2.99.0.beta2)
125
+ rspec-mocks (2.99.0)
131
126
  rubyntlm (0.1.1)
132
127
  savon (0.9.5)
133
128
  akami (~> 1.0)
@@ -147,7 +142,7 @@ GEM
147
142
  tins (~> 1.0)
148
143
  thor (0.18.1)
149
144
  timers (1.1.0)
150
- tins (1.2.0)
145
+ tins (1.3.0)
151
146
  uuidtools (2.1.4)
152
147
  vagrant-omnibus (1.4.1)
153
148
  wasabi (1.0.0)
@@ -171,7 +166,7 @@ DEPENDENCIES
171
166
  guard-rspec
172
167
  rake
173
168
  rb-inotify
174
- rspec (= 2.99.0.beta2)
169
+ rspec (= 2.99.0)
175
170
  vagrant!
176
171
  vagrant-cachier!
177
172
  vagrant-lxc!
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # vagrant-lxc
2
2
 
3
- [![Build Status](https://travis-ci.org/fgrehm/vagrant-lxc.png?branch=master)](https://travis-ci.org/fgrehm/vagrant-lxc) [![Gem Version](https://badge.fury.io/rb/vagrant-lxc.png)](http://badge.fury.io/rb/vagrant-lxc) [![Code Climate](https://codeclimate.com/github/fgrehm/vagrant-lxc.png)](https://codeclimate.com/github/fgrehm/vagrant-lxc) [![Coverage Status](https://coveralls.io/repos/fgrehm/vagrant-lxc/badge.png?branch=master)](https://coveralls.io/r/fgrehm/vagrant-lxc) [![Gittip](http://img.shields.io/gittip/fgrehm.svg)](https://www.gittip.com/fgrehm/)
3
+ [![Build Status](https://travis-ci.org/fgrehm/vagrant-lxc.png?branch=master)](https://travis-ci.org/fgrehm/vagrant-lxc) [![Gem Version](https://badge.fury.io/rb/vagrant-lxc.png)](http://badge.fury.io/rb/vagrant-lxc) [![Code Climate](https://codeclimate.com/github/fgrehm/vagrant-lxc.png)](https://codeclimate.com/github/fgrehm/vagrant-lxc) [![Coverage Status](https://coveralls.io/repos/fgrehm/vagrant-lxc/badge.png?branch=master)](https://coveralls.io/r/fgrehm/vagrant-lxc) [![Gittip](http://img.shields.io/gittip/fgrehm.svg)](https://www.gittip.com/fgrehm/) [![Gitter chat](https://badges.gitter.im/fgrehm/vagrant-lxc.png)](https://gitter.im/fgrehm/vagrant-lxc)
4
4
 
5
5
  [LXC](http://lxc.sourceforge.net/) provider for [Vagrant](http://www.vagrantup.com/) 1.1+
6
6
 
@@ -20,7 +20,7 @@ branch.
20
20
  * Port forwarding via [`redir`](http://linux.die.net/man/1/redir)
21
21
 
22
22
  As of now, it does not support public / private networks, but [private networks](https://github.com/fgrehm/vagrant-lxc/issues/120)
23
- will be coming along _soon_.
23
+ will be coming along with the final 1.0.0 release.
24
24
 
25
25
  ## Requirements
26
26
 
@@ -49,7 +49,7 @@ disable checksum offloading as described on [this comment](https://github.com/fg
49
49
  On Vagrant 1.5+:
50
50
 
51
51
  ```
52
- vagrant plugin install vagrant-lxc --plugin-version 1.0.0.alpha.2
52
+ vagrant plugin install vagrant-lxc --plugin-version 1.0.0.alpha.3
53
53
  ```
54
54
 
55
55
  On Vagrant < 1.5:
@@ -165,7 +165,7 @@ are not supported on mainstream kernels. To work around that, you can use the
165
165
  whitelisting all commands required by `vagrant-lxc` to run.
166
166
 
167
167
  If you are interested on what will be generated by that command, please check
168
- [this code](lib/vagrant-lxc/commands/sudoers.rb).
168
+ [this code](lib/vagrant-lxc/command/sudoers.rb).
169
169
 
170
170
  _vagrant-lxc < 1.0.0 users, please check this [Wiki page](https://github.com/fgrehm/vagrant-lxc/wiki/Avoiding-%27sudo%27-passwords)_
171
171
 
@@ -197,8 +197,14 @@ module Vagrant
197
197
  def self.action_fetch_ip
198
198
  Builder.new.tap do |b|
199
199
  b.use Builtin::ConfigValidate
200
- b.use FetchIpWithLxcAttach
201
- b.use FetchIpFromDnsmasqLeases
200
+ b.use Builtin::Call, Builtin::IsState, :running do |env, b2|
201
+ if env[:result]
202
+ b2.use FetchIpWithLxcAttach if env[:machine].provider.driver.supports_attach?
203
+ b2.use FetchIpFromDnsmasqLeases
204
+ else
205
+ b2.use Builtin::Message, I18n.t("vagrant_lxc.messages.not_running")
206
+ end
207
+ end
202
208
  end
203
209
  end
204
210
 
@@ -32,7 +32,7 @@ module Vagrant
32
32
 
33
33
  # From: https://github.com/lxc/lxc/blob/staging/src/python-lxc/lxc/__init__.py#L371-L385
34
34
  def get_container_ip_from_ip_addr(driver)
35
- output = driver.attach '/sbin/ip', '-4', 'addr', 'show', 'scope', 'global', 'eth0', namespaces: 'network'
35
+ output = driver.attach '/sbin/ip', '-4', 'addr', 'show', 'scope', 'global', 'eth0', namespaces: ['network', 'mount']
36
36
  if output =~ /^\s+inet ([0-9.]+)\/[0-9]+\s+/
37
37
  return $1.to_s
38
38
  end
@@ -40,135 +40,25 @@ module Vagrant
40
40
  end
41
41
 
42
42
  private
43
- # REFACTOR: Make use ERB rendering after https://github.com/mitchellh/vagrant/issues/3231
44
- # lands into core
43
+
44
+ # This requires vagrant 1.5.2+ https://github.com/mitchellh/vagrant/commit/3371c3716278071680af9b526ba19235c79c64cb
45
45
  def create_wrapper!
46
46
  wrapper = Tempfile.new('lxc-wrapper').tap do |file|
47
- file.puts "#!/usr/bin/env ruby"
48
- file.puts "# Automatically created by vagrant-lxc"
49
- file.puts <<-EOF
50
- class Whitelist
51
- class << self
52
- def add(command, *args)
53
- list[command] << args
54
- end
55
-
56
- def list
57
- @list ||= Hash.new do |key, hsh|
58
- key[hsh] = []
59
- end
60
- end
61
-
62
- def allowed(command)
63
- list[command] || []
64
- end
65
-
66
- def run!(argv)
67
- begin
68
- command, args = `which \#{argv.shift}`.chomp, argv || []
69
- check!(command, args)
70
- puts `\#{command} \#{args.join(" ")}`
71
- exit $?.to_i
72
- rescue => e
73
- STDERR.puts e.message
74
- exit 1
75
- end
76
- end
77
-
78
- private
79
- def check!(command, args)
80
- allowed(command).each do |checks|
81
- return if valid_args?(args, checks)
82
- end
83
- raise_invalid(command, args)
84
- end
85
-
86
- def valid_args?(args, checks)
87
- return false unless valid_length?(args, checks)
88
- check = nil
89
- args.each_with_index do |provided, i|
90
- check = checks[i] unless check == '**'
91
- return false unless match?(provided, check)
92
- end
93
- true
94
- end
95
-
96
- def valid_length?(args, checks)
97
- args.length == checks.length || checks.last == '**'
98
- end
99
-
100
- def match?(arg, check)
101
- check == '**' || check.is_a?(Regexp) && !!check.match(arg) || arg == check
102
- end
103
-
104
- def raise_invalid(command, args)
105
- raise "Invalid arguments for command \#{command}, " <<
106
- "provided args: \#{args.inspect}"
107
- end
108
- end
109
- end
110
-
111
- base = "/var/lib/lxc"
112
- base_path = %r{\\A\#{base}/.*\\z}
113
- templates_path = %r{\\A/usr/(share|lib|lib64|local/lib)/lxc/templates/.*\\z}
114
-
115
- ##
116
- # Commands from provider.rb
117
- # - Check lxc is installed
118
- Whitelist.add '/usr/bin/which', /\\Alxc-\\w+\\z/
119
-
120
- ##
121
- # Commands from driver.rb
122
- # - Container config file
123
- Whitelist.add '/bin/cat', base_path
124
- # - Shared folders
125
- Whitelist.add '/bin/mkdir', '-p', base_path
126
- # - Container config customizations and pruning
127
- Whitelist.add '/bin/cp', '-f', %r{/tmp/.*}, base_path
128
- Whitelist.add '/bin/chown', 'root:root', base_path
129
- # - Template import
130
- Whitelist.add '/bin/cp', %r{\\A.*\\z}, templates_path
131
- Whitelist.add '/bin/cp', %r{\\A.*\\z}, templates_path
132
- Whitelist.add '/bin/cp', %r{\\A.*\\z}, templates_path
133
- Whitelist.add '/bin/chmod', '+x', templates_path
134
- # - Template removal
135
- Whitelist.add '/bin/rm', templates_path
136
- # - Packaging
137
- Whitelist.add '/bin/tar', '--numeric-owner', '-cvzf', %r{/tmp/.*/rootfs.tar.gz}, '-C', base_path, './rootfs'
138
- Whitelist.add '/bin/chown', /\\A\\d+:\\d+\\z/, %r{\\A/tmp/.*/rootfs\.tar\.gz\\z}
139
-
140
- ##
141
- # Commands from driver/cli.rb
142
- Whitelist.add '/usr/bin/lxc-version'
143
- Whitelist.add '/usr/bin/lxc-ls'
144
- Whitelist.add '/usr/bin/lxc-info', '--name', /.*/
145
- Whitelist.add '/usr/bin/lxc-create', '-B', /.*/, '--template', /.*/, '--name', /.*/, '**'
146
- Whitelist.add '/usr/bin/lxc-destroy', '--name', /.*/
147
- Whitelist.add '/usr/bin/lxc-start', '-d', '--name', /.*/, '**'
148
- Whitelist.add '/usr/bin/lxc-stop', '--name', /.*/
149
- Whitelist.add '/usr/bin/lxc-shutdown', '--name', /.*/
150
- Whitelist.add '/usr/bin/lxc-attach', '--name', /.*/, '**'
151
- Whitelist.add '/usr/bin/lxc-attach', '-h'
152
-
153
- ##
154
- # Commands from driver/action/remove_temporary_files.rb
155
- Whitelist.add '/bin/rm', '-rf', %r{\\A\#{base}/.*/rootfs/tmp/.*}
156
-
157
- # Watch out for stones
158
- Whitelist.run!(ARGV)
159
- EOF
47
+ template = Vagrant::Util::TemplateRenderer.new(
48
+ 'sudoers.rb',
49
+ :template_root => Vagrant::LXC.source_root.join('templates').to_s,
50
+ :cmd_paths => build_cmd_paths_hash
51
+ )
52
+ file.puts template.render
160
53
  end
161
54
  wrapper.close
162
55
  wrapper.path
163
56
  end
164
57
 
165
- # REFACTOR: Make use ERB rendering after https://github.com/mitchellh/vagrant/issues/3231
166
- # lands into core
167
58
  def create_sudoers!(user, command)
168
59
  sudoers = Tempfile.new('vagrant-lxc-sudoers').tap do |file|
169
60
  file.puts "# Automatically created by vagrant-lxc"
170
- file.puts "Cmnd_Alias LXC = #{command}"
171
- file.puts "#{user} ALL=(root) NOPASSWD: LXC"
61
+ file.puts "#{user} ALL=(root) NOPASSWD: #{command}"
172
62
  end
173
63
  sudoers.close
174
64
  sudoers.path
@@ -185,6 +75,15 @@ Whitelist.run!(ARGV)
185
75
  }.flatten
186
76
  system "echo \"#{commands.join("; ")}\" | sudo sh"
187
77
  end
78
+
79
+ def build_cmd_paths_hash
80
+ {}.tap do |hash|
81
+ %w( which cat mkdir cp chown chmod rm tar chown ).each do |cmd|
82
+ hash[cmd] = `which #{cmd}`.strip
83
+ end
84
+ hash['lxc_bin'] = Pathname(`which lxc-create`.strip).parent.to_s
85
+ end
86
+ end
188
87
  end
189
88
  end
190
89
  end
@@ -84,6 +84,8 @@ module Vagrant
84
84
  end
85
85
 
86
86
  mount_options = Array(mount_options || ['bind'])
87
+ host_path = host_path.to_s.gsub(' ', '\\\040')
88
+ guest_path = guest_path.gsub(' ', '\\\040')
87
89
  @customizations << ['mount.entry', "#{host_path} #{guest_path} none #{mount_options.join(',')} 0 0"]
88
90
  end
89
91
 
@@ -102,10 +104,6 @@ module Vagrant
102
104
 
103
105
  def forced_halt
104
106
  @logger.info('Shutting down container...')
105
- # TODO: Remove `lxc-shutdown` usage, graceful halt is enough
106
- @cli.transition_to(:stopped) { |c| c.shutdown }
107
- # REFACTOR: Do not use exception to control the flow
108
- rescue CLI::TargetStateNotReached, CLI::ShutdownNotSupported
109
107
  @cli.transition_to(:stopped) { |c| c.stop }
110
108
  end
111
109
 
@@ -113,6 +111,10 @@ module Vagrant
113
111
  @cli.destroy
114
112
  end
115
113
 
114
+ def supports_attach?
115
+ @cli.supports_attach?
116
+ end
117
+
116
118
  def attach(*command)
117
119
  @cli.attach(*command)
118
120
  end
@@ -10,7 +10,6 @@ module Vagrant
10
10
  attr_accessor :name
11
11
 
12
12
  class TransitionBlockNotProvided < RuntimeError; end
13
- class ShutdownNotSupported < RuntimeError; end
14
13
  class TargetStateNotReached < RuntimeError
15
14
  def initialize(target_state, state)
16
15
  msg = "Target state '#{target_state}' not reached, currently on '#{state}'"
@@ -77,19 +76,10 @@ module Vagrant
77
76
  end
78
77
 
79
78
  def stop
80
- attach '/sbin/halt'
79
+ attach '/sbin/halt' if supports_attach?
81
80
  run :stop, '--name', @name
82
81
  end
83
82
 
84
- def shutdown
85
- if system('which lxc-shutdown > /dev/null')
86
- run :shutdown, '--name', @name
87
- else
88
- # REFACTOR: Do not use exception to control the flow
89
- raise ShutdownNotSupported
90
- end
91
- end
92
-
93
83
  def attach(*cmd)
94
84
  cmd = ['--'] + cmd
95
85
 
@@ -97,6 +87,11 @@ module Vagrant
97
87
  opts = cmd.pop
98
88
  namespaces = Array(opts[:namespaces]).map(&:upcase).join('|')
99
89
 
90
+ # HACK: The wrapper script should be able to handle this
91
+ if @sudo_wrapper.wrapper_path
92
+ namespaces = "'#{namespaces}'"
93
+ end
94
+
100
95
  if namespaces
101
96
  if supports_attach_with_namespaces?
102
97
  extra = ['--namespaces', namespaces]
@@ -126,6 +121,19 @@ module Vagrant
126
121
  end
127
122
  end
128
123
 
124
+ def supports_attach?
125
+ unless defined?(@supports_attach)
126
+ begin
127
+ @supports_attach = true
128
+ run(:attach, '--name', @name, '--', '/bin/true')
129
+ rescue LXC::Errors::ExecuteError
130
+ @supports_attach = false
131
+ end
132
+ end
133
+
134
+ return @supports_attach
135
+ end
136
+
129
137
  private
130
138
 
131
139
  def run(command, *args)
@@ -4,6 +4,8 @@ module Vagrant
4
4
  # Include this so we can use `Subprocess` more easily.
5
5
  include Vagrant::Util::Retryable
6
6
 
7
+ attr_reader :wrapper_path
8
+
7
9
  def initialize(wrapper_path = nil)
8
10
  @wrapper_path = wrapper_path
9
11
  @logger = Log4r::Logger.new("vagrant::lxc::sudo_wrapper")
@@ -1,5 +1,5 @@
1
1
  module Vagrant
2
2
  module LXC
3
- VERSION = "1.0.0.alpha.2"
3
+ VERSION = "1.0.0.alpha.3"
4
4
  end
5
5
  end
@@ -4,7 +4,7 @@ require 'vagrant-lxc/sudo_wrapper'
4
4
  require 'vagrant-lxc/driver/cli'
5
5
 
6
6
  describe Vagrant::LXC::Driver::CLI do
7
- let(:sudo_wrapper) { double(Vagrant::LXC::SudoWrapper, run: true) }
7
+ let(:sudo_wrapper) { double(Vagrant::LXC::SudoWrapper, run: true, wrapper_path: nil) }
8
8
 
9
9
  subject { described_class.new(sudo_wrapper) }
10
10
 
@@ -110,23 +110,42 @@ describe Vagrant::LXC::Driver::CLI do
110
110
  end
111
111
  end
112
112
 
113
- describe 'shutdown' do
113
+ describe 'stop' do
114
114
  let(:name) { 'a-running-container' }
115
115
  subject { described_class.new(sudo_wrapper, name) }
116
116
 
117
117
  before do
118
- subject.stub(system: true)
119
118
  allow(subject).to receive(:run)
120
119
  end
121
120
 
122
- it 'issues a lxc-shutdown with provided container name' do
123
- subject.shutdown
124
- expect(subject).to have_received(:run).with(:shutdown, '--name', name)
121
+ context 'lxc-attach is supported' do
122
+ before do
123
+ subject.stub(attach: true, supports_attach?: true)
124
+ subject.stop
125
+ end
126
+
127
+ it 'runs a /sbin/halt within the container' do
128
+ expect(subject).to have_received(:attach).with('/sbin/halt')
129
+ end
130
+
131
+ it 'issues a lxc-stop with provided container name' do
132
+ expect(subject).to have_received(:run).with(:stop, '--name', name)
133
+ end
125
134
  end
126
135
 
127
- it 'raises a ShutdownNotSupported in case it is not supported' do
128
- allow(subject).to receive(:system).with('which lxc-shutdown > /dev/null').and_return(false)
129
- expect { subject.shutdown }.to raise_error(described_class::ShutdownNotSupported)
136
+ context 'lxc-attach is not supported' do
137
+ before do
138
+ subject.stub(attach: false, supports_attach?: false)
139
+ subject.stop
140
+ end
141
+
142
+ it 'runs a /sbin/halt within the container' do
143
+ expect(subject).to_not have_received(:attach)
144
+ end
145
+
146
+ it 'issues a lxc-stop with provided container name' do
147
+ expect(subject).to have_received(:run).with(:stop, '--name', name)
148
+ end
130
149
  end
131
150
  end
132
151
 
@@ -183,9 +202,6 @@ describe Vagrant::LXC::Driver::CLI do
183
202
  end
184
203
 
185
204
  describe 'transition block' do
186
- let(:name) { 'a-running-container' }
187
- subject { described_class.new(name) }
188
-
189
205
  before do
190
206
  subject.stub(run: true, sleep: true, state: :stopped)
191
207
  end
@@ -204,4 +220,33 @@ describe Vagrant::LXC::Driver::CLI do
204
220
 
205
221
  skip 'waits for the expected container state'
206
222
  end
223
+
224
+ describe 'check for whether lxc-attach is supported' do
225
+ let(:name) { 'a-running-container' }
226
+ subject { described_class.new(sudo_wrapper, name) }
227
+
228
+ context 'lxc-attach is present on system' do
229
+ before { subject.stub(run: true) }
230
+
231
+ it 'returns true if `lxc-attach --name CNAME -- /bin/true` works' do
232
+ expect(subject.supports_attach?).to be_truthy
233
+ expect(subject).to have_received(:run).with(
234
+ :attach, '--name', name, '--', '/bin/true'
235
+ )
236
+ end
237
+ end
238
+
239
+ context 'lxc-attach is not present on system' do
240
+ before do
241
+ allow(subject).to receive(:run).and_raise(Vagrant::LXC::Errors::ExecuteError.new('msg'))
242
+ end
243
+
244
+ it 'returns true if `lxc-attach --name CNAME -- /bin/true` works' do
245
+ expect(subject.supports_attach?).to be_falsy
246
+ expect(subject).to have_received(:run).with(
247
+ :attach, '--name', name, '--', '/bin/true'
248
+ )
249
+ end
250
+ end
251
+ end
207
252
  end
@@ -75,6 +75,17 @@ describe Vagrant::LXC::Driver do
75
75
  end
76
76
  end
77
77
 
78
+ describe 'supports_attach?' do
79
+ let(:cli) { double(Vagrant::LXC::Driver::CLI, supports_attach?: true) }
80
+
81
+ subject { described_class.new('name', nil, cli) }
82
+
83
+ it 'delegates to cli object' do
84
+ expect(subject.supports_attach?).to be_truthy
85
+ expect(cli).to have_received(:supports_attach?)
86
+ end
87
+ end
88
+
78
89
  describe 'start' do
79
90
  let(:customizations) { [['a', '1'], ['b', '2']] }
80
91
  let(:internal_customization) { ['internal', 'customization'] }
@@ -102,7 +113,7 @@ describe Vagrant::LXC::Driver do
102
113
  end
103
114
 
104
115
  describe 'halt' do
105
- let(:cli) { double(Vagrant::LXC::Driver::CLI, shutdown: true) }
116
+ let(:cli) { double(Vagrant::LXC::Driver::CLI, stop: true) }
106
117
 
107
118
  subject { described_class.new('name', nil, cli) }
108
119
 
@@ -110,8 +121,8 @@ describe Vagrant::LXC::Driver do
110
121
  allow(cli).to receive(:transition_to).and_yield(cli)
111
122
  end
112
123
 
113
- it 'delegates to cli shutdown' do
114
- expect(cli).to receive(:shutdown)
124
+ it 'delegates to cli stop' do
125
+ expect(cli).to receive(:stop)
115
126
  subject.forced_halt
116
127
  end
117
128
 
@@ -122,14 +133,7 @@ describe Vagrant::LXC::Driver do
122
133
 
123
134
  it 'attempts to force the container to stop in case a shutdown doesnt work' do
124
135
  allow(cli).to receive(:shutdown).and_raise(Vagrant::LXC::Driver::CLI::TargetStateNotReached.new :target, :source)
125
- expect(cli).to receive(:transition_to).with(:stopped).twice
126
- expect(cli).to receive(:stop)
127
- subject.forced_halt
128
- end
129
-
130
- it 'attempts to force the container to stop in case lxc-shutdown is not supported' do
131
- allow(cli).to receive(:shutdown).and_raise(Vagrant::LXC::Driver::CLI::ShutdownNotSupported)
132
- expect(cli).to receive(:transition_to).with(:stopped).twice
136
+ expect(cli).to receive(:transition_to).with(:stopped)
133
137
  expect(cli).to receive(:stop)
134
138
  subject.forced_halt
135
139
  end
@@ -149,7 +153,8 @@ describe Vagrant::LXC::Driver do
149
153
  describe 'folder sharing' do
150
154
  let(:shared_folder) { {guestpath: '/vagrant', hostpath: '/path/to/host/dir'} }
151
155
  let(:ro_rw_folder) { {guestpath: '/vagrant/ro_rw', hostpath: '/path/to/host/dir', mount_options: ['ro', 'rw']} }
152
- let(:folders) { [shared_folder, ro_rw_folder] }
156
+ let(:with_space_folder) { {guestpath: '/tmp/with space', hostpath: '/path/with space'} }
157
+ let(:folders) { [shared_folder, ro_rw_folder, with_space_folder] }
153
158
  let(:rootfs_path) { Pathname('/path/to/rootfs') }
154
159
  let(:expected_guest_path) { "vagrant" }
155
160
  let(:sudo_wrapper) { double(Vagrant::LXC::SudoWrapper, run: true) }
@@ -178,5 +183,12 @@ describe Vagrant::LXC::Driver do
178
183
  "#{ro_rw_folder[:hostpath]} vagrant/ro_rw none ro,rw 0 0"
179
184
  ]
180
185
  end
186
+
187
+ it 'supports directories with spaces' do
188
+ expect(subject.customizations).to include [
189
+ 'mount.entry',
190
+ "/path/with\\040space tmp/with\\040space none bind 0 0"
191
+ ]
192
+ end
181
193
  end
182
194
  end
@@ -0,0 +1,110 @@
1
+ #!/opt/vagrant/embedded/bin/ruby
2
+ # Automatically created by vagrant-lxc
3
+
4
+ class Whitelist
5
+ class << self
6
+ def add(command, *args)
7
+ list[command] << args
8
+ end
9
+
10
+ def list
11
+ @list ||= Hash.new do |key, hsh|
12
+ key[hsh] = []
13
+ end
14
+ end
15
+
16
+ def allowed(command)
17
+ list[command] || []
18
+ end
19
+
20
+ def run!(argv)
21
+ begin
22
+ command, args = `which #{argv.shift}`.chomp, argv || []
23
+ check!(command, args)
24
+ puts `#{command} #{args.join(" ")}`
25
+ exit $?.to_i
26
+ rescue => e
27
+ STDERR.puts e.message
28
+ exit 1
29
+ end
30
+ end
31
+
32
+ private
33
+ def check!(command, args)
34
+ allowed(command).each do |checks|
35
+ return if valid_args?(args, checks)
36
+ end
37
+ raise_invalid(command, args)
38
+ end
39
+
40
+ def valid_args?(args, checks)
41
+ return false unless valid_length?(args, checks)
42
+ check = nil
43
+ args.each_with_index do |provided, i|
44
+ check = checks[i] unless check == '**'
45
+ return false unless match?(provided, check)
46
+ end
47
+ true
48
+ end
49
+
50
+ def valid_length?(args, checks)
51
+ args.length == checks.length || checks.last == '**'
52
+ end
53
+
54
+ def match?(arg, check)
55
+ check == '**' || check.is_a?(Regexp) && !!check.match(arg) || arg == check
56
+ end
57
+
58
+ def raise_invalid(command, args)
59
+ raise "Invalid arguments for command #{command}, " <<
60
+ "provided args: #{args.inspect}"
61
+ end
62
+ end
63
+ end
64
+
65
+ base = "/var/lib/lxc"
66
+ base_path = %r{\A#{base}/.*\z}
67
+ templates_path = %r{\A/usr/(share|lib|lib64|local/lib)/lxc/templates/.*\z}
68
+
69
+ ##
70
+ # Commands from provider.rb
71
+ # - Check lxc is installed
72
+ Whitelist.add '<%= cmd_paths['which'] %>', /\Alxc-\w+\z/
73
+
74
+ ##
75
+ # Commands from driver.rb
76
+ # - Container config file
77
+ Whitelist.add '<%= cmd_paths['cat'] %>', base_path
78
+ # - Shared folders
79
+ Whitelist.add '<%= cmd_paths['mkdir'] %>', '-p', base_path
80
+ # - Container config customizations and pruning
81
+ Whitelist.add '<%= cmd_paths['cp'] %>', '-f', %r{/tmp/.*}, base_path
82
+ Whitelist.add '<%= cmd_paths['chown'] %>', 'root:root', base_path
83
+ # - Template import
84
+ Whitelist.add '<%= cmd_paths['cp'] %>', %r{\A.*\z}, templates_path
85
+ Whitelist.add '<%= cmd_paths['chmod'] %>', '+x', templates_path
86
+ # - Template removal
87
+ Whitelist.add '<%= cmd_paths['rm'] %>', templates_path
88
+ # - Packaging
89
+ Whitelist.add '<%= cmd_paths['tar'] %>', '--numeric-owner', '-cvzf', %r{/tmp/.*/rootfs.tar.gz}, '-C', base_path, './rootfs'
90
+ Whitelist.add '<%= cmd_paths['chown'] %>', /\A\d+:\d+\z/, %r{\A/tmp/.*/rootfs\.tar\.gz\z}
91
+
92
+ ##
93
+ # Commands from driver/cli.rb
94
+ Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-version'
95
+ Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-ls'
96
+ Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-info', '--name', /.*/
97
+ Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-create', '-B', /.*/, '--template', /.*/, '--name', /.*/, '**'
98
+ Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-destroy', '--name', /.*/
99
+ Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-start', '-d', '--name', /.*/, '**'
100
+ Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-stop', '--name', /.*/
101
+ Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-shutdown', '--name', /.*/
102
+ Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-attach', '--name', /.*/, '**'
103
+ Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-attach', '-h'
104
+
105
+ ##
106
+ # Commands from driver/action/remove_temporary_files.rb
107
+ Whitelist.add '<%= cmd_paths['rm'] %>', '-rf', %r{\A#{base}/.*/rootfs/tmp/.*}
108
+
109
+ # Watch out for stones
110
+ Whitelist.run!(ARGV)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-lxc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.alpha.2
4
+ version: 1.0.0.alpha.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fabio Rehm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-13 00:00:00.000000000 Z
11
+ date: 2014-08-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Linux Containers provider for Vagrant
14
14
  email:
@@ -85,13 +85,14 @@ files:
85
85
  - spec/unit/support/unit_example_group.rb
86
86
  - spec/unit_helper.rb
87
87
  - tasks/spec.rake
88
+ - templates/sudoers.rb.erb
88
89
  - vagrant-lxc.gemspec
89
90
  - vagrant-spec.config.rb
90
91
  homepage: https://github.com/fgrehm/vagrant-lxc
91
92
  licenses:
92
93
  - MIT
93
94
  metadata: {}
94
- post_install_message: "\n Thanks for giving vagrant-lxc 1.0.0.alpha.2 a try!\n This
95
+ post_install_message: "\n Thanks for giving vagrant-lxc 1.0.0.alpha.3 a try!\n This
95
96
  version introduces many changes and includes some deprecations,\n please see the
96
97
  project's CHANGELOG:\n https://github.com/fgrehm/vagrant-lxc/blob/master/CHANGELOG.md\n
97
98
  \ "