Compare commits

...

72 commits

Author SHA1 Message Date
a47660a1e5 Update 'README.md' 2023-02-03 19:28:15 +00:00
3575d65ffb Update 'README.md' 2023-02-03 19:08:48 +00:00
Glenn Y. Rolland
938a29ed96
Merge branch 'fgrehm:master' into master 2023-02-03 19:56:32 +01:00
Fabio
ff58ecd5f2
Update README.md 2022-11-24 20:41:12 -03:00
Fabio
df6b78c4ed
Update README.md 2022-11-24 20:40:54 -03:00
Fabio
4d53acb9fb
Update README.md 2022-11-24 20:40:34 -03:00
Fabio
b88d50fb68
Update README.md 2022-11-16 22:39:19 -03:00
4e3306ed74 Fix the 'eval: Address:: not found' error that may appear 2022-09-28 15:01:04 +02:00
Fabio Rehm
c167ac7f83
Make it clear that project is looking for maintainers
Ref https://github.com/fgrehm/vagrant-lxc/issues/492
2021-01-12 11:15:50 -03:00
Virgil Dupras
a112b072aa
Merge pull request #473 from ebobby/fix-redir3
Fix redir version fetching.
2018-09-26 19:53:14 -04:00
Francisco Soto
f750bf406c Fix redir version fetching.
"" || "something" doesn't really work. Have to check for the actual string
length to determine if got something or not out of the pipe.
2018-09-24 18:43:03 -07:00
Virgil Dupras
2a5510b34c Fix "vargant package" for LXC 2.1+ config format
New config format would be under `lxc.rootfs.path` and be prefixed by
`dir:`.
2018-07-24 12:23:25 -04:00
Virgil Dupras
a1aa60ded5 Remove supports_attach? and call to /sbin/halt
Hosts without support for lxc-attach are ancien and can always use old
versions of vagrant-lxc. To be able to move forward more easily, we
should be able to assume a functional `lxc-attach`.

As for `/sbin/halt`, I'm really not sure it's needed anymore. Let's see
if its removal causes problems.
2018-07-24 11:21:09 -04:00
Virgil Dupras
61c921ac6f Use require_relative everywhere in plugin entry point 2018-07-24 10:25:08 -04:00
Virgil Dupras
437b5e7a2e README: base boxes status update 2018-07-24 10:08:07 -04:00
Virgil Dupras
2c2630a788 Bump minimum requirements for next vagrant-lxc release (v1.5)
We now depend on vagrant 1.9+ and LXC 2.0+, following bundled version in
debian stretch.

Also, update Gemfile to target latest vagrant/vagrant-spec. It's too
complicated to test against old vagrant versions. Vagrant 1.8.x didn't
specify an upper bound for supported versions but vagrant 1.9 does
(<2.4). This breaks out CI testing matrix which tests against 2.3, 2.4
and 2.5.

So let's make our live easier and just test against the latest vagrant
version and try not to mistakenly drop support for our lowest supported
vagrant version...
2018-07-24 09:37:34 -04:00
Virgil Dupras
5a1f6ab2cb
Merge pull request #469 from worxli/feature-add-ssh-ip
Add config for container SSH IP
2018-07-23 06:27:50 -04:00
Lukas Bischofberger
f71de429a1 Add config for container ssh IP 2018-07-21 14:52:26 +02:00
Virgil Dupras
50cbe5a0d6 v1.4.2 2018-07-17 14:37:18 -04:00
Virgil Dupras
44eefd81fb Merge tag 'v1.4.1' 2018-07-17 14:34:58 -04:00
Virgil Dupras
a84f8b59bf redir: adjust failing tests 2018-07-04 15:00:46 -04:00
Virgil Dupras
c1dd7baf2a redir: start in foreground mode under v3.x
ref #467
2018-07-04 14:34:26 -04:00
Virgil Dupras
8a1e1863a7 redir: fix version parsing
At some point in v 3.x, it outputted version in stderr, then went back
to stdout...
2018-07-04 14:33:51 -04:00
Virgil Dupras
b812a6934a v1.4.1 2018-04-30 21:32:33 -04:00
Virgil Dupras
8cfe577b17 Fix LXC 3.0 compatibility with old boxes
Creating a new vagrant machine with a box created with an old LXC config
format would fail with LXC 3.0. We now update the LXC config of the box
itself before calling `lxc-create`.
2018-04-30 20:45:25 -04:00
Virgil Dupras
dd24cdc3d6 Fix incompatibility with LXC 3.0
LXC 3.0, unlike 2.1, doesn't support old configuration formats at all
and because our previous approach to handling old format was incomplete,
running `vagrant up` on a system with LXC 3.0 would fail, even if the
base box itself was made with modernized config.

This commit fixes this problem: is the box has a modern config, it's
going to be properly created and booted under LXC 3.0. It does so
without breaking the support for LXC < 2.1
2018-04-29 22:57:31 -04:00
Virgil Dupras
208edd49e5
Merge pull request #461 from nicolasleger/patch-1
[CI] Test against Ruby 2.5
2018-03-18 16:41:55 -04:00
Virgil Dupras
484b868100
Merge pull request #460 from lucaskanashiro/support_redir-3.x
Support the new redir 3.x command line interface
2018-03-18 16:41:18 -04:00
Nicolas Leger
b5f2a9006c
[CI] Test against Ruby 2.5 2018-03-15 14:52:34 +01:00
Lucas Kanashiro
2e20f96fec Support the new redir 3.x command line interface
Since redir 2.x upstream is not evolving it, Joachim Nilsson adopted it
and have started to work on it and publish a new command line interface
(check out https://github.com/troglobit/redir). The redir 3.1 is already
available in Debian and Ubuntu in their stable releases.
2018-03-12 13:09:06 -03:00
Virgil Dupras
d3409ace2a v1.4.0 2018-03-04 09:22:58 -05:00
Virgil Dupras
530a899467 Add support for unprivileged containers
fixes #312

I've also remove the "EXPERIMENTAL" flag to bridge support in the README.
It's been there long enough.
2018-02-17 21:53:16 -05:00
Virgil Dupras
9e215ae1a1 v1.3.1 2018-02-06 22:02:29 -05:00
Cam Cope
8fa42b1ab4
Merge pull request #456 from fgrehm/tmpfs-revival
Revert tmpfs mount removal
2018-02-04 00:04:39 -08:00
Virgil Dupras
2ae84fcc51 Revert tmpfs mount removal
To fix #406, I reverted the tmpfs mount we add at boot time. As we can
see in #455, it was a bad idea.

In addition to bringing back that mount, I've also added a
`tmpfs_mount_size` config that allows to change the size of the mount
from its default `2G`. It's also possible to disable the mount
altogether.

fixes #455
2018-02-02 16:02:17 -05:00
Virgil Dupras
582e3b368a halt: check that machine is running before attempting to clear tmpfiles
Otherwise, running `vagrant halt` on a stopped machine would make us
crash. Particularly annoying in multi-machines environments.

ref #406
2018-01-27 14:32:42 -05:00
Virgil Dupras
6738febaa2 v1.3.0 2018-01-20 13:29:46 -05:00
Virgil Dupras
49ebf3488e sudoers: fix typo
fixes #451
2018-01-15 21:17:36 -05:00
Virgil Dupras
bd42317ec2 Update README
Fixes #431
2018-01-15 08:25:27 -05:00
Virgil Dupras
1c27047f4b Remove tmpfs mount on /tmp and bring back /tmp cleanup on halt
fixes #406 because the `tmpfs` mount isn't needed anymore.

Careful considerations had to be taken because #68 mentions host-side
data loss when cleaning up `/tmp`. We mitigate this by ensuring that all
mounts under `/tmp` are unmounted before we proceed with our `rm -rf`
operation.

More context about this issue can be found in #360.
2018-01-13 23:00:46 -05:00
Virgil Dupras
fef11bf7ef Update README 2018-01-13 21:06:45 -05:00
Virgil Dupras
c74ddbf2fc create: with LXC 2.1+ run lxc-update-config on new boxes
When running with LXC 2.1+, ensure that our boxes have up-to-date config
keys by running the `lxc-update-config` utility that ships with LXC
2.1+.

When the command doesn't exist (LXC <2.1), we do nothing.

ref #445
2018-01-13 21:03:34 -05:00
Virgil Dupras
2b08ae199f driver: little cleanup after LXC 1.0+ requirement bump
The conditional `lxc-version` and `lxc-config` mechanisms aren't needed
anymore. They were for pre-1.0 LXC versions.
2018-01-13 20:34:41 -05:00
Virgil Dupras
aa777653f4 Use lxc-info instead of lxc-attach to retrieve container IP
`lxc-info -iH` to retrieve IP address was not available in early LXC
development but was there at LXC 1.0. Because we've bumped our minimum
LXC requirement to v1.0 recently, we can simplify the IP retrieval
process and also get rid of the `dnsmasq` fallback.
2018-01-13 15:53:28 -05:00
Virgil Dupras
7e1eb1d373 Change version to 1.3.0-dev 2018-01-13 15:30:39 -05:00
Virgil Dupras
4ff412e2d2 Fix travis for real this time
Sorry for the commit noise, I didn't think I'd need this much fiddling
and I don't have push-force privileges on the repo.
2018-01-13 09:06:45 -05:00
Virgil Dupras
bd4aa8167c Fix travis (again) 2018-01-13 08:56:17 -05:00
Virgil Dupras
2423464cdb Fix travis (again) 2018-01-13 08:54:06 -05:00
Virgil Dupras
0b5087f72e Fix travis builds 2018-01-13 08:43:00 -05:00
Virgil Dupras
c8801ba8b2
Merge pull request #447 from hsoft/unprivileged-template
lxc-template: make runnable by unprivileged users
2018-01-13 08:35:43 -05:00
Virgil Dupras
97b5882262 Refactoring: make SudoWrapper a bit more self-contained
By looking at the code, it seems that it was a goal to make the sudo
wrapper path configurable through the Vagrantfile, but it wasn't
effective and didn't make much sense (that kind of config is a per-host
config, not a per-guest one).

This caused the cause to be needlessly complex by giving the Provider
the responsibility of instanciating the wrapper. This commit gets rid of
that.

I didn't get rid of `sudo_wrapper` injection in `Driver` and
`Driver::CLI` constructors because they're needed for tests. I'm not
ready to tackle this yet.
2018-01-13 08:32:27 -05:00
Virgil Dupras
6eb7ec1a2e Bump Vagrant and LXC requirements 2018-01-13 08:32:27 -05:00
Virgil Dupras
fe7d638b35 Remove Gemfile.lock and properly lock stuff in Gemfile
No other vagrant plugin use `Gemfile.lock`. It doesn't feel right.

