Class: Ufo::DockerBuilder

Inherits:
Object
  • Object
show all
Includes:
Execute, PrettyTime
Defined in:
lib/ufo/docker_builder.rb

Instance Method Summary collapse

Methods included from Execute

#execute

Methods included from PrettyTime

#pretty_time

Constructor Details

#initialize(options = {}) ⇒ DockerBuilder

Returns a new instance of DockerBuilder.



6
7
8
9
10
11
# File 'lib/ufo/docker_builder.rb', line 6

def initialize(options={})
  @options = options
  @project_root = options[:project_root] || '.'
  @dockerfile = options[:dockerfile] || 'Dockerfile'
  @image_namespace = options[:image_namespace] || 'ufo'
end

Instance Method Details

#buildObject



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/ufo/docker_builder.rb', line 13

def build
  start_time = Time.now
  store_full_image_name
  update_auth_token # call after store_full_image_name

  command = "docker build -t #{full_image_name} -f #{@dockerfile} ."
  say "Building docker image with:".green
  say "  #{command}".green
  check_dockerfile_exists
  command = "cd #{@project_root} && #{command}"
  success = execute(command, use_system: true)
  unless success
    puts "The docker image fail to build.  Are you sure the docker daemon is available?  Try running: docker version"
    exit 1
  end

  took = Time.now - start_time
  say "Docker image #{full_image_name} built.  " + "Took #{pretty_time(took)}.".green
end

#check_dockerfile_existsObject



47
48
49
50
51
52
# File 'lib/ufo/docker_builder.rb', line 47

def check_dockerfile_exists
  unless File.exist?("#{@project_root}/#{@dockerfile}")
    puts "#{@dockerfile} does not exist.  Are you sure it exists?"
    exit 1
  end
end

#docker_name_pathObject



99
100
101
102
# File 'lib/ufo/docker_builder.rb', line 99

def docker_name_path
  # output gets entirely wiped by tasks builder so dotn use that folder
  "#{@project_root}/ufo/docker_image_name_#{@image_namespace}.txt"
end

#ecr_image?Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/ufo/docker_builder.rb', line 61

def ecr_image?
  full_image_name =~ /\.amazonaws\.com/
end

#full_image_nameObject

full_image - includes the tag



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/ufo/docker_builder.rb', line 71

def full_image_name
  if @options[:generate]
    return generate_name # name already has a newline
  end

  unless File.exist?(docker_name_path)
    puts "Unable to find #{docker_name_path} which contains the last docker image name that was used as a part of `ufo docker build`.  Please run `ufo docker build` first."
    exit 1
  end
  IO.read(docker_name_path).strip
end

#generate_nameObject



95
96
97
# File 'lib/ufo/docker_builder.rb', line 95

def generate_name
  "#{image_name}:#{@image_namespace}-#{timestamp}-#{git_sha}"
end

#git_shaObject



108
109
110
111
112
113
# File 'lib/ufo/docker_builder.rb', line 108

def git_sha
  return @git_sha if @git_sha
  # always call this and dont use the execute method because of the noop option
  @git_sha = `cd #{@project_root} && git rev-parse --short HEAD`
  @git_sha.strip!
end

#image_nameObject

full_image - does not include the tag



66
67
68
# File 'lib/ufo/docker_builder.rb', line 66

def image_name
  settings.data["image"]
end

#pushObject



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

def push
  update_auth_token
  start_time = Time.now
  message = "Pushed #{full_image_name} docker image."
  if @options[:noop]
    message = "NOOP #{message}"
  else
    execute("docker push #{full_image_name}", use_system: true)
  end
  took = Time.now - start_time
  message << " Took #{pretty_time(took)}.".green
  puts message unless @options[:mute]
end

#say(msg) ⇒ Object



124
125
126
# File 'lib/ufo/docker_builder.rb', line 124

def say(msg)
  puts msg unless @options[:mute]
end

#settingsObject



115
116
117
# File 'lib/ufo/docker_builder.rb', line 115

def settings
  @settings ||= Settings.new(@project_root)
end

#store_full_image_nameObject

Store this in a file because this name gets reference in other tasks later and we want the image name to stay the same when the commands are run separate in different processes. So we store the state in a file. Only when a new docker build command gets run will the image name state be updated.



87
88
89
90
91
92
93
# File 'lib/ufo/docker_builder.rb', line 87

def store_full_image_name
  dirname = File.dirname(docker_name_path)
  FileUtils.mkdir_p(dirname) unless File.exist?(dirname)
  full_image_name = generate_name
  IO.write(docker_name_path, full_image_name)
  IO.write("#{@project_root}/ufo/version", full_image_name)
end

#timestampObject



104
105
106
# File 'lib/ufo/docker_builder.rb', line 104

def timestamp
  @timestamp ||= Time.now.strftime('%Y-%m-%dT%H-%M-%S')
end

#update_auth_tokenObject



54
55
56
57
58
59
# File 'lib/ufo/docker_builder.rb', line 54

def update_auth_token
  return unless ecr_image?
  repo_domain = "https://#{image_name.split('/').first}"
  auth = EcrAuth.new(repo_domain)
  auth.update
end

#update_dockerfileObject



119
120
121
122
# File 'lib/ufo/docker_builder.rb', line 119

def update_dockerfile
  updater = DockerfileUpdater.new(full_image_name, @options)
  updater.update
end