Class: Docker_Sync::SyncStrategy::Unison

Inherits:
Object
  • Object
show all
Includes:
Preconditions, Thor::Shell
Defined in:
lib/docker_sync/sync_strategy/unison.rb

Constant Summary collapse

UNISON_IMAGE =
'leighmcculloch/unison'
UNISON_VERSION =
'2.48.3'
UNISON_CONTAINER_PORT =
'5000'

Instance Method Summary collapse

Methods included from Preconditions

#check_all_preconditions, #docker_available, #docker_running, #docker_sync_available, #fswatch_available, #rsync_available, #unison_available

Constructor Details

#initialize(sync_name, options) ⇒ Unison

Returns a new instance of Unison.



18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/docker_sync/sync_strategy/unison.rb', line 18

def initialize(sync_name, options)
  @sync_name = sync_name
  @options = options

  begin
    unison_available
  rescue Exception => e
    say_status 'error', "#{@sync_name} has been configured to sync with unison, but no unison available", :red
    say_status 'error', e.message, :red
    exit 1
  end
end

Instance Method Details

#cleanObject



118
119
120
# File 'lib/docker_sync/sync_strategy/unison.rb', line 118

def clean
  reset_container
end

#get_container_nameObject



100
101
102
# File 'lib/docker_sync/sync_strategy/unison.rb', line 100

def get_container_name
  return "#{@sync_name}"
end

#get_volume_nameObject



104
105
106
# File 'lib/docker_sync/sync_strategy/unison.rb', line 104

def get_volume_name
  return @sync_name
end

#reset_containerObject



112
113
114
115
116
# File 'lib/docker_sync/sync_strategy/unison.rb', line 112

def reset_container
  stop_container
  `docker rm #{get_container_name}`
  `docker volume rm #{get_volume_name}`
end

#runObject



31
32
33
34
# File 'lib/docker_sync/sync_strategy/unison.rb', line 31

def run
  start_container
  sync
end

#start_containerObject



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/docker_sync/sync_strategy/unison.rb', line 72

def start_container
  say_status 'ok', 'Starting unison', :white
  container_name = get_container_name
  volume_name = get_volume_name

  running = `docker ps --filter 'status=running' --filter 'name=#{container_name}' | grep #{container_name}`
  if running == ''
    say_status 'ok', "#{container_name} container not running", :white if @options['verbose']
    exists = `docker ps --filter "status=exited" --filter "name=#{container_name}" | grep #{container_name}`
    if exists == ''
      say_status 'ok', "creating #{container_name} container", :white if @options['verbose']
      cmd = "docker run -p '#{@options['sync_host_port']}:#{UNISON_CONTAINER_PORT}' -v #{volume_name}:#{@options['dest']} -e UNISON_VERSION=#{UNISON_VERSION} -e UNISON_WORKING_DIR=#{@options['dest']} --name #{container_name} -d #{UNISON_IMAGE}"
    else
      say_status 'ok', "starting #{container_name} container", :white if @options['verbose']
      cmd = "docker start #{container_name}"
    end
    say_status 'command', cmd, :white if @options['verbose']
    `#{cmd}` || raise('Start failed')
  else
    say_status 'ok', "#{container_name} container still running", :blue
  end
  say_status 'ok', "starting initial #{container_name} of src", :white if @options['verbose']
  # this sleep is needed since the container could be not started
  sleep 1
  sync
  say_status 'success', 'Unison server started', :green
end

#stopObject



122
123
124
125
126
127
128
129
130
# File 'lib/docker_sync/sync_strategy/unison.rb', line 122

def stop
  say_status 'ok', "Stopping sync container #{get_container_name}"
  begin
    stop_container
  rescue Exception => e
    say_status 'error', "Stopping failed of #{get_container_name}:", :red
    puts e.message
  end
end

#stop_containerObject



108
109
110
# File 'lib/docker_sync/sync_strategy/unison.rb', line 108

def stop_container
  `docker stop #{get_container_name}`
end

#syncObject



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/docker_sync/sync_strategy/unison.rb', line 36

def sync
  args = sync_options
  cmd = 'unison ' + args.join(' ')

  say_status 'command', cmd, :white if @options['verbose']

  stdout, stderr, exit_status = Open3.capture3(cmd)
  if not exit_status.success?
    say_status 'error', "Error starting sync, exit code #{$?.exitstatus}", :red
    say_status 'message', stderr
  else
    say_status 'ok', "Synced #{@options['src']}", :white
    if @options['verbose']
      say_status 'output', stdout
    end
  end
end

#sync_optionsObject



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/docker_sync/sync_strategy/unison.rb', line 54

def sync_options
  args = []

  unless @options['sync_excludes'].nil?
    args = @options['sync_excludes'].map { |pattern| "-ignore='Path #{pattern}'" } + args
  end
  args.push(@options['src'])
  args.push('-auto')
  args.push('-batch')
  args.push(@options['sync_args']) if @options.key?('sync_args')
  args.push("socket://#{@options['sync_host_ip']}:#{@options['sync_host_port']}/")
  args.push('-debug verbose') if @options['verbose']
  if @options.key?('sync_user') || @options.key?('sync_group') || @options.key?('sync_groupid') || @options.key?('sync_userid')
    raise('Unison does not support sync_user, sync_group, sync_groupid or sync_userid - please use rsync if you need that')
  end
  return args
end