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:hostsync_0.3'
  end

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

  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



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

def clean
  reset_container
end

#get_container_nameObject



141
142
143
# File 'lib/docker-sync/sync_strategy/native_osx.rb', line 141

def get_container_name
  @sync_name.to_s
end

#runObject



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

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

  ignore_strings = expand_ignore_strings
  env['UNISON_EXCLUDES'] = ignore_strings.join(' ')

  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

  env['UNISON_SYNC_PREFER'] = sync_prefer
  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



131
132
133
134
135
136
137
138
139
# File 'lib/docker-sync/sync_strategy/native_osx.rb', line 131

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



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

def sync
  # nop
end

#watchObject



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

def watch
  # nop
end