class PmgmtLib::SyncFiles

Attributes

c[R]

Public Class Methods

new(common) click to toggle source
# File lib/syncfiles.rb, line 7
def initialize(common)
  @c = common
end

Public Instance Methods

foreach_static_file() { |static_file_src, entry| ... } click to toggle source
# File lib/syncfiles.rb, line 126
def foreach_static_file()
  env = c.load_env
  Dir.foreach(env.static_file_src) do |entry|
    unless [".", ".."].include?(entry)
      yield env.static_file_src, entry
    end
  end
end
get_dest_path(src, dst) click to toggle source
# File lib/syncfiles.rb, line 53
def get_dest_path(src, dst)
  if dst.nil?
    dst = src
  end
  dst = dst.split(/\//).reverse.drop(1).reverse.join("/")
  if not dst.empty?
    dst = "/w/#{dst}"
  else
    dst = "/w"
  end
end
get_src_volume_mount() click to toggle source
# File lib/syncfiles.rb, line 26
def get_src_volume_mount()
  if is_fswatch_installed
    %W{-v #{src_vol_name}:/w}
  else
    %W{-v #{ENV["PWD"]}:/w}
  end
end
get_volume_mounts() click to toggle source
# File lib/syncfiles.rb, line 34
def get_volume_mounts()
  env = c.load_env
  if env.static_file_dest
    get_src_volume_mount + %W{-v #{output_vol_name}:/w/#{env.static_file_dest}}
  else
    get_src_volume_mount
  end
end
is_fswatch_installed() click to toggle source
# File lib/syncfiles.rb, line 11
def is_fswatch_installed()
  status = c.run %W{which fswatch}
  return status.success?
end
log_file_name() click to toggle source
# File lib/syncfiles.rb, line 43
def log_file_name()
  ".rsync.log"
end
log_message(s) click to toggle source
# File lib/syncfiles.rb, line 47
def log_message(s)
  File.open(log_file_name, "a") do |file|
    file.write s
  end
end
maybe_start_file_syncing() click to toggle source
# File lib/syncfiles.rb, line 180
def maybe_start_file_syncing()
  system_name, _ = Open3.capture2("uname")
  system_name.chomp!
  env = c.load_env
  if env.static_file_src
    c.status "Linking static files..."
    link_static_files
  end
  fswatch_installed = is_fswatch_installed
  if system_name == "Darwin" and not fswatch_installed
    c.error "fswatch is not installed."
    STDERR.puts "File syncing will be extremely slow due to a performance problem in docker.\n" \
      "Installing fswatch is highly recommended. Try:\n\n$ brew install fswatch\n\n"
  end
  if fswatch_installed
    c.status "Starting rsync container..."
    at_exit { stop_rsync_container }
    start_rsync_container
    c.status "Performing initial file sync..."
    perform_initial_sync
    start_watching_sync
    c.status "Watching source files. See log at #{log_file_name}."
  end
end
output_vol_name() click to toggle source
# File lib/syncfiles.rb, line 21
def output_vol_name()
  env = c.load_env
  "#{env.namespace}-out"
end
perform_initial_sync() click to toggle source
# File lib/syncfiles.rb, line 145
def perform_initial_sync()
  env = c.load_env
  env.source_file_paths.each do |src_path|
    # Copying using tar ensures the destination directories will be created.
    c.pipe(
      %W{env COPYFILE_DISABLE=1 tar -c #{src_path}},
      %W{docker cp - #{env.namespace}-rsync:/w}
    )
    rsync_path src_path, nil, false
  end
  if env.static_file_src
    c.pipe(
      %W{env COPYFILE_DISABLE=1 tar -c #{env.static_file_src}},
      %W{docker cp - #{env.namespace}-rsync:/w}
    )
    rsync_path env.static_file_src, nil, false
  end
end
rsync_path(src, dst, log) click to toggle source
# File lib/syncfiles.rb, line 85
def rsync_path(src, dst, log)
  env = c.load_env
  dst = get_dest_path(src, dst)
  rsync_remote_shell = "docker exec -i"
  cmd = %W{
    rsync --blocking-io -azlv --delete -e #{rsync_remote_shell}
      #{src}
      #{env.namespace}-rsync:#{dst}
  }
  if log
    Open3.popen3(*cmd) do |i, o, e, t|
      i.close
      if not t.value.success?
        c.error e.read
        exit t.value.exitstatus
      end
      log_message o.read
    end
  else
    c.run_inline cmd
  end
end
src_vol_name() click to toggle source
# File lib/syncfiles.rb, line 16
def src_vol_name()
  env = c.load_env
  "#{env.namespace}-src"
end
start_rsync_container() click to toggle source
# File lib/syncfiles.rb, line 65
def start_rsync_container()
  env = c.load_env
  c.docker.requires_docker
  c.docker.ensure_image("tjamet/rsync")
  cmd = %W{
    docker run -d
      --name #{env.namespace}-rsync
      -v #{src_vol_name}:/w
  }
  if env.static_file_dest
    cmd += %W{-v #{output_vol_name}:/w/#{env.static_file_dest}}
  end
  c.run_inline cmd + %W{-e DAEMON=docker tjamet/rsync}
end
start_watching_sync() click to toggle source
# File lib/syncfiles.rb, line 164
def start_watching_sync()
  env = c.load_env
  File.open(log_file_name, "w") {} # Create and truncate if exists.
  paths_to_watch = env.source_file_paths
  if env.static_file_src
    paths_to_watch += [env.static_file_src]
  end
  paths_to_watch.each do |src_path|
    thread = Thread.new { watch_path src_path, nil }
    at_exit {
      Process.kill("HUP", thread["pid"])
      thread.join
    }
  end
end
stop_rsync_container() click to toggle source
# File lib/syncfiles.rb, line 80
def stop_rsync_container()
  env = c.load_env
  c.run_inline %W{docker rm -f #{env.namespace}-rsync}
end
watch_path(src, dst) click to toggle source
# File lib/syncfiles.rb, line 135
def watch_path(src, dst)
  Open3.popen3(*%W{fswatch -o #{src}}) do |stdin, stdout, stderr, thread|
    Thread.current["pid"] = thread.pid
    stdin.close
    stdout.each_line do |_|
      rsync_path src, dst, true
    end
  end
end