Class: DockerSync::SyncStrategy::NativeOsx

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

Instance Method Summary collapse

Methods included from Execution

#fork_exec, #thread_exec, #with_time

Constructor Details

#initialize(sync_name, options) ⇒ NativeOsx

Returns a new instance of NativeOsx.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/docker-sync/sync_strategy/native_osx.rb', line 19

def initialize(sync_name, options)
  @options = options
  @sync_name = sync_name
  # if a custom image is set, apply it
  if @options.key?('image')
    @docker_image = @options['image']
  else
    @docker_image = 'eugenmayer/unison:2.51.2.0'
  end

  # TODO: remove this when we have a more stable image, but for now, we need this
  uc = UpdateChecker.new
  uc.check_unison_image

  begin
    Dependencies::Docker.ensure!
  rescue StandardError => e
    say_status 'error', "#{@sync_name} has been configured to sync with native docker volume, but docker is not found", :red
    say_status 'error', e.message, :red
    exit 1
  end
end

Instance Method Details

#cleanObject



132
133
134
# File 'lib/docker-sync/sync_strategy/native_osx.rb', line 132

def clean
  reset_container
end

#get_container_nameObject



146
147
148
# File 'lib/docker-sync/sync_strategy/native_osx.rb', line 146

def get_container_name
  @sync_name.to_s
end

#runObject



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

def run
  start_container
  sync
end

#start_containerObject



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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/docker-sync/sync_strategy/native_osx.rb', line 42

def start_container
  say_status 'ok', "Starting native_osx for sync #{@sync_name}", :white
  container_name = get_container_name
  host_sync_src = File.realpath(@options['src'])
  volume_app_sync_name = @sync_name
  env = {}
  raise 'sync_user is no longer supported, since it is not needed. Use sync_userid only please' if @options.key?('sync_user')

  env['UNISON_SRC'] = '/host_sync'
  env['UNISON_DEST'] = '/app_sync'

  env['UNISON_ARGS'] = ''
  if @options.key?('sync_args')
    sync_args = @options['sync_args']
    sync_args = @options['sync_args'].join(' ') if @options['sync_args'].kind_of?(Array)
    env['UNISON_ARGS'] = sync_args
  end

  ignore_strings = expand_ignore_strings
  env['UNISON_ARGS'] << ' ' << ignore_strings.join(' ')
  env['UNISON_ARGS'] << ' ' << sync_prefer
  env['UNISON_ARGS'] << ' -numericids -auto -batch'
  env['UNISON_WATCH_ARGS'] = '-repeat watch'

  env['MAX_INOTIFY_WATCHES'] = @options['max_inotify_watches'] if @options.key?('max_inotify_watches')
  if @options['sync_userid'] == 'from_host'
    env['OWNER_UID'] = Process.uid
  else
    env['OWNER_UID'] = @options['sync_userid'] if @options.key?('sync_userid')
  end

  monit_options = {
    monit_enable: 'MONIT_ENABLE',
    monit_interval: 'MONIT_INTERVAL',
    monit_high_cpu_cycles: 'MONIT_HIGH_CPU_CYCLES',
  }

  monit_options.each do |key, env_key|
    env[env_key] = @options[key.to_s] if @options.key?(key.to_s)
  end

  host_disk_mount_mode = '' # see https://github.com/moby/moby/pull/31047
  host_disk_mount_mode = ":#{@options['host_disk_mount_mode']}" if @options.key?('host_disk_mount_mode')

  additional_docker_env = env.map{ |key,value| "-e #{key}=\"#{value}\"" }.join(' ')
  running = `docker ps --filter 'status=running' --filter 'name=#{container_name}' --format "{{.Names}}" | 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}" --format "{{.Names}}" | grep '^#{container_name}$'`
    if exists == ''
      say_status 'ok', "creating #{container_name} container", :white if @options['verbose']
      run_privileged = ''
      run_privileged = '--privileged' if @options.key?('max_inotify_watches') #TODO: replace by the minimum capabilities required
      say_status 'ok', 'Starting precopy', :white if @options['verbose']
      # we just run the precopy script and remove the container
      cmd = "docker run --rm -v \"#{volume_app_sync_name}:/app_sync\" -v \"#{host_sync_src}:/host_sync#{host_disk_mount_mode}\" -e HOST_VOLUME=/host_sync -e APP_VOLUME=/app_sync -e TZ=${TZ-`readlink /etc/localtime | sed -e 's,/usr/share/zoneinfo/,,'`} #{additional_docker_env} #{run_privileged} --name #{container_name} #{@docker_image} /usr/local/bin/precopy_appsync"
      say_status 'precopy', cmd, :white if @options['verbose']
      system(cmd) || raise('Precopy failed')
      say_status 'ok', 'Starting container', :white if @options['verbose']
      # this will be run below and start unison, since we did not manipulate CMD
      cmd = "docker run -d -v \"#{volume_app_sync_name}:/app_sync\" -v \"#{host_sync_src}:/host_sync#{host_disk_mount_mode}\" -e HOST_VOLUME=/host_sync -e APP_VOLUME=/app_sync -e TZ=${TZ-`readlink /etc/localtime | sed -e 's,/usr/share/zoneinfo/,,'`} #{additional_docker_env} #{run_privileged} --name #{container_name} #{@docker_image}"
    else
      say_status 'ok', "starting #{container_name} container", :white if @options['verbose']
      cmd = "docker start #{container_name} && docker exec #{container_name} supervisorctl restart unison"
    end
  else
    say_status 'ok', "#{container_name} container still running, restarting unison in container", :blue
    cmd = "docker exec #{container_name} supervisorctl restart unison"
  end
  say_status 'command', cmd, :white if @options['verbose']
  system(cmd) || raise('Start failed')
  say_status 'ok', "starting initial sync of #{container_name}", :white if @options['verbose']
  # wait until container is started, then sync:
  say_status 'success', 'Sync container started', :green
end

#stopObject



136
137
138
139
140
141
142
143
144
# File 'lib/docker-sync/sync_strategy/native_osx.rb', line 136

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

#syncObject



127
128
129
# File 'lib/docker-sync/sync_strategy/native_osx.rb', line 127

def sync
  # nop
end

#watchObject



123
124
125
# File 'lib/docker-sync/sync_strategy/native_osx.rb', line 123

def watch
  # nop
end