When removing it, however, we end up with many dependencies conflicts.
It then becomes necessary to freeze dependencies in `Gemfile`.
2018-01-13 08:32:27 -05:00
Virgil Dupras
f8a78e520b Adjust changelog for v1.2.4 2017-12-20 15:45:31 -05:00
Virgil Dupras
dbf2dfb8ff
Merge pull request #448 from hsoft/master
v1.2.4
2017-12-20 10:33:49 -05:00
Virgil Dupras
d3788f55f3
Merge pull request #449 from nicobrevin/nicobrevin-master
Fix for #336
2017-12-16 19:15:16 -05:00
Nick Griffiths
f224fc5ea5 Fix for #336:
Subprocessed being interrupted resulted in it looking
like those commands were executing successfully but with
zero output.  Interrupting the sudo prompt would result
in any command running in sudo returning nothing and looking
like it had succeeded.  There was some clean up code in
the lxc provider that nuked vagrant container state in
the .vagrant directory if it looked like the container no
longer existed based on the result of lxc-ls.  Interrupting
this check resulted in it looking like the container not
existing, resulting in the provider code nuking the lxc dir
in .vagrant.  Voila
2017-12-16 12:07:11 +13:00
Virgil Dupras
1c64ea1b2c v1.2.4 2017-12-12 11:02:57 -05:00
Fabio Rehm
b96ba86f72
Update CHANGELOG.md 2017-12-12 13:55:25 -02:00
Virgil Dupras
8b93206c18
Merge pull request #435 from brandon-rhodes/fix-umask
Avoid `Timed out` error when umask is 027 or 077
2017-12-11 19:35:22 -05:00
Virgil Dupras
e4c566ebc9
Merge pull request #421 from TobleMiner/lxc-template-option-fix
Fixes #420 (blaze it)
2017-12-11 17:21:00 -05:00
Virgil Dupras
d35ee4aed0
Merge pull request #410 from ChaosCloud/abk
vagrant-lxc-wrapper need to allow sudoer first-found binary path
2017-12-11 17:07:21 -05:00
Virgil Dupras
03c23d7df8 README: mention incompatibility with LXC v2.1
see #445
2017-12-11 14:51:09 -05:00
Virgil Dupras
10c53c54d7 Support alternative lxcpath in sudo wrapper
The previously hardcoded lxc path prevented the sudo wrapper from
working in environment with alternative `lxcpath`.

I had to move `sudo_wrapper` from `provider` to `LXC` because the
concept of "provider" is tied to a machine when a command sush as
`sudoers` is not.

Fixes #413 and #399
2017-12-11 11:48:19 -05:00
Virgil Dupras
2ce460bc30
Merge pull request #438 from fkleon/fix-sudoers-vagrant-1.9.x
Update pipework regexp for sudo wrapper
2017-12-11 10:20:36 -05:00
Virgil Dupras
553f1b5ed0 lxc-template: make runnable by unprivileged users
lxc-template needlessly require root privileges in two places:

1. lock file location for `flock`
2. failing on `tar` failure during rootfs extraction

For `flock`, it's not necessary that the lock file be in `/var/lock`, it
can be anywhere. Why not put it in `LXC_PATH`?

For the failing `tar` thing, that's because some device are created with
`mknod` which unprivileged users can't do. These device, however, are
not necessary for the container to run well. We can ignore `tar`'s error
exit code.

I replaced the exist code check by a check for the existence of
`/bin/true` in rootfs. I think that it's a good indication of whether
the rootfs was extracted.

Why am I making this change? Because I'd like to add support for
unprivileged containers in `vagrant-lxc` but it's kind of a big change
to make at once, so I thought I'd go incrementally.
2017-12-09 19:36:54 -05:00
Frederik Leonhardt
1f805f6deb Update pipework regexp for sudo wrapper
On Vagrant 1.9+ plugin gems are installed into a different folder, their path
containing the ruby version. This updates the regular expression whitelisting
the pipework script to reflect this change.
2017-02-09 15:55:32 +13:00
Brandon Rhodes
43aa9bfb3e Avoid Timed out error when umask is 027 or 077
If LXC commands are run with a restrictive umask like 027 or 077, then
the root directory of new containers will lack read `r` and access `x`
permission for non-root users.  The first failure to result from this
during `vagrant up` is that the SSH daemon cannot read the crucial file
`/home/vagrant/.ssh/authorized_keys` after it drops privileges to the
level of the `vagrant` user.  The result is the familiar:

```
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
Timed out while waiting for the machine to boot. This means that
Vagrant was unable to communicate with the guest machine within
the configured ("config.vm.boot_timeout" value) time period.
```

So we should make sure that we run all LXC commands with a umask that at
least does not prevent group and world `r` and `x` bits from being set
in newly created files and directories.
2017-01-29 13:53:09 -05:00
Cam Cope
851f58d42a v1.2.3 2016-12-20 20:20:38 -08:00
Cam Cope
fdb7222965 Fix bad version in Gemfile.lock 2016-12-20 20:20:07 -08:00
Tobias Schramm
0cdd4d352c Fixes #420 (blaze it) 2016-08-22 22:27:00 +02:00
AbhishekKr
848383e081 vagrant-lxc-wrapper need to allow sudoer first-found binary path
sudoer PATH may have different order than current user
2016-05-11 23:51:29 +05:30
31 changed files with 357 additions and 534 deletions

1
.gitignore vendored
View file

@ -19,6 +19,7 @@ doc/
/tags /tags
/gems.tags /gems.tags
/Gemfile.lock
.vagrant .vagrant
/cache /cache

View file

@ -1,8 +1,10 @@
language: ruby language: ruby
rvm: rvm:
- 2.0.0 - 2.2
- 2.1.1 - 2.3
matrix: - 2.4
allow_failures: - 2.5
- rvm: 2.1.1 install:
- gem install -v 1.12.5 bundler
- bundle _1.12.5_ install --jobs=3 --retry=3
script: "bundle exec rake ci" script: "bundle exec rake ci"

View file

@ -1,15 +1,88 @@
## [1.4.2](https://github.com/fgrehm/vagrant-lxc/compare/v1.4.1...v1.4.2) (Jul 17, 2018)
FIXES:
- Fix problems with `redir` 3.x command line. [[GH-467]]
## [1.4.1](https://github.com/fgrehm/vagrant-lxc/compare/v1.4.0...v1.4.1) (Apr 30, 2018)
FEATURES:
- Add support for LXC v3.0
- Add support for `redir` 3.x command line. [[GH-460]]
[GH-460]: https://github.com/fgrehm/vagrant-lxc/issues/460
## [1.4.0](https://github.com/fgrehm/vagrant-lxc/compare/v1.3.1...v1.4.0) (Mar 04, 2018)
FEATURES:
- Add support for unprivileged containers. [[GH-312]]
[GH-312]: https://github.com/fgrehm/vagrant-lxc/issues/312
## [1.3.1](https://github.com/fgrehm/vagrant-lxc/compare/v1.3.0...v1.3.1) (Fev 06, 2018)
FIXES:
- Fix problems with `tmpfs` fiddling in v1.3.0. [[GH-455]]
[GH-455]: https://github.com/fgrehm/vagrant-lxc/pull/455
## [1.3.0](https://github.com/fgrehm/vagrant-lxc/compare/v1.2.4...v1.3.0) (Jan 20, 2018)
FEATURES:
- lxc-template: make runnable by unprivileged users [[GH-447]]
- Use `lxc-info` instead of `lxc-attach` to retrieve container IP
- Add support for LXC v2.1+ [[GH-445]]
- Remove 2Gb limitation on `/tmp`. [[GH-406]]
OTHERS:
- Bump Vagrant requirements to v1.8+
- Bump LXC requirements to v1.0+
[GH-447]: https://github.com/fgrehm/vagrant-lxc/pull/447
[GH-445]: https://github.com/fgrehm/vagrant-lxc/pull/445
[GH-406]: https://github.com/fgrehm/vagrant-lxc/pull/406
## [1.2.4](https://github.com/fgrehm/vagrant-lxc/compare/v1.2.3...v1.2.4) (Dec 20, 2017)
BUGFIX:
- Support alternative `lxcpath` [[GH-413]]
- Update `pipework` regexp in sudo wrapper for Vagrant 1.9+ [[GH-438]]
- Work around restrictive `umask` values [[GH-435]]
- Make `--config` in `lxc-template` optional [[GH-421]]
- Fix sudo wrapper binpath construction logic [[GH-410]]
- Fix bug causing CTRL-C on `vagrant up` to destroy the VM [[GH-449]]
[GH-413]: https://github.com/fgrehm/vagrant-lxc/pull/413
[GH-438]: https://github.com/fgrehm/vagrant-lxc/pull/438
[GH-435]: https://github.com/fgrehm/vagrant-lxc/pull/435
[GH-421]: https://github.com/fgrehm/vagrant-lxc/pull/421
[GH-410]: https://github.com/fgrehm/vagrant-lxc/pull/410
[GH-449]: https://github.com/fgrehm/vagrant-lxc/pull/449
## [1.2.3](https://github.com/fgrehm/vagrant-lxc/compare/v1.2.2...v1.2.3) (Dec 20, 2016)
- Fix bug in Gemfile.lock
## [1.2.2](https://github.com/fgrehm/vagrant-lxc/compare/v1.2.1...v1.2.2) (Dec 20, 2016) ## [1.2.2](https://github.com/fgrehm/vagrant-lxc/compare/v1.2.1...v1.2.2) (Dec 20, 2016)
BUGFIX:
- Make the timeout for fetching container IP's configurable [[GH-426]] - Make the timeout for fetching container IP's configurable [[GH-426]]
- Load locale file only once [[GH-423]] - Load locale file only once [[GH-423]]
- Preserve xattrs in container filesystems [[GH-411]] - Preserve xattrs in container filesystems [[GH-411]]
- Forward port latest pipework script [[GH-408]] - Forward port latest pipework script [[GH-408]]
- Fix handling of non-fatal lxc-stop return code [[GH-405]] - Fix handling of non-fatal lxc-stop return code [[GH-405]]
[GH-426]: https://github.com/fgrehm/vagrant-lxc/pull/426
[GH-423]: https://github.com/fgrehm/vagrant-lxc/pull/423
[GH-411]: https://github.com/fgrehm/vagrant-lxc/pull/411
[GH-408]: https://github.com/fgrehm/vagrant-lxc/pull/408
[GH-405]: https://github.com/fgrehm/vagrant-lxc/pull/405
## [1.2.1](https://github.com/fgrehm/vagrant-lxc/compare/v1.2.0...v1.2.1) (Sep 24, 2015) ## [1.2.1](https://github.com/fgrehm/vagrant-lxc/compare/v1.2.0...v1.2.1) (Sep 24, 2015)
BUGFIX: BUGFIX:
- Fix sudo Wrapper [[GH-393]] - Fix sudo Wrapper [[GH-393]]
[GH-393]: https://github.com/fgrehm/vagrant-lxc/pull/393 [GH-393]: https://github.com/fgrehm/vagrant-lxc/pull/393
## [1.2.0](https://github.com/fgrehm/vagrant-lxc/compare/v1.1.0...v1.2.0) (Sep 15, 2015) ## [1.2.0](https://github.com/fgrehm/vagrant-lxc/compare/v1.1.0...v1.2.0) (Sep 15, 2015)
@ -27,6 +100,7 @@ IMPROVEMENTS:
- Fix shebangs to be more portable [[GH-376]] - Fix shebangs to be more portable [[GH-376]]
- Fix removal of lxcbr0/virbr0 when using private networking [[GH-383]] - Fix removal of lxcbr0/virbr0 when using private networking [[GH-383]]
- Improve /tmp handling by using tmpfs [[GH-362]] - Improve /tmp handling by using tmpfs [[GH-362]]
[GH-301]: https://github.com/fgrehm/vagrant-lxc/issues/301 [GH-301]: https://github.com/fgrehm/vagrant-lxc/issues/301
[GH-355]: https://github.com/fgrehm/vagrant-lxc/pull/355 [GH-355]: https://github.com/fgrehm/vagrant-lxc/pull/355
[GH-357]: https://github.com/fgrehm/vagrant-lxc/pull/357 [GH-357]: https://github.com/fgrehm/vagrant-lxc/pull/357

