Class: Buildizer::Docker

Inherits:
Object
  • Object
show all
Defined in:
lib/buildizer/docker.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(builder, cache: nil) ⇒ Docker

Returns a new instance of Docker.



6
7
8
9
# File 'lib/buildizer/docker.rb', line 6

def initialize(builder, cache: nil)
  @builder = builder
  @cache = cache
end

Instance Attribute Details

#builderObject (readonly)

Returns the value of attribute builder.



3
4
5
# File 'lib/buildizer/docker.rb', line 3

def builder
  @builder
end

#cacheObject (readonly)

Returns the value of attribute cache.



4
5
6
# File 'lib/buildizer/docker.rb', line 4

def cache
  @cache
end

Instance Method Details

#_common_docker_params(target, env) ⇒ Object



150
151
152
153
154
155
156
# File 'lib/buildizer/docker.rb', line 150

def _common_docker_params(target, env)
  [*env.map {|k,v| "-e #{k}=#{v}"},
   "-v #{builder.packager.package_path}:#{container_package_mount_path}:ro",
   "-v #{target.image_extra_path}:#{container_extra_path}:ro",
   "-v #{target.image_build_path}:#{container_build_path}",
   target.image.name]
end

#_make_cmd(cmd) ⇒ Object



166
167
168
# File 'lib/buildizer/docker.rb', line 166

def _make_cmd(cmd)
  Array(cmd).join('; ')
end

#_wrap_docker_exec(cmd) ⇒ Object



158
159
160
# File 'lib/buildizer/docker.rb', line 158

def _wrap_docker_exec(cmd)
  "/bin/bash -lec '#{_make_cmd(cmd)}'"
end

#_wrap_docker_run(cmd) ⇒ Object



162
163
164
# File 'lib/buildizer/docker.rb', line 162

def _wrap_docker_run(cmd)
  "'#{['set -e', _make_cmd(cmd)].join('; ')}'"
end

#build_image!(target) ⇒ Object



90
91
92
93
94
95
96
97
98
# File 'lib/buildizer/docker.rb', line 90

def build_image!(target)
  pull_image target.image

  target.image_work_path.join('Dockerfile').write [*target.image.instructions, nil].join("\n")
  builder.packager.command! "docker build -t #{target.image.name} #{target.image_work_path}",
                             desc: "Build docker image #{target.image.name}"

  push_image target.image
end

#cache_login!Object

Raises:



47
48
49
50
51
52
53
54
55
56
# File 'lib/buildizer/docker.rb', line 47

def cache_login!
  raise Error, error: :logical_error, message: "no docker cache account info" unless cache

  cmd = ["docker login"]
  cmd << "--email=#{cache[:email]}" if cache[:email]
  cmd << "--username=#{cache[:user]}" if cache[:user]
  cmd << "--password=#{cache[:password]}" if cache[:password]
  cmd << "--server=#{cache[:server]}" if cache[:server]
  builder.packager.command! cmd.join(' '), desc: "Docker cache account login"
end

#cache_logout!Object

Raises:



58
59
60
61
# File 'lib/buildizer/docker.rb', line 58

def cache_logout!
  raise Error, error: :logical_error, message: "no docker cache account info" unless cache
  builder.packager.command! 'docker logout', desc: "Docker cache account logout"
end

#container_build_pathObject



112
113
114
# File 'lib/buildizer/docker.rb', line 112

def container_build_path
  Pathname.new('/build')
end

#container_extra_pathObject



116
117
118
# File 'lib/buildizer/docker.rb', line 116

def container_extra_path
  Pathname.new('/extra')
end

#container_package_archive_pathObject



104
105
106
# File 'lib/buildizer/docker.rb', line 104

def container_package_archive_path
  Pathname.new('/package.tar.gz')
end

#container_package_mount_pathObject



108
109
110
# File 'lib/buildizer/docker.rb', line 108

def container_package_mount_path
  Pathname.new('/.package')
end

#container_package_pathObject



100
101
102
# File 'lib/buildizer/docker.rb', line 100

def container_package_path
  Pathname.new('/package')
end

#image_klass(os_name, os_version) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/buildizer/docker.rb', line 11

