97b5882262
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.
97 lines
3 KiB
Ruby
97 lines
3 KiB
Ruby
require 'tempfile'
|
|
|
|
require "vagrant-lxc/driver"
|
|
require "vagrant-lxc/sudo_wrapper"
|
|
|
|
module Vagrant
|
|
module LXC
|
|
module Command
|
|
class Sudoers < Vagrant.plugin("2", :command)
|
|
|
|
def initialize(argv, env)
|
|
super
|
|
@argv
|
|
@env = env
|
|
end
|
|
|
|
def execute
|
|
options = { user: ENV['USER'] }
|
|
|
|
opts = OptionParser.new do |opts|
|
|
opts.banner = "Usage: vagrant lxc sudoers"
|
|
opts.separator ""
|
|
opts.on('-u user', '--user user', String, "The user for which to create the policy (defaults to '#{options[:user]}')") do |u|
|
|
options[:user] = u
|
|
end
|
|
end
|
|
|
|
argv = parse_options(opts)
|
|
return unless argv
|
|
|
|
wrapper_path = SudoWrapper.bin_path
|
|
wrapper = create_wrapper!
|
|
sudoers = create_sudoers!(options[:user], wrapper_path)
|
|
|
|
su_copy([
|
|
{source: wrapper, target: wrapper_path, mode: "0555"},
|
|
{source: sudoers, target: sudoers_path, mode: "0440"}
|
|
])
|
|
end
|
|
|
|
def sudoers_path
|
|
"/etc/sudoers.d/vagrant-lxc"
|
|
end
|
|
|
|
private
|
|
|
|
# This requires vagrant 1.5.2+ https://github.com/mitchellh/vagrant/commit/3371c3716278071680af9b526ba19235c79c64cb
|
|
def create_wrapper!
|
|
lxc_base_path = Driver.new("").containers_path
|
|
wrapper = Tempfile.new('lxc-wrapper').tap do |file|
|
|
template = Vagrant::Util::TemplateRenderer.new(
|
|
'sudoers.rb',
|
|
:template_root => Vagrant::LXC.source_root.join('templates').to_s,
|
|
:cmd_paths => build_cmd_paths_hash,
|
|
: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
|
|
end
|
|
wrapper.close
|
|
wrapper.path
|
|
end
|
|
|
|
def create_sudoers!(user, command)
|
|
sudoers = Tempfile.new('vagrant-lxc-sudoers').tap do |file|
|
|
file.puts "# Automatically created by vagrant-lxc"
|
|
file.puts "#{user} ALL=(root) NOPASSWD: #{command}"
|
|
end
|
|
sudoers.close
|
|
sudoers.path
|
|
end
|
|
|
|
def su_copy(files)
|
|
commands = files.map { |file|
|
|
[
|
|
"rm -f #{file[:target]}",
|
|
"cp #{file[:source]} #{file[:target]}",
|
|
"chown root:root #{file[:target]}",
|
|
"chmod #{file[:mode]} #{file[:target]}"
|
|
]
|
|
}.flatten
|
|
system "echo \"#{commands.join("; ")}\" | sudo sh"
|
|
end
|
|
|
|
def build_cmd_paths_hash
|
|
{}.tap do |hash|
|
|
%w( which cat mkdir cp chown chmod rm tar chown ip ifconfig brctl ).each do |cmd|
|
|
hash[cmd] = `sudo which #{cmd}`.strip
|
|
end
|
|
hash['lxc_bin'] = Pathname(`sudo which lxc-create`.strip).parent.to_s
|
|
hash['ruby'] = Gem.ruby
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|