Module: Mcrain::DockerMachine

Defined in:
lib/mcrain/docker_machine.rb

Constant Summary collapse

DEFAULT_HOSTNAME =
'docker-host1'.freeze
DOCKER_MACHINE_DOCKER_HOME =
'/home/docker'.freeze

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.certs_dirObject

Returns the value of attribute certs_dir.



18
19
20
# File 'lib/mcrain/docker_machine.rb', line 18

def certs_dir
  @certs_dir
end

Class Method Details

.build_docker_options(uri) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/mcrain/docker_machine.rb', line 70

def build_docker_options(uri)
  d = DockerMachine.certs_dir
  cert_path = File.join(d, "cert.pem")
  key_path = File.join(d, "key.pem")
  files = {
    ".docker/cert.pem" => cert_path,
    ".docker/key.pem" => key_path,
  }
  download_files_from_vm(uri.host, files)
  return {
    client_cert: cert_path,
    client_key: key_path,
    scheme: 'https',
  }
end

.cp_r(src, dest) ⇒ Object



170
171
172
# File 'lib/mcrain/docker_machine.rb', line 170

def cp_r(src, dest)
  used? ? cp_r_remote(src, dest) : cp_r_local(src, dest)
end

.cp_r_local(src, dest) ⇒ Object



191
192
193
# File 'lib/mcrain/docker_machine.rb', line 191

def cp_r_local(src, dest)
  FileUtils.cp_r(src, dest)
end

.cp_r_remote(src, dest) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/mcrain/docker_machine.rb', line 174

def cp_r_remote(src, dest)
  Dir.mktmpdir("for_tarball") do |dir|
    tarball_name = "#{File.basename(src)}.tar.gz"
    FileUtils.chdir(dir) do
      FileUtils.cp_r(src, ".")
      unless system("tar zcf #{tarball_name} #{File.basename(src)}")
        raise "failed to create tarball of #{src} to #{dir}"
      end
    end
    host = URI.parse(ENV["DOCKER_HOST"]).host
    scp_connect(host) do |scp|
      scp.upload!(File.join(dir, tarball_name), dest)
      scp.session.exec!("cd #{dest} && tar zxf #{tarball_name}")
    end
  end
end

.docker_hostnameObject



24
25
26
# File 'lib/mcrain/docker_machine.rb', line 24

def docker_hostname
  ENV['MCRAIN_DOCKER_HOSTNAME'] || DEFAULT_HOSTNAME
end

.docker_hostname!Object



28
29
30
31
32
# File 'lib/mcrain/docker_machine.rb', line 28

def docker_hostname!
  name = docker_hostname
  return name if valid_docker_hostname?
  raise "hostname: #{name.inspect} is not valid. Plase set it with docker IP address to /etc/hosts or export MCRAIN_DOCKER_HOSTNAME=(valid-hostname) ."
end

.docker_machine_nameObject



20
21
22
# File 'lib/mcrain/docker_machine.rb', line 20

def docker_machine_name
  ENV['DOCKER_MACHINE_NAME']
end

.download_files_from_vm(host, files) ⇒ Object



91
92
93
94
95
96
97
98
99
# File 'lib/mcrain/docker_machine.rb', line 91

def download_files_from_vm(host, files)
  return if files.values.all?{|f| File.readable?(f)}
  files.values.each{|f| FileUtils.mkdir_p(File.dirname(f))}
  scp_connect(host) do |scp|
    files.each do |src, dest|
      scp.download(src, dest)
    end
  end
end

.mktmpdir(&block) ⇒ Object



120
121
122
# File 'lib/mcrain/docker_machine.rb', line 120

def mktmpdir(&block)
  used? ? mktmpdir_ssh(&block) : mktmpdir_local(&block)
end

.mktmpdir_local(*args) ⇒ Object



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/mcrain/docker_machine.rb', line 153