def image_klass(os_name, os_version)
  ({
    'ubuntu' => {
      '12.04' => Image::Ubuntu1204,
      '14.04' => Image::Ubuntu1404,
      '16.04' => Image::Ubuntu1604,
      nil => Image::Ubuntu1404,
    },
    'centos' => {
      'centos6' => Image::Centos6,
      'centos7' => Image::Centos7,
      nil => Image::Centos7,
    },
  }[os_name] || {})[os_version]
end

#new_image(os_name, os_version, **kwargs) ⇒ Object

Raises:



27
28
29
30
31
# File 'lib/buildizer/docker.rb', line 27

def new_image(os_name, os_version, **kwargs)
  klass = image_klass(os_name, os_version)
  raise Error, message: "unknown os '#{[os_name, os_version].compact.join('-')}'" unless klass
  klass.new(self, **kwargs)
end

#pull_image(image) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/buildizer/docker.rb', line 63

def pull_image(image)
  builder.packager.command! "docker pull #{image.base_image}", desc: "Pull docker base image #{image.base_image}"
  if cache
    pull_cache_res = builder.packager.command(
      "docker pull #{image.cache_name}",
      desc: "Try to pull docker cache image #{image.cache_name}"
    )
    if pull_cache_res.status.success?
      builder.packager.command! "docker tag -f #{image.cache_name} #{image.name}",
                                 desc: "Tag cache image #{image.cache_name}" +
                                       " as prepared build image #{image.name}"
      builder.packager.command! "docker rmi #{image.cache_name}",
                                 desc: "Remove cache image #{image.cache_name}"
    end
  end
end

#push_image(image) ⇒ Object



80
81
82
83
84
85
86
87
88
# File 'lib/buildizer/docker.rb', line 80

def push_image(image)
  if cache
    builder.packager.command! "docker tag -f #{image.name} #{image.cache_name}",
                               desc: "Tag prepared build image #{image.name}" +
                                     " as cache image #{image.cache_name}"
    builder.packager.command! "docker push #{image.cache_name}",
                               desc: "Push cache image #{image.cache_name}"
  end
end

#run_in_container!(container:, cmd:, desc: nil) ⇒ Object



135
136
137
138
139
140
# File 'lib/buildizer/docker.rb', line 135

def run_in_container!(container:, cmd:, desc: nil)
  builder.packager.command! [
    "docker exec #{container}",
    _wrap_docker_exec(cmd),
  ].join(' '), timeout: 24*60*60, desc: desc
end

#run_in_image!(target:, cmd:, env: {}, desc: nil) ⇒ Object



142
143
144
145
146
147
148
# File 'lib/buildizer/docker.rb', line 142

def run_in_image!(target:, cmd:, env: {}, desc: nil)
  builder.packager.command! [
    "docker run --rm",
    *Array(_common_docker_params(target, env)),
    _wrap_docker_run(cmd),
  ].join(' '), timeout: 24*60*60, desc: desc
end

#run_target_container!(target:, env: {}) ⇒ Object



120
121
122
123
124
125
126
127
128
# File 'lib/buildizer/docker.rb', line 120

def run_target_container!(target:, env: {})
  container = SecureRandom.uuid
  builder.packager.command! [
    "docker run --detach --name #{container}",
    *Array(_common_docker_params(target, env)),
    _wrap_docker_run("while true ; do sleep 1 ; done"),
  ].join(' '), desc: "Run container '#{container}' from docker image '#{target.image.name}'"
  container
end

#shutdown_container!(container:) ⇒ Object



130
131
132
133
# File 'lib/buildizer/docker.rb', line 130

def shutdown_container!(container:)
  builder.packager.command! "docker kill #{container}", desc: "Kill container '#{container}'"
  builder.packager.command! "docker rm #{container}", desc: "Remove container '#{container}'"
end

#with_cache(&blk) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/buildizer/docker.rb', line 33

def with_cache(&blk)
  warn("No docker cache account settings " +
       "(BUILDIZER_DOCKER_CACHE, BUILDIZER_DOCKER_CACHE_USERNAME," +
       " BUILDIZER_DOCKER_CACHE_PASSWORD, BUILDIZER_DOCKER_CACHE_EMAIL," +
       " BUILDIZER_DOCKER_CACHE_SERVER) [WARN]") unless cache

  cache_login! if cache
  begin
    yield if block_given?
  ensure
    cache_logout! if cache
  end
end