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.
This commit is contained in:
parent
9e215ae1a1
commit
530a899467
6 changed files with 57 additions and 28 deletions
24
README.md
24
README.md
|
@ -78,7 +78,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).
|
||||
|
||||
### Private Networks [EXPERIMENTAL]
|
||||
### Private Networks
|
||||
|
||||
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)
|
||||
|
@ -137,25 +137,29 @@ Vagrant.configure("2") do |config|
|
|||
end
|
||||
```
|
||||
|
||||
For old versions of lxc (like 0.7.5 shipped with Ubuntu 12.04 by default) that
|
||||
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
|
||||
`~/.vagrant.d/Vagrantfile` using the same `provider` block:
|
||||
## Unprivileged containers support
|
||||
|
||||
Since v1.4.0, `vagrant-lxc` gained support for unprivileged containers. For now, since it's a new
|
||||
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
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.provider :lxc do |lxc|
|
||||
lxc.backingstore = 'none'
|
||||
lxc.privileged = false
|
||||
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
|
||||
|
||||
This plugin requires **a lot** of `sudo`ing since [unprivileged containers](https://github.com/fgrehm/vagrant-lxc/issues/312)
|
||||
are not supported yet. To work around that, you can use the `vagrant lxc sudoers`
|
||||
command which will create a file under `/etc/sudoers.d/vagrant-lxc` whitelisting
|
||||
all commands required by `vagrant-lxc` to run.
|
||||
If you're not using unprivileged containers, this plugin requires **a lot** of `sudo`ing To work
|
||||
around that, you can use the `vagrant lxc sudoers` command which will create a file under
|
||||
`/etc/sudoers.d/vagrant-lxc` whitelisting all commands required by `vagrant-lxc` to run.
|
||||
|
||||
If you are interested on what will be generated by that command, please check
|
||||
[this code](lib/vagrant-lxc/command/sudoers.rb).
|
||||
|
|
|
@ -19,10 +19,14 @@ module Vagrant
|
|||
container_name = generate_container_name(env)
|
||||
end
|
||||
|
||||
backingstore = config.backingstore
|
||||
if backingstore.nil?
|
||||
backingstore = config.privileged ? "best" : "dir"
|
||||
end
|
||||
driver = env[:machine].provider.driver
|
||||
driver.create(
|
||||
container_name,
|
||||
config.backingstore,
|
||||
backingstore,
|
||||
config.backingstore_options,
|
||||
env[:lxc_template_src],
|
||||
env[:lxc_template_config],
|
||||
|
|
|
@ -24,6 +24,12 @@ module Vagrant
|
|||
|
||||
attr_accessor :fetch_ip_tries
|
||||
|
||||
# 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
|
||||
@customizations = []
|
||||
@backingstore = UNSET_VALUE
|
||||
|
@ -31,6 +37,7 @@ module Vagrant
|
|||
@container_name = UNSET_VALUE
|
||||
@tmpfs_mount_size = UNSET_VALUE
|
||||
@fetch_ip_tries = UNSET_VALUE
|
||||
@privileged = UNSET_VALUE
|
||||
end
|
||||
|
||||
# Customize the container by calling `lxc-start` with the given
|
||||
|
@ -55,10 +62,11 @@ module Vagrant
|
|||
|
||||
def finalize!
|
||||
@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
|
||||
@tmpfs_mount_size = '2G' if @tmpfs_mount_size == UNSET_VALUE
|
||||
@fetch_ip_tries = 10 if @fetch_ip_tries == UNSET_VALUE
|
||||
@privileged = true if @privileged == UNSET_VALUE
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,9 +20,9 @@ module Vagrant
|
|||
attr_reader :container_name,
|
||||
:customizations
|
||||
|
||||
def initialize(container_name, sudo_wrapper = nil, cli = nil)
|
||||
def initialize(container_name, sudo_wrapper = nil, cli = nil, privileged: true)
|
||||
@container_name = container_name
|
||||
@sudo_wrapper = sudo_wrapper || SudoWrapper.new()
|
||||
@sudo_wrapper = sudo_wrapper || SudoWrapper.new(privileged: privileged)
|
||||
@cli = cli || CLI.new(@sudo_wrapper, container_name)
|
||||
@logger = Log4r::Logger.new("vagrant::provider::lxc::driver")
|
||||
@customizations = []
|
||||
|
@ -266,12 +266,21 @@ module Vagrant
|
|||
end
|
||||
|
||||
def write_config(contents)
|
||||
confpath = base_path.join('config').to_s
|
||||
begin
|
||||
File.open(confpath, File::RDWR) do |file|
|
||||
file.write contents
|
||||
end
|
||||
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, config_path
|
||||
@sudo_wrapper.run 'chown', 'root:root', config_path
|
||||
@sudo_wrapper.run 'cp', '-f', file.path, confpath
|
||||
@sudo_wrapper.run 'chown', 'root:root', confpath
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,6 @@ require "log4r"
|
|||
|
||||
require "vagrant-lxc/action"
|
||||
require "vagrant-lxc/driver"
|
||||
require "vagrant-lxc/sudo_wrapper"
|
||||
|
||||
module Vagrant
|
||||
module LXC
|
||||
|
@ -27,7 +26,7 @@ module Vagrant
|
|||
|
||||
def ensure_lxc_installed!
|
||||
begin
|
||||
SudoWrapper.new().run("which", "lxc-create")
|
||||
SudoWrapper.new(privileged: @machine.provider_config.privileged).run("which", "lxc-create")
|
||||
rescue Vagrant::LXC::Errors::ExecuteError
|
||||
raise Errors::LxcNotInstalled
|
||||
end
|
||||
|
@ -40,7 +39,7 @@ module Vagrant
|
|||
|
||||
begin
|
||||
@logger.debug("Instantiating the container for: #{id.inspect}")
|
||||
@driver = Driver.new(id)
|
||||
@driver = Driver.new(id, privileged: @machine.provider_config.privileged)
|
||||
@driver.validate!
|
||||
rescue Driver::ContainerNotFound
|
||||
# The container doesn't exist, so we probably have a stale
|
||||
|
|
|
@ -10,8 +10,9 @@ module Vagrant
|
|||
"/usr/local/bin/vagrant-lxc-wrapper"
|
||||
end
|
||||
|
||||
def initialize()
|
||||
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")
|
||||
end
|
||||
|
||||
|
@ -27,12 +28,16 @@ module Vagrant
|
|||
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
|
||||
|
|
Loading…
Reference in a new issue