From 8590c87132042919de72980b2b0d0797d5ebd7db Mon Sep 17 00:00:00 2001 From: Jef Mathiot Date: Sun, 16 Mar 2014 18:59:18 +0100 Subject: [PATCH] Created an "lxc sudoers" command to create sudoers file for a given user (defaults to current one). --- Vagrantfile | 5 ++ lib/vagrant-lxc/command/root.rb | 57 ++++++++++++++++++++ lib/vagrant-lxc/command/sudoers.rb | 83 ++++++++++++++++++++++++++++++ lib/vagrant-lxc/plugin.rb | 5 ++ 4 files changed, 150 insertions(+) create mode 100644 Vagrantfile create mode 100644 lib/vagrant-lxc/command/root.rb create mode 100644 lib/vagrant-lxc/command/sudoers.rb diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..9d29377 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,5 @@ +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + Vagrant.require_plugin "vagrant-lxc" +end diff --git a/lib/vagrant-lxc/command/root.rb b/lib/vagrant-lxc/command/root.rb new file mode 100644 index 0000000..278d663 --- /dev/null +++ b/lib/vagrant-lxc/command/root.rb @@ -0,0 +1,57 @@ +module Vagrant + module LXC + module Command + class Root < Vagrant.plugin("2", :command) + def self.synopsis + 'LXC setup' + end + + def initialize(argv, env) + @args, @sub_command, @sub_args = split_main_and_subcommand(argv) + @subcommands = Vagrant::Registry.new.tap do |registry| + registry.register(:sudoers) do + require_relative 'sudoers' + Sudoers + end + end + super(argv, env) + end + + def execute + # Print the help + return help if @args.include?("-h") || @args.include?("--help") + + klazz = @subcommands.get(@sub_command.to_sym) if @sub_command + return help unless klazz + + @logger.debug("Executing command: #{klazz} #{@sub_args.inspect}") + + # Initialize and execute the command class + klazz.new(@sub_args, @env).execute + end + + def help + opts = OptionParser.new do |opts| + opts.banner = "Usage: vagrant lxc []" + opts.separator "" + opts.separator "Available subcommands:" + + # https://github.com/mitchellh/vagrant/commit/4194da19c60956f6e59239c0145f772be257e79d + keys = [] + @subcommands.each { |key, value| keys << key } + + keys.sort.each do |key| + opts.separator " #{key}" + end + + opts.separator "" + opts.separator "For help on any individual subcommand run `vagrant lxc -h`" + end + + @env.ui.info(opts.help, :prefix => false) + end + + end + end + end +end diff --git a/lib/vagrant-lxc/command/sudoers.rb b/lib/vagrant-lxc/command/sudoers.rb new file mode 100644 index 0000000..4ae57b1 --- /dev/null +++ b/lib/vagrant-lxc/command/sudoers.rb @@ -0,0 +1,83 @@ +require 'tempfile' + +module Vagrant + module LXC + module Command + class Sudoers < Vagrant.plugin("2", :command) + + def execute + options = { :user => ENV['USER'] } + + opts = OptionParser.new do |opts| + opts.banner = "Usage: vagrant lxc sudoers" + opts.separator "" + opts.on('-u', '--user', "The user for which to create the policy") do |u| + options[:user]=u + end + end + + argv = parse_options(opts) + return unless argv + + filename = "vagrant-lxc-#{options[:user]}" + to_sudoers!(create_tempfile!(options[:user], filename), filename) + end + + private + def create_tempfile!(user, filename) + sudoers = Tempfile.new(filename).tap do |file| + file.write "# Automatically created by vagrant-lxc\n" + commands.each do |command| + file.write sudoers_policy(user, command[:cmd], command[:args]) + end + end + sudoers.close + File.chmod(0644, sudoers.path) + sudoers.path + end + + def to_sudoers!(source, destination) + destination = "/etc/sudoers.d/#{destination}" + commands = [ + "rm -f #{destination}", + "cp #{source} #{destination}", + "chmod 440 #{destination}" + ] + `echo "#{commands.join('; ')}" | sudo sh` + end + + def sudoers_policy(user, command, args) + home = `echo ~#{user}`.chomp + args = args.gsub /\$\{BOXES\}/, "#{home}/.vagrant.d/boxes" + "#{user} ALL=(root) NOPASSWD: #{command} #{args}\n" + end + + def commands + [ + { :cmd => '/usr/bin/lxc-ls', :args => '' }, + { :cmd => '/usr/bin/lxc-info', :args => '' }, + { :cmd => '/usr/bin/lxc-attach', :args => '' }, + { :cmd => '/usr/bin/which', :args => 'lxc-*' }, + { :cmd => '/bin/cat', :args => '/var/lib/lxc/*' }, + { :cmd => '/bin/mkdir', :args => '/var/lib/lxc/*' }, + { :cmd => '/bin/su', :args => "root -c sed -e '*' -ibak /var/lib/lxc/*" }, + { :cmd => '/bin/su', :args => "root -c echo '*' >> /var/lib/lxc/*" }, + { :cmd => '/usr/bin/lxc-start', :args => '-d --name *' }, + { :cmd => '/bin/cp', :args => '${BOXES}/*/lxc/lxc-template /usr/lib/lxc/templates/*' }, + { :cmd => '/bin/cp', :args => '${BOXES}/*/lxc/lxc-template /usr/share/lxc/templates/*' }, + { :cmd => '/bin/rm', :args => '/usr/lib/lxc/templates/*' }, + { :cmd => '/bin/rm', :args => '/usr/share/lxc/templates/*' }, + { :cmd => '/bin/chmod', :args => '+x /usr/lib/lxc/*' }, + { :cmd => '/bin/chmod', :args => '+x /usr/share/lxc/*' }, + { :cmd => '/usr/bin/lxc-create', :args => '--template * --name * -- --tarball ${BOXES}/*' }, + { :cmd => '/bin/rm', :args => '-rf /var/lib/lxc/*/rootfs/tmp/*' }, + { :cmd => '/usr/bin/lxc-shutdown', :args => '--name *' }, + { :cmd => '/usr/bin/lxc-stop', :args => '--name *' }, + { :cmd => '/usr/bin/lxc-destroy', :args => '--name *' } + ] + end + + end + end + end +end diff --git a/lib/vagrant-lxc/plugin.rb b/lib/vagrant-lxc/plugin.rb index 801c927..a09f919 100644 --- a/lib/vagrant-lxc/plugin.rb +++ b/lib/vagrant-lxc/plugin.rb @@ -9,6 +9,11 @@ module Vagrant LXC-based virtual machines. EOF + command "lxc" do + require_relative 'command/root' + Command::Root + end + provider(:lxc, parallel: true) do require File.expand_path("../provider", __FILE__)