From ce6d95c13114720b904ec5911c191bb2c5a7112e Mon Sep 17 00:00:00 2001 From: John Bender Date: Tue, 18 May 2010 01:24:59 -0700 Subject: [PATCH] rsync mostly complete, few tests left --- config/default.rb | 5 +++ lib/vagrant/actions/vm/shared_folders.rb | 13 ++++-- lib/vagrant/config.rb | 5 +++ lib/vagrant/systems/linux.rb | 37 ++++++++++++++- templates/crontab-entry.erb | 1 + templates/rsync.erb | 14 ++++++ .../vagrant/actions/vm/shared_folders_test.rb | 45 +++++++++++++++---- test/vagrant/config_test.rb | 7 ++- vagrant.gemspec | 3 +- 9 files changed, 114 insertions(+), 16 deletions(-) create mode 100644 templates/crontab-entry.erb create mode 100644 templates/rsync.erb diff --git a/config/default.rb b/config/default.rb index f9cd934e9..51143d93c 100644 --- a/config/default.rb +++ b/config/default.rb @@ -24,6 +24,11 @@ Vagrant::Config.run do |config| config.vm.boot_mode = "vrdp" config.vm.system = :linux + # TODO new config class + config.vm.rsync_opts = "-ur --delete" + config.vm.rsync_script = "/tmp/rsync" + config.vm.rsync_crontab_entry_file = "/tmp/crontab-entry" + config.package.name = 'vagrant' config.package.extension = '.box' end diff --git a/lib/vagrant/actions/vm/shared_folders.rb b/lib/vagrant/actions/vm/shared_folders.rb index 2945743d8..e6bcd1e7d 100644 --- a/lib/vagrant/actions/vm/shared_folders.rb +++ b/lib/vagrant/actions/vm/shared_folders.rb @@ -5,7 +5,7 @@ module Vagrant def shared_folders @runner.env.config.vm.shared_folders.inject([]) do |acc, data| name, value = data - acc << [name, File.expand_path(value[:hostpath]), value[:guestpath]] + acc << [name, File.expand_path(value[:hostpath]), value[:guestpath], value[:rsyncpath]].compact end end @@ -18,9 +18,14 @@ module Vagrant logger.info "Mounting shared folders..." @runner.ssh.execute do |ssh| - shared_folders.each do |name, hostpath, guestpath| - logger.info "-- #{name}: #{guestpath}" + @runner.system.prepare_rsync(ssh) if @runner.env.config.vm.rsync_required + + shared_folders.each do |name, hostpath, guestpath, rsyncpath| + logger.info "-- #{name}: #{rsyncpath ? guestpath + " -rsync-> " + rsyncpath : guestpath}" @runner.system.mount_shared_folder(ssh, name, guestpath) + if rsyncpath + @runner.system.create_rsync(ssh, :rsyncpath => rsyncpath, :guestpath => guestpath) + end end end end @@ -50,4 +55,4 @@ module Vagrant end end end -end \ No newline at end of file +end diff --git a/lib/vagrant/config.rb b/lib/vagrant/config.rb index da8829a34..ac22ab9dc 100644 --- a/lib/vagrant/config.rb +++ b/lib/vagrant/config.rb @@ -82,6 +82,10 @@ module Vagrant attr_accessor :boot_mode attr_accessor :project_directory attr_accessor :rsync_project_directory + attr_accessor :rsync_opts + attr_accessor :rsync_script + attr_accessor :rsync_crontab_entry_file + attr_reader :rsync_required attr_reader :forwarded_ports attr_reader :shared_folders attr_accessor :hd_location @@ -151,6 +155,7 @@ module Vagrant def shift(orig, rsync) if rsync + @rsync_required = true [orig + '-rsync', rsync == true ? orig : rsync] else [orig, rsync] diff --git a/lib/vagrant/systems/linux.rb b/lib/vagrant/systems/linux.rb index cf6fdc46c..b553ca933 100644 --- a/lib/vagrant/systems/linux.rb +++ b/lib/vagrant/systems/linux.rb @@ -49,7 +49,24 @@ module Vagrant def mount_shared_folder(ssh, name, guestpath) ssh.exec!("sudo mkdir -p #{guestpath}") mount_folder(ssh, name, guestpath) - ssh.exec!("sudo chown #{vm.env.config.ssh.username} #{guestpath}") + chown(ssh, guestpath) + end + + def create_rsync(ssh, opts) + crontab_entry = render_crontab_entry(opts.merge(:rsyncopts => config.vm.rsync_opts, + :scriptname => config.vm.rsync_script)) + + ssh.exec!("sudo mkdir -p #{opts[:rsyncpath]}") + ssh.exec!("sudo chmod +x #{config.vm.rsync_script}") + ssh.exec!("sudo echo \"#{crontab_entry}\" >> #{config.vm.rsync_crontab_entry_file}") + ssh.exec!("crontab #{config.vm.rsync_crontab_entry_file}") + chown(ssh, opts[:rsyncpath]) + end + + def prepare_rsync(ssh) + logger.info "Preparing system for rsync..." + vm.env.ssh.upload!(StringIO.new(render_rsync), config.vm.rsync_script) + ssh.exec!('sudo rm #{config.vm.rsync_crontab_entry_file}') end #------------------------------------------------------------------- @@ -76,6 +93,22 @@ module Vagrant sleep sleeptime end end + + def chown(ssh, dir) + ssh.exec!("sudo chown #{config.ssh.username} #{dir}") + end + + def config + vm.env.config + end + + def render_rsync + TemplateRenderer.render('rsync') + end + + def render_crontab_entry(opts) + TemplateRenderer.render('crontab-entry', opts) + end end end -end \ No newline at end of file +end diff --git a/templates/crontab-entry.erb b/templates/crontab-entry.erb new file mode 100644 index 000000000..ac0ae246d --- /dev/null +++ b/templates/crontab-entry.erb @@ -0,0 +1 @@ +* * * * * <%= scriptname %> '<%= rsyncopts %>' '<%= guestpath %>/*' '<%= rsyncpath %>/' diff --git a/templates/rsync.erb b/templates/rsync.erb new file mode 100644 index 000000000..7b5109121 --- /dev/null +++ b/templates/rsync.erb @@ -0,0 +1,14 @@ +#!/bin/sh +TIMESTART=`date +%s` +while [ 1 ] +do + echo 'Syncing...' + rsync $1 $2 $3 + TIME=$((`date +%s`-$TIMESTART)) + echo $TIME + if [ $TIME -ge 50 ] + then + break + fi + sleep 1 +done diff --git a/test/vagrant/actions/vm/shared_folders_test.rb b/test/vagrant/actions/vm/shared_folders_test.rb index 4d7871ba4..ae478f6ca 100644 --- a/test/vagrant/actions/vm/shared_folders_test.rb +++ b/test/vagrant/actions/vm/shared_folders_test.rb @@ -27,12 +27,7 @@ class SharedFoldersActionTest < Test::Unit::TestCase end should "convert the vagrant config values into an array" do - env = mock_environment do |config| - config.vm.shared_folders.clear - config.vm.share_folder("foo", "bar", "baz") - end - - @runner.expects(:env).returns(env) + mock_env_shared_folders result = [["foo", "baz", "bar"]] assert_equal result, @action.shared_folders @@ -51,6 +46,23 @@ class SharedFoldersActionTest < Test::Unit::TestCase result = [["foo", "expanded_baz", "bar"]] assert_equal result, @action.shared_folders end + + context "with rsync" do + should "append the rsync value to the other config values" do + mock_env_shared_folders(:rsync => true) + + assert_equal [["foo", "baz", "bar-rsync", "bar"]], @action.shared_folders + end + end + + def mock_env_shared_folders(opts={}) + env = mock_environment do |config| + config.vm.shared_folders.clear + config.vm.share_folder("foo", "bar", "baz", opts) + end + + @runner.expects(:env).returns(env) + end end context "clearing shared folders" do @@ -91,17 +103,34 @@ class SharedFoldersActionTest < Test::Unit::TestCase context "mounting the shared folders" do setup do @folders = stub_shared_folders + @ssh = mock("ssh") + @runner.env.ssh.stubs(:execute).yields(@ssh) + @runner.system.stubs(:mount_shared_folder) end should "mount all shared folders to the VM" do mount_seq = sequence("mount_seq") - ssh = mock("ssh") @folders.each do |name, hostpath, guestpath| - @runner.system.expects(:mount_shared_folder).with(ssh, name, guestpath).in_sequence(mount_seq) + @runner.system.expects(:mount_shared_folder).with(@ssh, name, guestpath).in_sequence(mount_seq) + end + + @action.after_boot + end + + should "execute the necessary rysnc commands for each rsync folder" do + @folders.map { |f| f << 'rsync' } + @folders.each do |name, hostpath, guestpath, rsyncd| + @runner.system.expects(:create_rsync).with(@ssh, :rsyncpath => rsyncd, :guestpath => guestpath) end @runner.ssh.expects(:execute).yields(ssh) @action.after_boot end end + + context "with rsyncd folders" do + # TODO + should "prepare the system for rsync if necessary" do + end + end end diff --git a/test/vagrant/config_test.rb b/test/vagrant/config_test.rb index 3fa56aabe..a9f34ea9a 100644 --- a/test/vagrant/config_test.rb +++ b/test/vagrant/config_test.rb @@ -257,7 +257,7 @@ class ConfigTest < Test::Unit::TestCase end end - context "shared folders" do + context "rsyncd folders" do should "set the rsyncpath to nil by default" do share_with_opts assert !@config.shared_folders['foo'][:rsyncpath] @@ -280,6 +280,11 @@ class ConfigTest < Test::Unit::TestCase end end + should "set the rsync required flag to true" do + share_with_opts(:rsync => true) + assert @config.rsync_required + end + def share_with_opts(opts={}) @config.share_folder('foo', 'foo-dir', '', opts) end diff --git a/vagrant.gemspec b/vagrant.gemspec index 91a3b6c95..e609fda4c 100644 --- a/vagrant.gemspec +++ b/vagrant.gemspec @@ -101,7 +101,9 @@ Gem::Specification.new do |s| "templates/Vagrantfile.erb", "templates/chef_server_client.erb", "templates/chef_solo_solo.erb", + "templates/crontab-entry.erb", "templates/package_Vagrantfile.erb", + "templates/rsync.erb", "templates/ssh_config.erb", "templates/strings.yml", "test/test_helper.rb", @@ -229,7 +231,6 @@ Gem::Specification.new do |s| "test/vagrant/commands/resume_test.rb", "test/vagrant/commands/ssh_test.rb", "test/vagrant/downloaders/base_test.rb", - "test/vagrant/downloaders/file_test.rb", "test/vagrant/downloaders/http_test.rb", "test/vagrant/util/stacked_proc_runner_test.rb", "test/vagrant/util/progress_meter_test.rb",