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
# 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
  @docker_image = @options.key?('image') ? @options['image'] : 'ghcr.io/eugenmayer/unison:2.52.1-4.12.0'

  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



125
126
127
# File 'lib/docker-sync/sync_strategy/native_osx.rb', line 125

def clean
  reset_container
end

#get_container_nameObject



139
140
141
# File 'lib/docker-sync/sync_strategy/native_osx.rb', line 139

def get_container_name
  @sync_name.to_s
end

#runObject



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

def run
  start_container
  sync
end

#start_containerObject



34
35
36
37
38
39
40
41
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
# File 'lib/docker-sync/sync_strategy/native_osx.rb', line 34

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
      tz_expression = '-e TZ=$(basename $(dirname `readlink /etc/localtime`))/$(basename `readlink /etc/localtime`)'
      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 #{tz_expression} #{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 #{tz_expression} #{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



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

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



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

def sync
  # nop
end

#watchObject



116
117
118
# File 'lib/docker-sync/sync_strategy/native_osx.rb', line 116

def watch
  # nop
end