Class: Vader::Sync
- Inherits:
-
Object
- Object
- Vader::Sync
- Defined in:
- lib/vader/sync.rb
Constant Summary collapse
- B2D_BIN =
'/usr/local/bin/boot2docker'- B2D_ROOT =
ENV['VADER_B2D_ROOT'] || "/vader"
- CONFIG_DIR =
File.(ENV['VADER_CONFIG_DIR'] || '~/.vader')
- SYNC_LATENCY =
(ENV['VADER_SYNC_LATENCY'] || 0.1).to_f
Instance Attribute Summary collapse
-
#local_watch_paths ⇒ Object
readonly
Array of local paths.
-
#watch_paths ⇒ Object
readonly
Hash of local paths and boot2docker destination.
Instance Method Summary collapse
- #boot2docker_config ⇒ Object
- #boot2docker_ssh_host ⇒ Object
- #boot2docker_ssh_options ⇒ Object
- #handle_fs_event(full_paths) ⇒ Object
-
#initialize ⇒ Sync
constructor
A new instance of Sync.
- #run ⇒ Object
- #sync(path) ⇒ Object
- #verbose? ⇒ Boolean
Constructor Details
#initialize ⇒ Sync
Returns a new instance of Sync.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/vader/sync.rb', line 14 def initialize glob = File.join(CONFIG_DIR, '*') # A hash of paths to watch and their boot2docker destinations # E.g. # { '/Users/alice/Documents/my-project' => '/vader/my-project' } @watch_paths = Dir.glob(glob).inject({}) { |hash, config_path| b2d_path = File.join(B2D_ROOT, File.basename(config_path)) begin watch_path = File.readlink(config_path) hash.merge(watch_path => b2d_path) rescue Errno::EINVAL hash end } @local_watch_paths = @watch_paths.keys end |
Instance Attribute Details
#local_watch_paths ⇒ Object (readonly)
Array of local paths
12 13 14 |
# File 'lib/vader/sync.rb', line 12 def local_watch_paths @local_watch_paths end |
#watch_paths ⇒ Object (readonly)
Hash of local paths and boot2docker destination
10 11 12 |
# File 'lib/vader/sync.rb', line 10 def watch_paths @watch_paths end |
Instance Method Details
#boot2docker_config ⇒ Object
140 141 142 143 144 145 146 147 148 149 |
# File 'lib/vader/sync.rb', line 140 def boot2docker_config @boot2docker_config ||= `#{B2D_BIN} config`.split("\n").inject({}) {|hash, line| match = line.match(/(?<key>\S+)\s=\s"?(?<value>[^\s"]+)"?/) if match hash.merge(match[:key] => match[:value]) else hash end } end |
#boot2docker_ssh_host ⇒ Object
163 164 165 |
# File 'lib/vader/sync.rb', line 163 def boot2docker_ssh_host "docker@localhost" end |
#boot2docker_ssh_options ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/vader/sync.rb', line 151 def # From http://git.io/vJhs2 [ "-o", "IdentitiesOnly=yes", "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", "-o", "LogLevel=quiet", "-p", boot2docker_config['SSHPort'], "-i", boot2docker_config['SSHKey'] ].join(' ') end |
#handle_fs_event(full_paths) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/vader/sync.rb', line 81 def handle_fs_event(full_paths) puts "handling event for #{full_paths.inspect}" if verbose? # full_paths is potentially large, so try to iterated efficiently matched_paths = [] full_paths.each do |full_path| # Skip if we've already mathed this path next if matched_paths.any? {|p| full_path.start_with?(p) } matched_path = local_watch_paths.detect{|p| full_path.start_with?(p) } matched_paths << matched_path if matched_path if full_path.start_with? CONFIG_DIR puts "Vader config change detected, restarting." exit 0 end end matched_paths.each {|path| sync(path) } end |
#run ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/vader/sync.rb', line 35 def run # Make sure boot2docker is running waiting = false while `#{B2D_BIN} status`.chomp != 'running' puts "Waiting until boot2docker is running" unless waiting waiting = true sleep 2 end # Initialize boot2docker for vader cmds = [ 'tce-load -wi rsync', # Install rsync # Make vader destination and symlink to /vader 'sudo mkdir -p /mnt/sda1/vader', 'sudo ln -sf /mnt/sda1/vader /', 'sudo chown docker:staff /vader' ] safe_paths = @watch_paths.values.map{|path| Shellwords.shellescape(path)}.join(' ') cmds << "mkdir -p #{safe_paths}" unless safe_paths.empty? cmds = cmds.join(' && ') puts "Running #{cmds}" if verbose? `ssh #{} #{boot2docker_ssh_host} "#{cmds}"` unless $?.success? puts "Error initalizing boot2docker for vader" exit 1 end # Do initial sync of each local watch path local_watch_paths.each do |path| puts "Doing initial sync of #{path}" sync(path) end # Watch for fs changes puts "Watching #{local_watch_paths.inspect} + #{CONFIG_DIR}" if verbose? fsevent = FSEvent.new fsevent.watch local_watch_paths + [CONFIG_DIR], latency: SYNC_LATENCY do |paths| handle_fs_event(paths) end fsevent.run end |
#sync(path) ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/vader/sync.rb', line 102 def sync(path) puts "Syncing #{path}" exclude_path = File.join(path, '.rsync-excludes') = [ '-av', '--delete', "--rsh=ssh #{}" ] if File.exists?(exclude_path) << "--exclude-from=#{exclude_path}" end += [ "#{path}/", "#{boot2docker_ssh_host}:#{watch_paths[path]}" ] puts .inspect if verbose? = verbose? ? {} : {out: '/dev/null'} start = Time.now pid = spawn("rsync", *, ) Process.wait(pid) puts "Finished in #{Time.now - start} seconds" if verbose? unless $?.success? puts "Error syncing #{path}, restarting." exit 1 end end |
#verbose? ⇒ Boolean
136 137 138 |
# File 'lib/vader/sync.rb', line 136 def verbose? ENV['VADER_VERBOSE'] end |