-
Notifications
You must be signed in to change notification settings - Fork 13
/
Rakefile
128 lines (105 loc) · 2.86 KB
/
Rakefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
require 'bundler/setup'
require 'docker'
require 'etcd'
require 'minigit'
$git = MiniGit::Capturing.new(__FILE__)
$etcd = Etcd.client(
host: ENV['ETCD_HOST'] || '127.0.0.1',
port: (ENV['ETCD_PORT'] || 4001).to_i)
ENV['ETCD_PREFIX'] ||= '/3ofcoins/docker-images'
DOCKER_REBASE = File.join(Dir.getwd, 'script/docker-rebase.rb')
GIT_BRANCH = ENV['GIT_BRANCH'] ? ENV['GIT_BRANCH'].sub(/^origin\//, '') :
$git.rev_parse({ abbrev_ref: true }, 'HEAD').strip
class DockerImageTask < Rake::Task
include Rake::FileUtilsExt # for #sh
PULL = Hash.new do |h, k|
h[k] = Rake::Task.define_task("docker:pull:#{k}") do
$stdout.write "Pulling #{k} ... "
$stdout.flush
image, tag = k.split(':')
tag ||= 'latest'
img = Docker::Image.create(fromImage: image, tag: tag)
$stdout.puts img.id
end
end
def initialize(*args, &block)
super
enhance [ PULL[base_image_name] ], &:build!
end
def sha1
@sha1 ||= $git.rev_list({max_count: 1}, 'HEAD', '--', name).strip
end
def etcd_key
"#{ENV['ETCD_PREFIX']}/#{name}/built/sha1:#{sha1}"
end
def image_name(tag=nil)
rv = "#{ENV['REGISTRY']}/#{File.basename(name)}"
rv << ":#{tag}" if tag
rv
end
def tag!(*tags)
return unless ENV['REGISTRY']
tags = self.tags if tags.empty?
tags.each do |tag|
sh "docker tag -f #{image_id} #{image_name(tag)}"
sh "docker push #{image_name(tag)}"
end
end
def tags
@tags ||= begin
rv = dockerfile
.map { |ln| ln =~ /^\s*\#\s*tag\s+/i && $'.split }
.compact
.flatten
rv << GIT_BRANCH
rv << 'latest' if GIT_BRANCH == 'master'
rv
end
end
def image_id
@image_id ||= $etcd.get(etcd_key).value
rescue Etcd::KeyNotFound
nil
end
def image
Docker::Image.get(image_id) if image_id
end
def save_id!
$etcd.set(etcd_key, value: image_id)
end
def dockerfile
@dockerfile ||= File.read(File.join(name, "Dockerfile"))
.lines
.map(&:strip)
end
def base_image_name
@base_image_name ||= dockerfile
.grep(/^\s*from\s/i)
.first
.sub(/^\s*from\s+/i, '')
end
def base_image
Docker::Image.get(base_image_name)
end
def needed?
image.nil? || image.info['parent'] != base_image.id
end
def build!(*)
sh "ruby #{DOCKER_REBASE}#{' --verbose' if ENV['VERBOSE']} --save-id=#{self}/.image_id --build #{self}"
@image_id = File.read("#{self}/.image_id")
tag!
save_id!
end
end
def docker_image(path, &block)
path = File.dirname(path) if File.basename(path) == 'Dockerfile'
desc "docker build #{path}"
DockerImageTask.define_task(path, &block)
end
desc 'All Docker images'
task :images
Dir['public/*/Dockerfile'].each { |df| task :images => docker_image(df) }
task :pry do
require 'pry'
binding.pry
end