def mktmpdir_local(*args)
  r = Dir.mktmpdir(*args)
  if block_given?
    begin
      yield(r)
    ensure
      Mcrain.logger.debug("removing #{r}")
      begin
        FileUtils.remove_entry_secure(r, true)
      rescue => e
        Mcrain.logger.warn("[#{e.class}] #{e.message}")
      end
    end
  end
  return r
end

.mktmpdir_remote(ssh, &block) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/mcrain/docker_machine.rb', line 130

def mktmpdir_remote(ssh, &block)
  Dir.mktmpdir do |orig_dir|
    dir = File.join(DOCKER_MACHINE_DOCKER_HOME, 'tmp', orig_dir)
    cmd1 = "mkdir -p #{dir}"
    Mcrain.logger.debug(cmd1)
    ssh.exec! cmd1
    if block_given?
      begin
        yield(dir)
      ensure
        begin
          cmd2 = "rm -rf #{dir}"
          Mcrain.logger.debug(cmd2)
          ssh.exec! cmd2
        rescue => e
          Mcrain.logger.warn("[#{e.class}] #{e.message}")
        end
      end
    end
    return dir
  end
end

.mktmpdir_ssh(&block) ⇒ Object



124
125
126
127
128
# File 'lib/mcrain/docker_machine.rb', line 124

def mktmpdir_ssh(&block)
  ssh_to_vm do |ssh|
    return mktmpdir_remote(ssh, &block)
  end
end

.preparing_commandObject



48
49
50
51
52
53
54
55
56
57
# File 'lib/mcrain/docker_machine.rb', line 48

def preparing_command
  return "" unless used?
  name = Mcrain::DockerMachine.docker_machine_name
  unless `docker-machine status #{name}`.strip.downcase == "running"
    raise "docker-machine #{name} is not running. Please `docker-machine start #{name}`"
  end
  exports = `docker-machine env #{name} 2>/dev/null`.strip.split(/\n/).
    select{|line| line =~ /\Aexport /}
  exports.empty? ? '' : "%s && " % exports.join(" && ")
end

.scp_connect(host, &block) ⇒ Object



101
102
103
# File 'lib/mcrain/docker_machine.rb', line 101

def scp_connect(host, &block)
  Net::SCP.start(host, "docker", :password => "tcuser", &block)
end

.setup_docker_optionsObject



59
60
61
62
63
64
65
66
67
68
# File 'lib/mcrain/docker_machine.rb', line 59

def setup_docker_options
  if used?
    require 'docker'
    uri = URI.parse(ENV["DOCKER_HOST"])
    Excon.defaults[:ssl_verify_peer] = false
    Docker.options = build_docker_options(uri)
  elsif ENV["DOCKER_HOST"].nil?
    ENV["DOCKER_HOST"] = "http://localhost:2375"
  end
end

.ssh_to_vm(&block) ⇒ Object



112
113
114
115
116
117
118
# File 'lib/mcrain/docker_machine.rb', line 112

def ssh_to_vm(&block)
  host = used? ? URI.parse(ENV["DOCKER_HOST"]).host : "localhost"
  Mcrain.logger.debug("connection STARTING to #{host} by SSH")
  r = Net::SSH.start(host, "docker", :password => "tcuser", &block)
  Mcrain.logger.debug("connection SUCCESS  to #{host} by SSH")
  return r
end

.tmpdirObject

return temporary dire for 2nd argument of Dir.mktmpdir



108
109
110
# File 'lib/mcrain/docker_machine.rb', line 108

def tmpdir
  used? ? File.join(DOCKER_MACHINE_DOCKER_HOME, 'tmp', Dir.tmpdir) : Dir.tmpdir
end

.used?Boolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/mcrain/docker_machine.rb', line 44

def used?
  RbConfig::CONFIG["host_os"] =~ /darwin/
end

.valid_docker_hostname?Boolean

Returns:

  • (Boolean)


34
35
36
37
38
# File 'lib/mcrain/docker_machine.rb', line 34

def valid_docker_hostname?
  return !!IPSocket.getaddress(docker_hostname)
rescue SocketError
  return false
end