View file

@ -1,16 +1,16 @@
source 'https://rubygems.org' source 'https://rubygems.org'
group :development do group :development do
gem 'vagrant', git: 'https://github.com/mitchellh/vagrant.git', tag: 'v1.7.4' gem 'vagrant', git: 'https://github.com/mitchellh/vagrant.git'
gem 'guard' gem 'guard'
gem 'guard-rspec' gem 'guard-rspec'
gem 'rb-inotify' gem 'rb-inotify'
end end
group :development, :test do group :development, :test do
gem 'rake' gem 'rake', '~> 10.4.2'
gem 'rspec', '2.99.0' gem 'rspec', '~> 3.5.0'
gem 'coveralls', require: (ENV['COVERAGE'] == 'true') gem 'coveralls', '~> 0.7.2', require: (ENV['COVERAGE'] == 'true')
gem 'vagrant-spec', git: 'https://github.com/mitchellh/vagrant-spec.git' gem 'vagrant-spec', git: 'https://github.com/mitchellh/vagrant-spec.git'
end end

View file

@ -1,182 +0,0 @@
GIT
remote: https://github.com/fgrehm/vagrant-cachier.git
revision: 40dddfb368526948e769492a00a7937c5a044a4d
specs:
vagrant-cachier (1.2.2)
GIT
remote: https://github.com/fgrehm/vagrant-pristine.git
revision: 6d044265db17451c606f000bf43437e95a742bb4
specs:
vagrant-pristine (0.3.0)
GIT
remote: https://github.com/mitchellh/vagrant-spec.git
revision: 1df5a3af81cb7cce568b2eac52b8f6822bcb1d8e
specs:
vagrant-spec (0.0.1)
childprocess (~> 0.5.0)
log4r (~> 1.1.9)
rspec (~> 2.14)
thor (~> 0.18.1)
GIT
remote: https://github.com/mitchellh/vagrant.git
revision: 78ea5e4a78ce644717ab16d8001ab77430168f0f
tag: v1.7.4
specs:
vagrant (1.7.4)
bundler (>= 1.5.2, <= 1.10.5)
childprocess (~> 0.5.0)
erubis (~> 2.7.0)
hashicorp-checkpoint (~> 0.1.1)
i18n (>= 0.6.0, <= 0.8.0)
listen (~> 3.0.2)
log4r (~> 1.1.9, < 1.1.11)
net-scp (~> 1.1.0)
net-sftp (~> 2.1)
net-ssh (>= 2.6.6, < 2.10.0)
nokogiri (= 1.6.3.1)
rb-kqueue (~> 0.2.0)
rest-client (>= 1.6.0, < 2.0)
wdm (~> 0.1.0)
winrm (~> 1.3)
winrm-fs (~> 0.2.0)
PATH
remote: .
specs:
vagrant-lxc (1.2.1)
GEM
remote: https://rubygems.org/
specs:
builder (3.2.2)
childprocess (0.5.6)
ffi (~> 1.0, >= 1.0.11)
coderay (1.1.0)
coveralls (0.7.2)
multi_json (~> 1.3)
rest-client (= 1.6.7)
simplecov (>= 0.7)
term-ansicolor (= 1.2.2)
thor (= 0.18.1)
diff-lcs (1.2.5)
docile (1.1.5)
erubis (2.7.0)
ffi (1.9.10)
formatador (0.2.5)
gssapi (1.2.0)
ffi (>= 1.0.1)
guard (2.12.8)
formatador (>= 0.2.4)
listen (>= 2.7, <= 4.0)
lumberjack (~> 1.0)
nenv (~> 0.1)
notiffany (~> 0.0)
pry (>= 0.9.12)
shellany (~> 0.0)
thor (>= 0.18.1)
guard-compat (1.2.1)
guard-rspec (4.6.2)
guard (~> 2.1)
guard-compat (~> 1.1)
rspec (>= 2.99.0, < 4.0)
gyoku (1.3.1)
builder (>= 2.1.2)
hashicorp-checkpoint (0.1.4)
httpclient (2.6.0.1)
i18n (0.7.0)
json (1.8.3)
listen (3.0.2)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
little-plugger (1.1.3)
log4r (1.1.10)
logging (1.8.2)
little-plugger (>= 1.1.3)
multi_json (>= 1.8.4)
lumberjack (1.0.9)
method_source (0.8.2)
mime-types (2.6.1)
mini_portile (0.6.0)
multi_json (1.11.2)
nenv (0.2.0)
net-scp (1.1.2)
net-ssh (>= 2.6.5)
net-sftp (2.1.2)
net-ssh (>= 2.6.5)
net-ssh (2.9.2)
nokogiri (1.6.3.1)
mini_portile (= 0.6.0)
nori (2.6.0)
notiffany (0.0.6)
nenv (~> 0.1)
shellany (~> 0.0)
pry (0.10.1)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
rake (10.4.2)
rb-fsevent (0.9.5)
rb-inotify (0.9.5)
ffi (>= 0.5.0)
rb-kqueue (0.2.4)
ffi (>= 0.5.0)
rest-client (1.6.7)
mime-types (>= 1.16)
rspec (2.99.0)
rspec-core (~> 2.99.0)
rspec-expectations (~> 2.99.0)
rspec-mocks (~> 2.99.0)
rspec-core (2.99.2)
rspec-expectations (2.99.2)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.99.4)
rubyntlm (0.4.0)
rubyzip (1.1.7)
shellany (0.0.1)
simplecov (0.10.0)
docile (~> 1.1.0)
json (~> 1.8)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
slop (3.6.0)
term-ansicolor (1.2.2)
tins (~> 0.8)
thor (0.18.1)
tins (0.13.2)
uuidtools (2.1.5)
vagrant-omnibus (1.4.1)
wdm (0.1.1)
winrm (1.3.3)
builder (>= 2.1.2)
gssapi (~> 1.2)
gyoku (~> 1.0)
httpclient (~> 2.2, >= 2.2.0.2)
logging (~> 1.6, >= 1.6.1)
nori (~> 2.0)
rubyntlm (~> 0.4.0)
uuidtools (~> 2.1.2)
winrm-fs (0.2.0)
erubis (~> 2.7)
logging (~> 1.6, >= 1.6.1)
rubyzip (~> 1.1)
winrm (~> 1.3.0)
PLATFORMS
ruby
DEPENDENCIES
coveralls
guard
guard-rspec
rake
rb-inotify
rspec (= 2.99.0)
vagrant!
vagrant-cachier!
vagrant-lxc!
vagrant-omnibus
vagrant-pristine!
vagrant-spec!

View file

