Class: Docker_Sync::SyncStrategy::Unison

Inherits:
Object
  • Object
show all
Includes:
Thor::Shell
Defined in:
lib/docker-sync/sync_strategy/unison.rb

Constant Summary collapse

UNISON_CONTAINER_PORT =
'5000'

Instance Method Summary collapse

Constructor Details

#initialize(sync_name, options) ⇒ Unison

Returns a new instance of Unison.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/docker-sync/sync_strategy/unison.rb', line 14

def initialize(sync_name, options)
  @sync_name = sync_name
  @options = options
  # if a custom image is set, apply it
  if @options.key?('image')
    @docker_image = @options['image']
  else
    @docker_image = 'eugenmayer/unison'
  end
  begin
    Preconditions::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



119
120
121
# File 'lib/docker-sync/sync_strategy/unison.rb', line 119

def clean
  reset_container
end

#get_container_nameObject



101
102
103
# File 'lib/docker-sync/sync_strategy/unison.rb', line 101

def get_container_name
  return "#{@sync_name}"
end

#get_volume_nameObject



105
106
107
# File 'lib/docker-sync/sync_strategy/unison.rb', line 105

def get_volume_name
  return @sync_name
end

#reset_containerObject



113
114
115
116
117
# File 'lib/docker-sync/sync_strategy/unison.rb', line 113

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

#runObject



32
33
34
35
# File 'lib/docker-sync/sync_strategy/unison.rb', line 32

def run
  start_container
  sync
end

#start_containerObject



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
99
# File 'lib/docker-sync/sync_strategy/unison.rb', line 73

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_DIR=#{@options['dest']} --name #{container_name} -d #{@docker_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



123
124
125
126
127
128
129
130
131
# File 'lib/docker-sync/sync_strategy/unison.rb', line 123

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



109
110
111
# File 'lib/docker-sync/sync_strategy/unison.rb', line 109

def stop_container
  `docker stop #{get_container_name}`
end

#syncObject



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

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



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

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 all') 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