vagrant-lxc 1.0.0.alpha.2 → 1.0.0.alpha.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +26 -31
- data/README.md +4 -4
- data/lib/vagrant-lxc/action.rb +8 -2
- data/lib/vagrant-lxc/action/fetch_ip_with_lxc_attach.rb +1 -1
- data/lib/vagrant-lxc/command/sudoers.rb +18 -119
- data/lib/vagrant-lxc/driver.rb +6 -4
- data/lib/vagrant-lxc/driver/cli.rb +19 -11
- data/lib/vagrant-lxc/sudo_wrapper.rb +2 -0
- data/lib/vagrant-lxc/version.rb +1 -1
- data/spec/unit/driver/cli_spec.rb +57 -12
- data/spec/unit/driver_spec.rb +24 -12
- data/templates/sudoers.rb.erb +110 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd50ec26aecfabf94b58e9f16ff0a996fc6d7598
|
4
|
+
data.tar.gz: ae1c22bb9caf6b7b233d0acc100437619f3b5728
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/Gemfile.lock
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
GIT
|
2
2
|
remote: https://github.com/fgrehm/vagrant-cachier.git
|
3
|
-
revision:
|
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:
|
25
|
+
revision: 0a5f6bb77e6a61b56c96057de94f5f8c6868e27c
|
26
26
|
specs:
|
27
|
-
vagrant (1.6.
|
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.
|
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.
|
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.
|
81
|
+
httpclient (2.4.0)
|
85
82
|
httpi (0.9.7)
|
86
83
|
rack
|
87
84
|
i18n (0.6.9)
|
88
|
-
listen (2.7.
|
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.
|
94
|
+
lumberjack (1.0.6)
|
99
95
|
method_source (0.8.2)
|
100
|
-
mime-types (2.
|
101
|
-
mini_portile (0.
|
102
|
-
multi_json (1.10.
|
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.
|
106
|
-
|
107
|
-
|
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.
|
110
|
+
rake (10.3.2)
|
116
111
|
rb-fsevent (0.9.4)
|
117
|
-
rb-inotify (0.9.
|
112
|
+
rb-inotify (0.9.5)
|
118
113
|
ffi (>= 0.5.0)
|
119
|
-
rb-kqueue (0.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
|
124
|
-
rspec-core (
|
125
|
-
rspec-expectations (
|
126
|
-
rspec-mocks (
|
127
|
-
rspec-core (2.99.0
|
128
|
-
rspec-expectations (2.99.0
|
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
|
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.
|
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
|
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
|
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.
|
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/
|
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
|
|
data/lib/vagrant-lxc/action.rb
CHANGED
@@ -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
|
201
|
-
|
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
|
-
|
44
|
-
#
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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 "
|
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
|
data/lib/vagrant-lxc/driver.rb
CHANGED
@@ -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")
|
data/lib/vagrant-lxc/version.rb
CHANGED
@@ -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 '
|
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
|
-
|
123
|
-
|
124
|
-
|
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
|
-
|
128
|
-
|
129
|
-
|
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
|
data/spec/unit/driver_spec.rb
CHANGED
@@ -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,
|
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
|
114
|
-
expect(cli).to receive(:
|
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)
|
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(:
|
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.
|
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-
|
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.
|
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
|
\ "
|