@ -1,8 +1,12 @@
🟢 We plan to support and maintain vagrant-lxc, as well as clean it up.<br/>
🟢 Please feel free to contribute Issues and pull requests.<br/>
🟢 P.S: Thanks [Fabio Rehm](https://fabiorehm.com) for the amazing initial project.
# vagrant-lxc # vagrant-lxc
[![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) [![Gitter chat](https://badges.gitter.im/fgrehm/vagrant-lxc.png)](https://gitter.im/fgrehm/vagrant-lxc) [![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) [![Gitter chat](https://badges.gitter.im/fgrehm/vagrant-lxc.png)](https://gitter.im/fgrehm/vagrant-lxc)
[LXC](http://lxc.sourceforge.net/) provider for [Vagrant](http://www.vagrantup.com/) 1.6+ [LXC](http://lxc.sourceforge.net/) provider for [Vagrant](http://www.vagrantup.com/) 1.9+
This is a Vagrant plugin that allows it to control and provision Linux Containers This is a Vagrant plugin that allows it to control and provision Linux Containers
as an alternative to the built in VirtualBox provider for Linux hosts. Check out as an alternative to the built in VirtualBox provider for Linux hosts. Check out
@ -12,22 +16,19 @@ to see it in action.
## Features ## Features
* Provides the same workflow as the Vagrant VirtualBox provider * Provides the same workflow as the Vagrant VirtualBox provider
* Port forwarding via [`redir`](http://linux.die.net/man/1/redir) * Port forwarding via [`redir`](https://github.com/troglobit/redir)
* Private networking via [`pipework`](https://github.com/jpetazzo/pipework) * Private networking via [`pipework`](https://github.com/jpetazzo/pipework)
## Requirements ## Requirements
* [Vagrant 1.5+](http://www.vagrantup.com/downloads.html) (tested with 1.7.2) * [Vagrant 1.9+](http://www.vagrantup.com/downloads.html)
* lxc 0.7.5+ * lxc >=2.1
* tar 1.27 (the lxc-template script uses the --xattrs option)
* `redir` (if you are planning to use port forwarding) * `redir` (if you are planning to use port forwarding)
* `brctl` (if you are planning to use private networks, on Ubuntu this means `apt-get install bridge-utils`) * `brctl` (if you are planning to use private networks, on Ubuntu this means `apt-get install bridge-utils`)
* A [kernel != 3.5.0-17.28](https://github.com/fgrehm/vagrant-lxc/wiki/Troubleshooting#wiki-im-unable-to-restart-containers)
The plugin is known to work better and pretty much out of the box on Ubuntu 14.04+ The plugin is known to work better and pretty much out of the box on Ubuntu 14.04+
hosts and installing the dependencies on it basically means a `apt-get install lxc lxc-templates cgroup-lite redir` hosts and installing the dependencies on it basically means a
(older LXC versions like 0.7.5 shipped with Ubuntu 12.04 by default might require `apt-get install lxc lxc-templates cgroup-lite redir`. For setting up other
[additional configurations to work](#backingstore-options)). For setting up other
types of hosts please have a look at the [Wiki](https://github.com/fgrehm/vagrant-lxc/wiki). types of hosts please have a look at the [Wiki](https://github.com/fgrehm/vagrant-lxc/wiki).
If you are on a Mac or Windows machine, you might want to have a look at [this](http://the.taoofmac.com/space/HOWTO/Vagrant) If you are on a Mac or Windows machine, you might want to have a look at [this](http://the.taoofmac.com/space/HOWTO/Vagrant)
@ -54,8 +55,9 @@ _More information about skipping the `--provider` argument can be found at the
## Base boxes ## Base boxes
Base boxes can be found on [Atlas](https://atlas.hashicorp.com/boxes/search?provider=lxc) Base boxes provided on Atlas haven't been refreshed for a good while and shouldn't be relied on.
and some scripts to build your own are available at [fgrehm/vagrant-lxc-base-boxes](https://github.com/fgrehm/vagrant-lxc-base-boxes). Your best best is to build your boxes yourself. Some scripts to build your own are available at
[hsoft/vagrant-lxc-base-boxes](https://github.com/hsoft/vagrant-lxc-base-boxes).
If you want to build your own boxes, please have a look at [`BOXES.md`](https://github.com/fgrehm/vagrant-lxc/tree/master/BOXES.md) If you want to build your own boxes, please have a look at [`BOXES.md`](https://github.com/fgrehm/vagrant-lxc/tree/master/BOXES.md)
for more information. for more information.
@ -81,7 +83,7 @@ prior to starting it.
For other configuration options, please check the [lxc.conf manpages](http://manpages.ubuntu.com/manpages/precise/man5/lxc.conf.5.html). For other configuration options, please check the [lxc.conf manpages](http://manpages.ubuntu.com/manpages/precise/man5/lxc.conf.5.html).
### Private Networks [EXPERIMENTAL] ### Private Networks
Starting with vagrant-lxc 1.1.0, there is some rudimentary support for configuring Starting with vagrant-lxc 1.1.0, there is some rudimentary support for configuring
[Private Networks](https://docs.vagrantup.com/v2/networking/private_network.html) [Private Networks](https://docs.vagrantup.com/v2/networking/private_network.html)
@ -140,31 +142,33 @@ Vagrant.configure("2") do |config|
end end
``` ```
For old versions of lxc (like 0.7.5 shipped with Ubuntu 12.04 by default) that ## Unprivileged containers support
does not support `best` for the backingstore option, changing it to `none` is
required and a default for all Vagrant environments can be set from your Since v1.4.0, `vagrant-lxc` gained support for unprivileged containers. For now, since it's a new
`~/.vagrant.d/Vagrantfile` using the same `provider` block: feature, privileged containers are still the default, but you can have your `Vagrantfile` use
unprivileged containers with the `privileged` flag (which defaults to `true`). Example:
```ruby ```ruby
Vagrant.configure("2") do |config| Vagrant.configure("2") do |config|
config.vm.provider :lxc do |lxc| config.vm.provider :lxc do |lxc|
lxc.backingstore = 'none' lxc.privileged = false
end end
end end
``` ```
For unprivileged containers to work with `vagrant-lxc`, you need a properly configured system. On
some distros, it can be somewhat of a challenge. Your journey to configuring your system can start
with [Stéphane Graber's blog post about it](https://stgraber.org/2014/01/17/lxc-1-0-unprivileged-containers/).
## Avoiding `sudo` passwords ## Avoiding `sudo` passwords
This plugin requires **a lot** of `sudo`ing since [user namespaces](https://wiki.ubuntu.com/UserNamespace) If you're not using unprivileged containers, this plugin requires **a lot** of `sudo`ing To work
is not supported yet. To work around that, you can use the `vagrant lxc sudoers` around that, you can use the `vagrant lxc sudoers` command which will create a file under
command which will create a file under `/etc/sudoers.d/vagrant-lxc` whitelisting `/etc/sudoers.d/vagrant-lxc` whitelisting all commands required by `vagrant-lxc` to run.
all commands required by `vagrant-lxc` to run.
If you are interested on what will be generated by that command, please check If you are interested on what will be generated by that command, please check
[this code](lib/vagrant-lxc/command/sudoers.rb). [this code](lib/vagrant-lxc/command/sudoers.rb).
_vagrant-lxc < 1.0.0 users, please check this [Wiki page](https://github.com/fgrehm/vagrant-lxc/wiki/Avoiding-%27sudo%27-passwords)_
## More information ## More information

View file

@ -6,9 +6,5 @@ module Vagrant
def self.source_root def self.source_root
@source_root ||= Pathname.new(File.dirname(__FILE__)).join('..').expand_path @source_root ||= Pathname.new(File.dirname(__FILE__)).join('..').expand_path
end end
def self.sudo_wrapper_path
"/usr/local/bin/vagrant-lxc-wrapper"
end
end end
end end

View file

@ -4,8 +4,7 @@ require 'vagrant-lxc/action/create'
require 'vagrant-lxc/action/destroy' require 'vagrant-lxc/action/destroy'
require 'vagrant-lxc/action/destroy_confirm' require 'vagrant-lxc/action/destroy_confirm'
require 'vagrant-lxc/action/compress_rootfs' require 'vagrant-lxc/action/compress_rootfs'
require 'vagrant-lxc/action/fetch_ip_with_lxc_attach' require 'vagrant-lxc/action/fetch_ip_with_lxc_info'
require 'vagrant-lxc/action/fetch_ip_from_dnsmasq_leases'
require 'vagrant-lxc/action/forced_halt' require 'vagrant-lxc/action/forced_halt'
require 'vagrant-lxc/action/forward_ports' require 'vagrant-lxc/action/forward_ports'
require 'vagrant-lxc/action/gc_private_network_bridges' require 'vagrant-lxc/action/gc_private_network_bridges'
@ -182,8 +181,7 @@ module Vagrant
def self.action_ssh_ip def self.action_ssh_ip
Builder.new.tap do |b| Builder.new.tap do |b|
b.use Builtin::Call, Builtin::ConfigValidate do |env, b2| b.use Builtin::Call, Builtin::ConfigValidate do |env, b2|
b2.use FetchIpWithLxcAttach if env[:machine].provider.driver.supports_attach? b2.use FetchIpWithLxcInfo
b2.use FetchIpFromDnsmasqLeases
end end
end end
end end

View file

@ -8,11 +8,15 @@ module Vagrant
def call(env) def call(env)
@env = env @env = env
driver = env[:machine].provider.driver
config = env[:machine].provider_config config = env[:machine].provider_config
utsname = env[:machine].config.vm.hostname || env[:machine].id utsname = env[:machine].config.vm.hostname || env[:machine].id
config.customize 'utsname', utsname if driver.supports_new_config_format
config.customize 'uts.name', utsname
else
config.customize 'utsname', utsname
end
# Fix apparmor issues when starting Ubuntu 14.04 containers # Fix apparmor issues when starting Ubuntu 14.04 containers
# See https://github.com/fgrehm/vagrant-lxc/issues/278 for more information # See https://github.com/fgrehm/vagrant-lxc/issues/278 for more information
@ -26,11 +30,13 @@ module Vagrant
config.customize 'mount.entry', '/sys/fs/selinux sys/fs/selinux none bind,ro 0 0' config.customize 'mount.entry', '/sys/fs/selinux sys/fs/selinux none bind,ro 0 0'
end end
# Make /tmp a tmpfs to prevent init scripts from nuking synced folders mounted in here if config.tmpfs_mount_size && !config.tmpfs_mount_size.empty?
config.customize 'mount.entry', 'tmpfs tmp tmpfs nodev,nosuid,size=2G 0 0' # Make /tmp a tmpfs to prevent init scripts from nuking synced folders mounted in here
config.customize 'mount.entry', "tmpfs tmp tmpfs nodev,nosuid,size=#{config.tmpfs_mount_size} 0 0"
end
env[:ui].info I18n.t("vagrant_lxc.messages.starting") env[:ui].info I18n.t("vagrant_lxc.messages.starting")
env[:machine].provider.driver.start(config.customizations) driver.start(config.customizations)
@app.call env @app.call env
end end

View file

@ -19,14 +19,28 @@ module Vagrant
container_name = generate_container_name(env) container_name = generate_container_name(env)
end end
env[:machine].provider.driver.create( backingstore = config.backingstore
if backingstore.nil?
backingstore = config.privileged ? "best" : "dir"
end
driver = env[:machine].provider.driver
template_options = env[:lxc_template_opts]
if driver.supports_new_config_format
if env[:lxc_box_config]
driver.update_config_keys(env[:lxc_box_config])
end
else
template_options['--oldconfig'] = ''
end
driver.create(
container_name, container_name,
config.backingstore, backingstore,
config.backingstore_options, config.backingstore_options,
env[:lxc_template_src], env[:lxc_template_src],
env[:lxc_template_config], env[:lxc_template_config],
env[:lxc_template_opts] template_options
) )
driver.update_config_keys
env[:machine].id = container_name env[:machine].id = container_name

View file

@ -1,49 +0,0 @@
module Vagrant
module LXC
module Action
class FetchIpFromDnsmasqLeases
def initialize(app, env)
@app = app
@logger = Log4r::Logger.new("vagrant::lxc::action::fetch_ip_from_dnsmasq_leases")
end
def call(env)
env[:machine_ip] ||= assigned_ip(env)
@app.call(env)
end
def assigned_ip(env)
mac_address = env[:machine].provider.driver.mac_address
ip = nil
10.times do
dnsmasq_leases = read_dnsmasq_leases
@logger.debug "Attempting to load ip from dnsmasq leases (mac: #{mac_address})"
@logger.debug dnsmasq_leases
if dnsmasq_leases =~ /#{Regexp.escape mac_address.to_s}\s+([0-9.]+)\s+/i
ip = $1.to_s
break
else
@logger.debug 'Ip could not be parsed from dnsmasq leases file'
sleep 2
end
end
ip
end
LEASES_PATHS = %w(
/var/lib/misc/dnsmasq.*.leases
/var/lib/misc/dnsmasq.leases
/var/lib/dnsmasq/dnsmasq.leases
/var/db/dnsmasq.leases
/var/lib/libvirt/dnsmasq/*.leases
)
def read_dnsmasq_leases
Dir["{#{LEASES_PATHS.join(',')}}"].map do |file|
File.read(file)
end.join("\n")
end
end
end
end
end

View file

@ -1,19 +1,17 @@
module Vagrant module Vagrant
module LXC module LXC
module Action module Action
class FetchIpWithLxcAttach class FetchIpWithLxcInfo
# Include this so we can use `Subprocess` more easily. # Include this so we can use `Subprocess` more easily.
include Vagrant::Util::Retryable include Vagrant::Util::Retryable
def initialize(app, env) def initialize(app, env)
@app = app @app = app
@logger = Log4r::Logger.new("vagrant::lxc::action::fetch_ip_with_lxc_attach") @logger = Log4r::Logger.new("vagrant::lxc::action::fetch_ip_with_lxc_info")
end end
def call(env) def call(env)
env[:machine_ip] ||= assigned_ip(env) env[:machine_ip] ||= assigned_ip(env)
rescue LXC::Errors::NamespacesNotSupported
@logger.info 'The `lxc-attach` command available does not support the --namespaces parameter, falling back to dnsmasq leases to fetch container ip'
ensure ensure
@app.call(env) @app.call(env)
end end
@ -23,10 +21,11 @@ module Vagrant
fetch_ip_tries = config.fetch_ip_tries fetch_ip_tries = config.fetch_ip_tries
driver = env[:machine].provider.driver driver = env[:machine].provider.driver
ip = '' ip = ''
return config.ssh_ip_addr if not config.ssh_ip_addr.nil?
retryable(:on => LXC::Errors::ExecuteError, :tries => fetch_ip_tries, :sleep => 3) do retryable(:on => LXC::Errors::ExecuteError, :tries => fetch_ip_tries, :sleep => 3) do
unless ip = get_container_ip_from_ip_addr(driver) unless ip = get_container_ip_from_ip_addr(driver)
# retry # retry
raise LXC::Errors::ExecuteError, :command => "lxc-attach" raise LXC::Errors::ExecuteError, :command => "lxc-info"
end end
end end
ip ip
@ -34,8 +33,8 @@ module Vagrant
# From: https://github.com/lxc/lxc/blob/staging/src/python-lxc/lxc/__init__.py#L371-L385 # From: https://github.com/lxc/lxc/blob/staging/src/python-lxc/lxc/__init__.py#L371-L385
def get_container_ip_from_ip_addr(driver) def get_container_ip_from_ip_addr(driver)
output = driver.attach '/sbin/ip', '-4', 'addr', 'show', 'scope', 'global', 'eth0', namespaces: ['network', 'mount'] output = driver.info '-iH'
if output =~ /^\s+inet ([0-9.]+)\/[0-9]+\s+/ if output =~ /^([0-9.]+)/
return $1.to_s return $1.to_s
end end
end end

View file

@ -1,3 +1,5 @@
require 'open3'
module Vagrant module Vagrant
module LXC module LXC
module Action module Action
@ -78,8 +80,12 @@ module Vagrant
end end
def redirect_port(host_ip, host_port, guest_ip, guest_port) def redirect_port(host_ip, host_port, guest_ip, guest_port)
params = %W( --lport=#{host_port} --caddr=#{guest_ip} --cport=#{guest_port} ) if redir_version >= 3
params.unshift "--laddr=#{host_ip}" if host_ip params = %W( -n #{host_ip}:#{host_port} #{guest_ip}:#{guest_port} )
else
params = %W( --lport=#{host_port} --caddr=#{guest_ip} --cport=#{guest_port} )
params.unshift "--laddr=#{host_ip}" if host_ip
end
params << '--syslog' if ENV['REDIR_LOG'] params << '--syslog' if ENV['REDIR_LOG']
if host_port < 1024 if host_port < 1024
redir_cmd = "sudo redir #{params.join(' ')} 2>/dev/null" redir_cmd = "sudo redir #{params.join(' ')} 2>/dev/null"
@ -99,6 +105,13 @@ module Vagrant
end end
end end
def redir_version
stdout, stderr, _ = Open3.capture3 "redir --version"
# For some weird reason redir printed version information in STDERR prior to 3.2
version = stdout.empty? ? stderr : stdout
version.split('.')[0].to_i
end
def redir_installed? def redir_installed?
system "which redir > /dev/null" system "which redir > /dev/null"
end end

View file

@ -33,8 +33,10 @@ module Vagrant
end end
if template_config_file.exist? if template_config_file.exist?
@env[:lxc_box_config] = template_config_file.to_s
@env[:lxc_template_opts].merge!('--config' => template_config_file.to_s) @env[:lxc_template_opts].merge!('--config' => template_config_file.to_s)
elsif old_template_config_file.exist? elsif old_template_config_file.exist?
@env[:lxc_box_config] = old_template_config_file.to_s
@env[:lxc_template_config] = old_template_config_file.to_s @env[:lxc_template_config] = old_template_config_file.to_s
end end

View file

@ -1,5 +1,8 @@
require 'tempfile' require 'tempfile'
require "vagrant-lxc/driver"
require "vagrant-lxc/sudo_wrapper"
module Vagrant module Vagrant
module LXC module LXC
module Command module Command
@ -25,7 +28,7 @@ module Vagrant
argv = parse_options(opts) argv = parse_options(opts)
return unless argv return unless argv
wrapper_path = Vagrant::LXC.sudo_wrapper_path wrapper_path = SudoWrapper.dest_path
wrapper = create_wrapper! wrapper = create_wrapper!
sudoers = create_sudoers!(options[:user], wrapper_path) sudoers = create_sudoers!(options[:user], wrapper_path)
@ -43,12 +46,14 @@ module Vagrant
# This requires vagrant 1.5.2+ https://github.com/mitchellh/vagrant/commit/3371c3716278071680af9b526ba19235c79c64cb # This requires vagrant 1.5.2+ https://github.com/mitchellh/vagrant/commit/3371c3716278071680af9b526ba19235c79c64cb
def create_wrapper! def create_wrapper!
lxc_base_path = Driver.new("").containers_path
wrapper = Tempfile.new('lxc-wrapper').tap do |file| wrapper = Tempfile.new('lxc-wrapper').tap do |file|
template = Vagrant::Util::TemplateRenderer.new( template = Vagrant::Util::TemplateRenderer.new(
'sudoers.rb', 'sudoers.rb',
:template_root => Vagrant::LXC.source_root.join('templates').to_s, :template_root => Vagrant::LXC.source_root.join('templates').to_s,
:cmd_paths => build_cmd_paths_hash, :cmd_paths => build_cmd_paths_hash,
:pipework_regex => "#{ENV['HOME']}/\.vagrant\.d/gems/gems/vagrant-lxc.+/scripts/pipework" :lxc_base_path => lxc_base_path,
:pipework_regex => "#{ENV['HOME']}/\.vagrant\.d/gems/(?:\\d+?\\.\\d+?\\.\\d+?/)?gems/vagrant-lxc.+/scripts/pipework"
) )
file.puts template.render file.puts template.render
end end
@ -80,9 +85,9 @@ module Vagrant
def build_cmd_paths_hash def build_cmd_paths_hash
{}.tap do |hash| {}.tap do |hash|
%w( which cat mkdir cp chown chmod rm tar chown ip ifconfig brctl ).each do |cmd| %w( which cat mkdir cp chown chmod rm tar chown ip ifconfig brctl ).each do |cmd|
hash[cmd] = `which #{cmd}`.strip hash[cmd] = `sudo which #{cmd}`.strip
end end
hash['lxc_bin'] = Pathname(`which lxc-create`.strip).parent.to_s hash['lxc_bin'] = Pathname(`sudo which lxc-create`.strip).parent.to_s
hash['ruby'] = Gem.ruby hash['ruby'] = Gem.ruby
end end
end end

View file

@ -18,15 +18,29 @@ module Vagrant
# machine name, set this to :machine # machine name, set this to :machine
attr_accessor :container_name attr_accessor :container_name
# Size (as a string like '400M') of the tmpfs to mount at /tmp on boot.
# Set to false or nil to disable the tmpfs mount altogether. Defaults to '2G'.
attr_accessor :tmpfs_mount_size
attr_accessor :fetch_ip_tries attr_accessor :fetch_ip_tries
attr_accessor :ssh_ip_addr
# Whether the container needs to be privileged. Defaults to true (unprivileged containers
# is a very new feature in vagrant-lxc). If false, will try creating an unprivileged
# container. If it can't, will revert to the old "sudo wrapper" method to create a privileged
# container.
attr_accessor :privileged
def initialize def initialize
@customizations = [] @customizations = []
@backingstore = UNSET_VALUE @backingstore = UNSET_VALUE
@backingstore_options = [] @backingstore_options = []
@sudo_wrapper = UNSET_VALUE
@container_name = UNSET_VALUE @container_name = UNSET_VALUE
@tmpfs_mount_size = UNSET_VALUE
@fetch_ip_tries = UNSET_VALUE @fetch_ip_tries = UNSET_VALUE
@ssh_ip_addr = UNSET_VALUE
@privileged = UNSET_VALUE
end end
# Customize the container by calling `lxc-start` with the given # Customize the container by calling `lxc-start` with the given
@ -50,11 +64,13 @@ module Vagrant
end end
def finalize! def finalize!
@sudo_wrapper = nil if @sudo_wrapper == UNSET_VALUE
@container_name = nil if @container_name == UNSET_VALUE @container_name = nil if @container_name == UNSET_VALUE
@backingstore = "best" if @backingstore == UNSET_VALUE @backingstore = nil if @backingstore == UNSET_VALUE
@existing_container_name = nil if @existing_container_name == UNSET_VALUE @existing_container_name = nil if @existing_container_name == UNSET_VALUE
@tmpfs_mount_size = '2G' if @tmpfs_mount_size == UNSET_VALUE
@fetch_ip_tries = 10 if @fetch_ip_tries == UNSET_VALUE @fetch_ip_tries = 10 if @fetch_ip_tries == UNSET_VALUE
@ssh_ip_addr = nil if @ssh_ip_addr == UNSET_VALUE
@privileged = true if @privileged == UNSET_VALUE
end end
end end
end end

View file

@ -3,6 +3,7 @@ require "vagrant/util/subprocess"
require "vagrant-lxc/errors" require "vagrant-lxc/errors"
require "vagrant-lxc/driver/cli" require "vagrant-lxc/driver/cli"
require "vagrant-lxc/sudo_wrapper"
require "etc" require "etc"
@ -16,15 +17,13 @@ module Vagrant
class ContainerNotFound < StandardError; end class ContainerNotFound < StandardError; end
# Default root folder where container configs are stored # Default root folder where container configs are stored
DEFAULT_CONTAINERS_PATH = '/var/lib/lxc'
attr_reader :container_name, attr_reader :container_name,
:customizations :customizations
def initialize(container_name, sudo_wrapper, cli = nil) def initialize(container_name, sudo_wrapper = nil, cli = nil, privileged: true)
@container_name = container_name @container_name = container_name
@sudo_wrapper = sudo_wrapper @sudo_wrapper = sudo_wrapper || SudoWrapper.new(privileged: privileged)
@cli = cli || CLI.new(sudo_wrapper, container_name) @cli = cli || CLI.new(@sudo_wrapper, container_name)
@logger = Log4r::Logger.new("vagrant::provider::lxc::driver") @logger = Log4r::Logger.new("vagrant::provider::lxc::driver")
@customizations = [] @customizations = []
end end
@ -35,7 +34,7 @@ module Vagrant
# Root folder where container configs are stored # Root folder where container configs are stored
def containers_path def containers_path
@containers_path ||= @cli.support_config_command? ? @cli.config('lxc.lxcpath') : DEFAULT_CONTAINERS_PATH @containers_path ||= @cli.config('lxc.lxcpath')
end end
def all_containers def all_containers
@ -46,21 +45,25 @@ module Vagrant
Pathname.new("#{containers_path}/#{@container_name}") Pathname.new("#{containers_path}/#{@container_name}")
end end
def config_path
base_path.join('config').to_s
end
def rootfs_path def rootfs_path
config_entry = config_string.match(/^lxc\.rootfs\s+=\s+(.+)$/)[1] pathtype, path = config_string.match(/^lxc\.rootfs(?:\.path)?\s+=\s+(.+:)?(.+)$/)[1..2]
case config_entry case pathtype
when /^overlayfs:/ when 'overlayfs:'
# Split on colon (:), ignoring any colon escaped by an escape character ( \ ) # Split on colon (:), ignoring any colon escaped by an escape character ( \ )
# Pays attention to when the escape character is itself escaped. # Pays attention to when the escape character is itself escaped.
fs_type, master_path, overlay_path = config_entry.split(/(?<!\\)(?:\\\\)*:/) _, overlay_path = config_entry.split(/(?<!\\)(?:\\\\)*:/)
if overlay_path if overlay_path
Pathname.new(overlay_path) Pathname.new(overlay_path)
else else
# Malformed: fall back to prior behaviour # Malformed: fall back to prior behaviour
Pathname.new(config_entry) Pathname.new(path)
end end
else else
Pathname.new(config_entry) Pathname.new(path)
end end
end end
@ -73,13 +76,14 @@ module Vagrant
end end
def config_string def config_string
@sudo_wrapper.run('cat', base_path.join('config').to_s) @sudo_wrapper.run('cat', config_path)
end end
def create(name, backingstore, backingstore_options, template_path, config_file, template_options = {}) def create(name, backingstore, backingstore_options, template_path, config_file, template_options = {})
@cli.name = @container_name = name @cli.name = @container_name = name
@logger.debug "Creating container..." @logger.debug "Creating container..."
@cli.create template_path, backingstore, backingstore_options, config_file, template_options @cli.create template_path, backingstore, backingstore_options, config_file, template_options
end end
@ -118,14 +122,14 @@ module Vagrant
@cli.destroy @cli.destroy
end end
def supports_attach?
@cli.supports_attach?
end
def attach(*command) def attach(*command)
@cli.attach(*command) @cli.attach(*command)
end end
def info(*command)
@cli.info(*command)
end
def configure_private_network(bridge_name, bridge_ip, container_name, address_type, ip) def configure_private_network(bridge_name, bridge_ip, container_name, address_type, ip)
@logger.info "Configuring network interface for #{container_name} using #{ip} and bridge #{bridge_name}" @logger.info "Configuring network interface for #{container_name} using #{ip} and bridge #{bridge_name}"
if ip if ip
@ -207,6 +211,10 @@ module Vagrant
@version ||= @cli.version @version ||= @cli.version
end end
def supports_new_config_format
Gem::Version.new(version) >= Gem::Version.new('2.1.0')
end
# TODO: This needs to be reviewed and specs needs to be written # TODO: This needs to be reviewed and specs needs to be written
def compress_rootfs def compress_rootfs
# TODO: Pass in tmpdir so we can clean up from outside # TODO: Pass in tmpdir so we can clean up from outside
@ -237,6 +245,13 @@ module Vagrant
write_config(contents) write_config(contents)
end end
def update_config_keys(path = nil)
path = path || config_path
@cli.update_config(path)
rescue Errors::ExecuteError
# not on LXC 2.1+. Doesn't matter, ignore.
end
protected protected
def write_customizations(customizations) def write_customizations(customizations)
@ -253,12 +268,21 @@ module Vagrant
end end
def write_config(contents) def write_config(contents)
Tempfile.new('lxc-config').tap do |file| confpath = base_path.join('config').to_s
file.chmod 0644 begin
file.write contents File.open(confpath, File::RDWR) do |file|
file.close file.write contents
@sudo_wrapper.run 'cp', '-f', file.path, base_path.join('config').to_s end
@sudo_wrapper.run 'chown', 'root:root', base_path.join('config').to_s rescue
# We don't have permissions to write in the conf file. That's probably because it's a
# privileged container. Work around that through sudo_wrapper.
Tempfile.new('lxc-config').tap do |file|
file.chmod 0644
file.write contents
file.close
@sudo_wrapper.run 'cp', '-f', file.path, confpath
@sudo_wrapper.run 'chown', 'root:root', confpath
end
end end
end end
end end

View file

@ -29,7 +29,7 @@ module Vagrant
def version def version
return @version if @version return @version if @version
@version = support_version_command? ? run(:version) : run(:create, '--version') @version = run(:create, '--version')
if @version =~ /(lxc version:\s+|)(.+)\s*$/ if @version =~ /(lxc version:\s+|)(.+)\s*$/
@version = $2.downcase @version = $2.downcase
else else
@ -39,11 +39,11 @@ module Vagrant
end end
def config(param) def config(param)
if support_config_command? run(:config, param).gsub("\n", '')
run(:config, param).gsub("\n", '') end
else
raise Errors::CommandNotSupported, name: 'config', available_version: '> 1.x.x', version: version def update_config(path)
end run('update-config', '-c', path)
end end
def state def state
@ -59,7 +59,7 @@ module Vagrant
config_opts = ['-f', config_file] config_opts = ['-f', config_file]
end end
extra = template_opts.to_a.flatten extra = template_opts.to_a.flatten.reject { |elem| elem.empty? }
extra.unshift '--' unless extra.empty? extra.unshift '--' unless extra.empty?
run :create, run :create,
@ -89,14 +89,13 @@ module Vagrant
# Man Page: # Man Page:
# 2 The specified container exists but was not running. # 2 The specified container exists but was not running.
def stop def stop
attach '/sbin/halt' if supports_attach?
begin begin
run :stop, '--name', @name run :stop, '--name', @name
rescue LXC::Errors::ExecuteError => e rescue LXC::Errors::ExecuteError => e
if e.exitcode == 2 if e.exitcode == 2
@logger.debug "Machine already stopped, lxc-stop returned 2" @logger.debug "Machine already stopped, lxc-stop returned 2"
else else
raise e raise e
end end
end end
end end
@ -114,17 +113,17 @@ module Vagrant
end end
if namespaces if namespaces
if supports_attach_with_namespaces? extra = ['--namespaces', namespaces]
extra = ['--namespaces', namespaces]
else
raise LXC::Errors::NamespacesNotSupported
end
end end
end end
run :attach, '--name', @name, *((extra || []) + cmd) run :attach, '--name', @name, *((extra || []) + cmd)
end end
def info(*cmd)
run(:info, '--name', @name, *cmd)
end
def transition_to(target_state, tries = 30, timeout = 1, &block) def transition_to(target_state, tries = 30, timeout = 1, &block)
raise TransitionBlockNotProvided unless block_given? raise TransitionBlockNotProvided unless block_given?
@ -142,42 +141,11 @@ module Vagrant
end end
end end
def supports_attach?
unless defined?(@supports_attach)
begin
@supports_attach = true
run(:attach, '--name', @name, '--', '/bin/true')
rescue LXC::Errors::ExecuteError
@supports_attach = false
end
end
return @supports_attach
end
def support_config_command?
version[0].to_i >= 1
end
def support_version_command?
@sudo_wrapper.run('which', 'lxc-version').strip.chomp != ''
rescue Vagrant::LXC::Errors::ExecuteError
return false
end
private private
def run(command, *args) def run(command, *args)
@sudo_wrapper.run("lxc-#{command}", *args) @sudo_wrapper.run("lxc-#{command}", *args)
end end
def supports_attach_with_namespaces?
unless defined?(@supports_attach_with_namespaces)
@supports_attach_with_namespaces = run(:attach, '-h', :show_stderr => true).values.join.include?('--namespaces')
end
return @supports_attach_with_namespaces
end
end end
end end
end end

View file

@ -16,9 +16,15 @@ module Vagrant
end end
end end
class NamespacesNotSupported < Vagrant::Errors::VagrantError # Raised when user interrupts a subprocess
class SubprocessInterruptError < Vagrant::Errors::VagrantError
error_key(:lxc_interrupt_error)
def initialize(message, *args)
super
end
end end
class LxcLinuxRequired < Vagrant::Errors::VagrantError class LxcLinuxRequired < Vagrant::Errors::VagrantError
error_key(:lxc_linux_required) error_key(:lxc_linux_required)
end end

View file

@ -10,7 +10,7 @@ module Vagrant
EOF EOF
provider(:lxc, parallel: true, priority: 7) do provider(:lxc, parallel: true, priority: 7) do
require File.expand_path("../provider", __FILE__) require_relative 'provider'
init! init!
Provider Provider
end end
@ -22,13 +22,13 @@ module Vagrant
end end
config(:lxc, :provider) do config(:lxc, :provider) do
require File.expand_path("../config", __FILE__) require_relative 'config'
init! init!
Config Config
end end
synced_folder(:lxc) do synced_folder(:lxc) do
require File.expand_path("../synced_folder", __FILE__) require_relative 'synced_folder'
SyncedFolder SyncedFolder
end end

View file

@ -2,7 +2,6 @@ require "log4r"
require "vagrant-lxc/action" require "vagrant-lxc/action"
require "vagrant-lxc/driver" require "vagrant-lxc/driver"
require "vagrant-lxc/sudo_wrapper"
module Vagrant module Vagrant
module LXC module LXC
@ -25,18 +24,9 @@ module Vagrant
machine_id_changed machine_id_changed
end end
def sudo_wrapper
@shell ||= begin
wrapper = Pathname.new(LXC.sudo_wrapper_path).exist? &&
LXC.sudo_wrapper_path || nil
@logger.debug("Found sudo wrapper : #{wrapper}") if wrapper
SudoWrapper.new(wrapper)
end
end
def ensure_lxc_installed! def ensure_lxc_installed!
begin begin
sudo_wrapper.run("which", "lxc-create") SudoWrapper.new(privileged: @machine.provider_config.privileged).run("which", "lxc-create")
rescue Vagrant::LXC::Errors::ExecuteError rescue Vagrant::LXC::Errors::ExecuteError
raise Errors::LxcNotInstalled raise Errors::LxcNotInstalled
end end
@ -49,7 +39,7 @@ module Vagrant
begin begin
@logger.debug("Instantiating the container for: #{id.inspect}") @logger.debug("Instantiating the container for: #{id.inspect}")
@driver = Driver.new(id, self.sudo_wrapper) @driver = Driver.new(id, privileged: @machine.provider_config.privileged)
@driver.validate! @driver.validate!
rescue Driver::ContainerNotFound rescue Driver::ContainerNotFound
# The container doesn't exist, so we probably have a stale # The container doesn't exist, so we probably have a stale

View file

@ -6,18 +6,40 @@ module Vagrant
attr_reader :wrapper_path attr_reader :wrapper_path
def initialize(wrapper_path = nil) def self.dest_path
@wrapper_path = wrapper_path "/usr/local/bin/vagrant-lxc-wrapper"
end
def initialize(privileged: true)
@wrapper_path = Pathname.new(SudoWrapper.dest_path).exist? && SudoWrapper.dest_path || nil
@privileged = privileged
@logger = Log4r::Logger.new("vagrant::lxc::sudo_wrapper") @logger = Log4r::Logger.new("vagrant::lxc::sudo_wrapper")
end end
def run(*command) def run(*command)
options = command.last.is_a?(Hash) ? command.last : {} options = command.last.is_a?(Hash) ? command.last : {}
if @wrapper_path && !options[:no_wrapper]
command.unshift @wrapper_path # Avoid running LXC commands with a restrictive umask.
execute *(['sudo'] + command) # Otherwise disasters occur, like the container root directory
else # having permissions `rwxr-x---` which prevents the `vagrant`
execute *(['sudo', '/usr/bin/env'] + command) # user from accessing its own home directory; among other
# problems, SSH cannot then read `authorized_keys`!
old_mask = File.umask
File.umask(old_mask & 022) # allow all `r` and `x` bits
begin
if @privileged
if @wrapper_path && !options[:no_wrapper]
command.unshift @wrapper_path
execute *(['sudo'] + command)
else
execute *(['sudo', '/usr/bin/env'] + command)
end
else
execute *(['/usr/bin/env'] + command)
end
ensure
File.umask(old_mask)
end end
end end
@ -46,7 +68,7 @@ module Vagrant
# nicely handled by Vagrant. # nicely handled by Vagrant.
if r.exit_code != 0 if r.exit_code != 0
if @interrupted if @interrupted
@logger.info("Exit code != 0, but interrupted. Ignoring.") raise LXC::Errors::SubprocessInterruptError, command.inspect
else else
raise LXC::Errors::ExecuteError, raise LXC::Errors::ExecuteError,
command: command.inspect, stderr: r.stderr, stdout: r.stdout, exitcode: r.exit_code command: command.inspect, stderr: r.stderr, stdout: r.stdout, exitcode: r.exit_code

View file

@ -1,5 +1,5 @@
module Vagrant module Vagrant
module LXC module LXC
VERSION = "1.2.2" VERSION = "1.4.2"
end end
end end

View file

@ -40,6 +40,9 @@ en:
preparing: Setting up mount entries for shared folders... preparing: Setting up mount entries for shared folders...
errors: errors:
lxc_interrupt_error: |-
Interrupted
lxc_execute_error: |- lxc_execute_error: |-
There was an error executing %{command} There was an error executing %{command}

View file

@ -33,8 +33,10 @@ LXC_PATH=
LXC_ROOTFS= LXC_ROOTFS=
LXC_TARBALL= LXC_TARBALL=
LXC_CONFIG= LXC_CONFIG=
LXC_USE_OLDCONFIG=
LXC_STRIP_COMPONENTS=2 LXC_STRIP_COMPONENTS=2
usage() { usage() {
cat <<EOF cat <<EOF
vagrant-lxc default template vagrant-lxc default template
@ -44,6 +46,7 @@ Required arguments:
Optional arguments: Optional arguments:
[ --config ]: Configuration file to be used when building the container [ --config ]: Configuration file to be used when building the container
[ --oldconfig ]: Use pre LXC 2.1 config format
[ -h | --help ]: This help message [ -h | --help ]: This help message
LXC internal arguments (do not pass manually!): LXC internal arguments (do not pass manually!):
@ -57,7 +60,7 @@ EOF
return 0 return 0
} }
options=$(getopt -o h -l tarball:,config:,help:,name:,path:,rootfs:,mapped-uid:,mapped-gid:,strip-components: -- "$@")SS options=$(getopt -o h -l tarball:,config:,oldconfig,help:,name:,path:,rootfs:,mapped-uid:,mapped-gid:,strip-components: -- "$@")SS
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
usage $(basename $0) usage $(basename $0)
@ -70,6 +73,7 @@ do
case "$1" in case "$1" in
-h|--help) usage $0 && exit 0;; -h|--help) usage $0 && exit 0;;
--config) LXC_CONFIG=$2; shift 2;; --config) LXC_CONFIG=$2; shift 2;;
--oldconfig) LXC_USE_OLDCONFIG=1; shift 1;;
--tarball) LXC_TARBALL=$2; shift 2;; --tarball) LXC_TARBALL=$2; shift 2;;
--name) LXC_NAME=$2; shift 2;; --name) LXC_NAME=$2; shift 2;;
--path) LXC_PATH=$2; shift 2;; --path) LXC_PATH=$2; shift 2;;
@ -96,11 +100,6 @@ if [ -z "${LXC_PATH}" ]; then
exit 1 exit 1
fi fi
if [ -z "${LXC_CONFIG}" ]; then
echo "'config' parameter is required"
exit 1
fi
# if $LXC_ROOTFS exists here, it was passed in with --rootfs # if $LXC_ROOTFS exists here, it was passed in with --rootfs
if [ -z "${LXC_ROOTFS}" ]; then if [ -z "${LXC_ROOTFS}" ]; then
config=${LXC_PATH}/config config=${LXC_PATH}/config
@ -115,7 +114,6 @@ fi
# Unpack the rootfs # Unpack the rootfs
echo "Unpacking the rootfs" echo "Unpacking the rootfs"
mkdir -p /var/lock/subsys
( (
flock -x 200 flock -x 200
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
@ -124,13 +122,14 @@ mkdir -p /var/lock/subsys
fi fi
mkdir -p ${LXC_ROOTFS} mkdir -p ${LXC_ROOTFS}
(cd ${LXC_ROOTFS} && tar xfz ${LXC_TARBALL} --strip-components=${LXC_STRIP_COMPONENTS} --xattrs --xattrs-include=*) (cd ${LXC_ROOTFS} && tar xfz ${LXC_TARBALL} --strip-components=${LXC_STRIP_COMPONENTS} --xattrs --xattrs-include=* || true)
if [ $? -ne 0 ]; then if [ ! -f ${LXC_ROOTFS}/bin/true ]; then
echo "Failed to extract rootfs" echo "Failed to extract rootfs"
exit 1 exit 1
fi fi
) 200>/var/lock/subsys/lxc ) 200>${LXC_PATH}/vagrant_lock
rm ${LXC_PATH}/vagrant_lock
mkdir -p ${LXC_ROOTFS}/dev/pts/ mkdir -p ${LXC_ROOTFS}/dev/pts/
@ -149,7 +148,12 @@ if [ -e "${LXC_PATH}/config-auto" ]; then
cat ${LXC_PATH}/config-auto >> ${LXC_PATH}/config cat ${LXC_PATH}/config-auto >> ${LXC_PATH}/config
rm ${LXC_PATH}/config-auto rm ${LXC_PATH}/config-auto
fi fi
echo "lxc.utsname = ${LXC_NAME}" >> ${LXC_PATH}/config
if [ $LXC_USE_OLDCONFIG ]; then
echo "lxc.utsname = ${LXC_NAME}" >> ${LXC_PATH}/config
else
echo "lxc.uts.name = ${LXC_NAME}" >> ${LXC_PATH}/config
fi
## Re-add the previously removed network config ## Re-add the previously removed network config
if [ -e "${LXC_PATH}/config-network" ]; then if [ -e "${LXC_PATH}/config-network" ]; then
@ -160,11 +164,13 @@ if [ -e "${LXC_PATH}/config-network" ]; then
rm ${LXC_PATH}/config-network rm ${LXC_PATH}/config-network
fi fi
## Append the defaults if [ -n "${LXC_CONFIG}" ]; then
echo "" >> ${LXC_PATH}/config ## Append the defaults
echo "##############################################" >> ${LXC_PATH}/config echo "" >> ${LXC_PATH}/config
echo "# vagrant-lxc base box specific configuration" >> ${LXC_PATH}/config echo "##############################################" >> ${LXC_PATH}/config
cat ${LXC_CONFIG} >> ${LXC_PATH}/config echo "# vagrant-lxc base box specific configuration" >> ${LXC_PATH}/config
cat ${LXC_CONFIG} >> ${LXC_PATH}/config
fi
# Empty section for lxc.customize calls from vagrantfile # Empty section for lxc.customize calls from vagrantfile
echo "" >> ${LXC_PATH}/config echo "" >> ${LXC_PATH}/config

View file

@ -390,7 +390,7 @@ else
;; ;;
"") "")
if installed ipcalc; then if installed ipcalc; then
eval $(ipcalc -b $IPADDR) eval "$(ipcalc -b $IPADDR)"
ip netns exec "$NSPID" ip addr add "$IPADDR" brd "$BROADCAST" dev "$CONTAINER_IFNAME" ip netns exec "$NSPID" ip addr add "$IPADDR" brd "$BROADCAST" dev "$CONTAINER_IFNAME"
else else
ip netns exec "$NSPID" ip addr add "$IPADDR" dev "$CONTAINER_IFNAME" ip netns exec "$NSPID" ip addr add "$IPADDR" dev "$CONTAINER_IFNAME"

4
spec/Vagrantfile vendored
View file

@ -15,10 +15,6 @@ Vagrant.configure("2") do |config|
config.cache.auto_detect = true config.cache.auto_detect = true
config.vm.provider :lxc do |lxc|
# lxc.sudo_wrapper = '/usr/bin/lxc-vagrant-wrapper'
end
config.vm.provision :shell, config.vm.provision :shell,
inline: 'mkdir -p /vagrant/tmp && echo -n "Provisioned" > /vagrant/tmp/provisioning' inline: 'mkdir -p /vagrant/tmp && echo -n "Provisioned" > /vagrant/tmp/provisioning'

View file

@ -24,6 +24,7 @@ describe Vagrant::LXC::Action::ForwardPorts do
machine.stub_chain(:config, :vm, :networks).and_return(networks) machine.stub_chain(:config, :vm, :networks).and_return(networks)
machine.stub(provider: provider, data_dir: data_dir) machine.stub(provider: provider, data_dir: data_dir)
subject.stub(redir_version: 3)
subject.stub(exec: true) subject.stub(exec: true)
subject.stub(spawn: pid) subject.stub(spawn: pid)
end end
@ -34,7 +35,7 @@ describe Vagrant::LXC::Action::ForwardPorts do
subject.stub(system: true) subject.stub(system: true)
subject.call(env) subject.call(env)
expect(subject).to have_received(:spawn).with( expect(subject).to have_received(:spawn).with(
"redir --laddr=#{host_ip} --lport=#{host_port} --caddr=#{container_ip} --cport=#{guest_port} 2>/dev/null" "redir -n #{host_ip}:#{host_port} #{container_ip}:#{guest_port} 2>/dev/null"
) )
end end
@ -43,7 +44,7 @@ describe Vagrant::LXC::Action::ForwardPorts do
subject.stub(system: true) subject.stub(system: true)
subject.call(env) subject.call(env)
expect(subject).to have_received(:spawn).with( expect(subject).to have_received(:spawn).with(
"redir --laddr=127.0.0.1 --lport=#{host_port} --caddr=#{container_ip} --cport=#{guest_port} 2>/dev/null" "redir -n 127.0.0.1:#{host_port} #{container_ip}:#{guest_port} 2>/dev/null"
) )
end end
@ -52,7 +53,7 @@ describe Vagrant::LXC::Action::ForwardPorts do
subject.stub(system: true) subject.stub(system: true)
subject.call(env) subject.call(env)
expect(subject).to have_received(:spawn).with( expect(subject).to have_received(:spawn).with(
"redir --laddr=127.0.0.1 --lport=#{host_port} --caddr=#{container_ip} --cport=#{guest_port} 2>/dev/null" "redir -n 127.0.0.1:#{host_port} #{container_ip}:#{guest_port} 2>/dev/null"
) )
end end
@ -70,6 +71,15 @@ describe Vagrant::LXC::Action::ForwardPorts do
expect(subject).not_to have_received(:spawn) expect(subject).not_to have_received(:spawn)
end end
it 'uses redir 2.x command line interface' do
subject.stub(system: true)
subject.stub(redir_version: 2)
subject.call(env)
expect(subject).to have_received(:spawn).with(
"redir --laddr=#{host_ip} --lport=#{host_port} --caddr=#{container_ip} --cport=#{guest_port} 2>/dev/null"
)
end
it 'raises RedirNotInstalled error if `redir` is not installed' do it 'raises RedirNotInstalled error if `redir` is not installed' do
subject.stub(system: false) subject.stub(system: false)
expect { subject.call(env) }.to raise_error(Vagrant::LXC::Errors::RedirNotInstalled) expect { subject.call(env) }.to raise_error(Vagrant::LXC::Errors::RedirNotInstalled)
@ -82,7 +92,7 @@ describe Vagrant::LXC::Action::ForwardPorts do
subject.stub(system: true) subject.stub(system: true)
subject.call(env) subject.call(env)
expect(subject).to have_received(:spawn).with( expect(subject).to have_received(:spawn).with(
"sudo redir --laddr=#{host_ip} --lport=#{host_port} --caddr=#{container_ip} --cport=#{guest_port} 2>/dev/null" "sudo redir -n #{host_ip}:#{host_port} #{container_ip}:#{guest_port} 2>/dev/null"
) )
end end
@ -91,7 +101,7 @@ describe Vagrant::LXC::Action::ForwardPorts do
subject.stub(system: true) subject.stub(system: true)
subject.call(env) subject.call(env)
expect(subject).to have_received(:spawn).with( expect(subject).to have_received(:spawn).with(
"sudo redir --laddr=127.0.0.1 --lport=#{host_port} --caddr=#{container_ip} --cport=#{guest_port} 2>/dev/null" "sudo redir -n 127.0.0.1:#{host_port} #{container_ip}:#{guest_port} 2>/dev/null"
) )
end end
@ -100,7 +110,7 @@ describe Vagrant::LXC::Action::ForwardPorts do
subject.stub(system: true) subject.stub(system: true)
subject.call(env) subject.call(env)
expect(subject).to have_received(:spawn).with( expect(subject).to have_received(:spawn).with(
"sudo redir --laddr=127.0.0.1 --lport=#{host_port} --caddr=#{container_ip} --cport=#{guest_port} 2>/dev/null" "sudo redir -n 127.0.0.1:#{host_port} #{container_ip}:#{guest_port} 2>/dev/null"
) )
end end
end end

View file

@ -30,16 +30,7 @@ describe Vagrant::LXC::Driver::CLI do
describe 'version' do describe 'version' do
before do before do
allow(subject).to receive(:support_version_command?).and_return(true) allow(subject).to receive(:run).with(:create, '--version').and_return(lxc_version_out)
allow(subject).to receive(:run).with(:version).and_return(lxc_version_out)
end
describe 'lxc version before 1.x.x' do
let(:lxc_version_out) { "lxc version: 0.x.y-rc1\n" }
it 'parses the version from the output' do
expect(subject.version).to eq('0.x.y-rc1')
end
end end
describe 'lxc version after 1.x.x' do describe 'lxc version after 1.x.x' do
@ -53,24 +44,11 @@ describe Vagrant::LXC::Driver::CLI do
describe 'config' do describe 'config' do
before do before do
allow(subject).to receive(:support_version_command?).and_return(support_version_command?)
allow(subject).to receive(:run).with(:config, 'lxc.lxcpath').and_return(lxc_config_out) allow(subject).to receive(:run).with(:config, 'lxc.lxcpath').and_return(lxc_config_out)
allow(subject).to receive(:run).with(:version).and_return(lxc_version_out)
allow(subject).to receive(:run).with(:create, '--version').and_return(lxc_version_out) allow(subject).to receive(:run).with(:create, '--version').and_return(lxc_version_out)
end end
describe 'lxc version before 1.x.x' do describe 'lxc version after 1.x.x'do
let(:support_version_command?) { true }
let(:lxc_config_out) { "/var/lib/lxc\n" }
let(:lxc_version_out) { "lxc version: 0.x.y-rc1\n" }
it 'not supported' do
expect{subject.config('lxc.lxcpath')}.to raise_error(Vagrant::LXC::Errors::CommandNotSupported)
end
end
describe 'lxc version before after 1.x.x'do
let(:support_version_command?) { false }
let(:lxc_config_out) { "/var/lib/lxc\n" } let(:lxc_config_out) { "/var/lib/lxc\n" }
let(:lxc_version_out) { "1.0.0\n" } let(:lxc_version_out) { "1.0.0\n" }
@ -156,36 +134,11 @@ describe Vagrant::LXC::Driver::CLI do
before do before do
allow(subject).to receive(:run) allow(subject).to receive(:run)
subject.stop
end end
context 'lxc-attach is supported' do it 'issues a lxc-stop with provided container name' do
before do expect(subject).to have_received(:run).with(:stop, '--name', name)
subject.stub(attach: true, supports_attach?: true)
subject.stop
end
it 'runs a /sbin/halt within the container' do
expect(subject).to have_received(:attach).with('/sbin/halt')
end
it 'issues a lxc-stop with provided container name' do
expect(subject).to have_received(:run).with(:stop, '--name', name)
end
end
context 'lxc-attach is not supported' do
before do
subject.stub(attach: false, supports_attach?: false)
subject.stop
end
it 'runs a /sbin/halt within the container' do
expect(subject).to_not have_received(:attach)
end
it 'issues a lxc-stop with provided container name' do
expect(subject).to have_received(:run).with(:stop, '--name', name)
end
end end
end end
@ -232,13 +185,6 @@ describe Vagrant::LXC::Driver::CLI do
subject.attach *(command + [{namespaces: ['network', 'mount']}]) subject.attach *(command + [{namespaces: ['network', 'mount']}])
expect(subject).to have_received(:run).with(:attach, '--name', name, '--namespaces', 'NETWORK|MOUNT', '--', *command) expect(subject).to have_received(:run).with(:attach, '--name', name, '--namespaces', 'NETWORK|MOUNT', '--', *command)
end end
it 'raises a NamespacesNotSupported error if not supported' do
allow(subject).to receive(:run).with(:attach, '-h', :show_stderr => true).and_return({:stdout => '', :stderr => 'not supported'})
expect {
subject.attach *(command + [{namespaces: ['network', 'mount']}])
}.to raise_error(Vagrant::LXC::Errors::NamespacesNotSupported)
end
end end
describe 'transition block' do describe 'transition block' do
@ -260,33 +206,4 @@ describe Vagrant::LXC::Driver::CLI do
skip 'waits for the expected container state' skip 'waits for the expected container state'
end end
describe 'check for whether lxc-attach is supported' do
let(:name) { 'a-running-container' }
subject { described_class.new(sudo_wrapper, name) }
context 'lxc-attach is present on system' do
before { subject.stub(run: true) }
it 'returns true if `lxc-attach --name CNAME -- /bin/true` works' do
expect(subject.supports_attach?).to be_truthy
expect(subject).to have_received(:run).with(
:attach, '--name', name, '--', '/bin/true'
)
end
end
context 'lxc-attach is not present on system' do
before do
allow(subject).to receive(:run).and_raise(Vagrant::LXC::Errors::ExecuteError.new('msg'))
end
it 'returns true if `lxc-attach --name CNAME -- /bin/true` works' do
expect(subject.supports_attach?).to be_falsy
expect(subject).to have_received(:run).with(
:attach, '--name', name, '--', '/bin/true'
)
end
end
end
end end

View file

@ -75,21 +75,10 @@ describe Vagrant::LXC::Driver do
end end
end end
describe 'supports_attach?' do
let(:cli) { double(Vagrant::LXC::Driver::CLI, supports_attach?: true) }
subject { described_class.new('name', nil, cli) }
it 'delegates to cli object' do
expect(subject.supports_attach?).to be_truthy
expect(cli).to have_received(:supports_attach?)
end
end
describe 'start' do describe 'start' do
let(:customizations) { [['a', '1'], ['b', '2']] } let(:customizations) { [['a', '1'], ['b', '2']] }
let(:internal_customization) { ['internal', 'customization'] } let(:internal_customization) { ['internal', 'customization'] }
let(:cli) { double(Vagrant::LXC::Driver::CLI, start: true, support_config_command?: false) } let(:cli) { double(Vagrant::LXC::Driver::CLI, start: true) }
let(:sudo) { double(Vagrant::LXC::SudoWrapper) } let(:sudo) { double(Vagrant::LXC::SudoWrapper) }
subject { described_class.new('name', sudo, cli) } subject { described_class.new('name', sudo, cli) }
@ -99,6 +88,7 @@ describe Vagrant::LXC::Driver do
and_return('# CONFIGURATION') and_return('# CONFIGURATION')
sudo.should_receive(:run).twice.with('cp', '-f', %r{/(run|tmp)/.*}, '/var/lib/lxc/name/config') sudo.should_receive(:run).twice.with('cp', '-f', %r{/(run|tmp)/.*}, '/var/lib/lxc/name/config')
sudo.should_receive(:run).twice.with('chown', 'root:root', '/var/lib/lxc/name/config') sudo.should_receive(:run).twice.with('chown', 'root:root', '/var/lib/lxc/name/config')
expect(cli).to receive(:config).with("lxc.lxcpath").and_return("/var/lib/lxc")
subject.customizations << internal_customization subject.customizations << internal_customization
subject.start(customizations) subject.start(customizations)
@ -152,21 +142,11 @@ describe Vagrant::LXC::Driver do
end end
describe 'containers_path' do describe 'containers_path' do
let(:cli) { double(Vagrant::LXC::Driver::CLI, config: cli_config_value, support_config_command?: cli_support_config_command_value) } let(:cli) { double(Vagrant::LXC::Driver::CLI, config: cli_config_value) }
subject { described_class.new('name', nil, cli) } subject { described_class.new('name', nil, cli) }
describe 'lxc version before 1.x.x' do
let(:cli_support_config_command_value) { false }
let(:cli_config_value) { '/var/lib/lxc' }
it 'delegates to cli' do
expect(subject.containers_path).to eq(cli_config_value)
end
end
describe 'lxc version after 1.x.x' do describe 'lxc version after 1.x.x' do
let(:cli_support_config_command_value) { true }
let(:cli_config_value) { '/etc/lxc' } let(:cli_config_value) { '/etc/lxc' }
it 'delegates to cli' do it 'delegates to cli' do
@ -220,9 +200,9 @@ describe Vagrant::LXC::Driver do
# Blah blah comment # Blah blah comment
lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0 lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0
lxc.mount.entry = sysfs sys sysfs defaults 0 0 lxc.mount.entry = sysfs sys sysfs defaults 0 0
lxc.tty = 4 lxc.tty.max = 4
lxc.pts = 1024 lxc.pty.max = 1024
lxc.rootfs = #{rootfs_path} lxc.rootfs.path = #{rootfs_path}
# VAGRANT-BEGIN # VAGRANT-BEGIN
lxc.network.type=veth lxc.network.type=veth
lxc.network.name=eth1 lxc.network.name=eth1
@ -250,9 +230,9 @@ describe Vagrant::LXC::Driver do
# Blah blah comment # Blah blah comment
lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0 lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0
lxc.mount.entry = sysfs sys sysfs defaults 0 0 lxc.mount.entry = sysfs sys sysfs defaults 0 0
lxc.tty = 4 lxc.tty.max = 4
lxc.pts = 1024 lxc.pty.max = 1024
lxc.rootfs = overlayfs:/path/to/master/directory:#{rootfs_path} lxc.rootfs.path = overlayfs:/path/to/master/directory:#{rootfs_path}
# VAGRANT-BEGIN # VAGRANT-BEGIN
lxc.network.type=veth lxc.network.type=veth
lxc.network.name=eth1 lxc.network.name=eth1

View file

@ -78,7 +78,7 @@ class Whitelist
end end
end end
base = "/var/lib/lxc" base = "<%= lxc_base_path %>"
base_path = %r{\A#{base}/.*\z} base_path = %r{\A#{base}/.*\z}
## ##
@ -109,6 +109,7 @@ Whitelist.add_regex %r{<%= pipework_regex %>}, '**'
Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-version' Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-version'
Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-ls' Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-ls'
Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-info', '--name', /.*/ Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-info', '--name', /.*/
Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-info', '--name', /.*/, '-iH'
Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-create', '-B', /.*/, '--template', /.*/, '--name', /.*/, '**' Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-create', '-B', /.*/, '--template', /.*/, '--name', /.*/, '**'
Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-create', '--version' Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-create', '--version'
Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-destroy', '--name', /.*/ Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-destroy', '--name', /.*/
@ -118,6 +119,7 @@ Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-shutdown', '--name', /.*/
Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-attach', '--name', /.*/, '**' Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-attach', '--name', /.*/, '**'
Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-attach', '-h' Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-attach', '-h'
Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-config', 'lxc.lxcpath' Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-config', 'lxc.lxcpath'
Whitelist.add '<%= cmd_paths['lxc_bin'] %>/lxc-update-config', '-c', /.*/
## ##
# Commands from driver/action/remove_temporary_files.rb # Commands from driver/action/remove_temporary_files.rb