buildizer 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Gemfile.lock +32 -26
- data/buildizer.gemspec +2 -2
- data/lib/buildizer.rb +10 -9
- data/lib/buildizer/builder/base.rb +132 -24
- data/lib/buildizer/builder/fpm.rb +2 -2
- data/lib/buildizer/builder/native.rb +1 -1
- data/lib/buildizer/builder/patch.rb +2 -2
- data/lib/buildizer/buildizer.rb +12 -4
- data/lib/buildizer/buildizer/buildizer_conf_mod.rb +0 -40
- data/lib/buildizer/buildizer/overcommit_mod.rb +1 -1
- data/lib/buildizer/ci/travis.rb +13 -6
- data/lib/buildizer/cli/main.rb +12 -10
- data/lib/buildizer/core_ext/hash.rb +5 -5
- data/lib/buildizer/core_ext/pathname.rb +3 -3
- data/lib/buildizer/docker.rb +104 -68
- data/lib/buildizer/image.rb +44 -1
- data/lib/buildizer/os.rb +4 -0
- data/lib/buildizer/os/base.rb +69 -0
- data/lib/buildizer/{image → os}/centos.rb +32 -24
- data/lib/buildizer/{image → os}/centos6.rb +2 -2
- data/lib/buildizer/{image → os}/centos7.rb +2 -2
- data/lib/buildizer/{image → os}/ubuntu.rb +29 -19
- data/lib/buildizer/{image → os}/ubuntu1204.rb +3 -3
- data/lib/buildizer/{image → os}/ubuntu1404.rb +3 -3
- data/lib/buildizer/{image → os}/ubuntu1604.rb +3 -3
- data/lib/buildizer/target/base.rb +65 -37
- data/lib/buildizer/target/fpm.rb +11 -21
- data/lib/buildizer/target/patch.rb +5 -8
- data/lib/buildizer/version.rb +1 -1
- metadata +14 -13
- data/lib/buildizer/image/base.rb +0 -76
@@ -16,46 +16,6 @@ module Buildizer
|
|
16
16
|
def buildizer_conf_setup!
|
17
17
|
write_yaml(buildizer_conf_path, buildizer_conf)
|
18
18
|
end
|
19
|
-
|
20
|
-
def package_name
|
21
|
-
buildizer_conf['package_name']
|
22
|
-
end
|
23
|
-
|
24
|
-
def package_version
|
25
|
-
buildizer_conf['package_version']
|
26
|
-
end
|
27
|
-
|
28
|
-
def before_prepare
|
29
|
-
Array(buildizer_conf['before_prepare'])
|
30
|
-
end
|
31
|
-
|
32
|
-
def after_prepare
|
33
|
-
Array(buildizer_conf['after_prepare'])
|
34
|
-
end
|
35
|
-
|
36
|
-
def targets
|
37
|
-
targets = Array(buildizer_conf['target'])
|
38
|
-
restrict_targets = ENV['BUILDIZER_TARGET']
|
39
|
-
restrict_targets = restrict_targets.split(',').map(&:strip) if restrict_targets
|
40
|
-
targets = targets & restrict_targets if restrict_targets
|
41
|
-
targets
|
42
|
-
end
|
43
|
-
|
44
|
-
def prepare
|
45
|
-
Array(buildizer_conf['prepare'])
|
46
|
-
end
|
47
|
-
|
48
|
-
def build_dep
|
49
|
-
Array(buildizer_conf['build_dep']).to_set
|
50
|
-
end
|
51
|
-
|
52
|
-
def before_build
|
53
|
-
Array(buildizer_conf['before_build'])
|
54
|
-
end
|
55
|
-
|
56
|
-
def maintainer
|
57
|
-
buildizer_conf['maintainer']
|
58
|
-
end
|
59
19
|
end # BuildizerConfMod
|
60
20
|
end # Buildizer
|
61
21
|
end # Buildizer
|
data/lib/buildizer/ci/travis.rb
CHANGED
@@ -51,24 +51,31 @@ module Buildizer
|
|
51
51
|
'sudo apt-get update',
|
52
52
|
|
53
53
|
# FIXME [https://github.com/docker/docker/issues/20316]:
|
54
|
-
'sudo apt-get -o dpkg::options::="--force-confnew" install -y docker-engine=1.9.1-0~trusty',
|
54
|
+
'sudo apt-get -o dpkg::options::="--force-confnew" install -y --force-yes docker-engine=1.9.1-0~trusty',
|
55
55
|
|
56
56
|
'echo "docker-engine hold" | sudo dpkg --set-selections',
|
57
57
|
]
|
58
58
|
install.push(*Array(buildizer_install_instructions(master: buildizer.project_settings['master'])))
|
59
59
|
|
60
|
-
|
61
|
-
|
60
|
+
if buildizer.project_settings['master']
|
61
|
+
buildizer_bin = 'bundle exec buildizer'
|
62
|
+
else
|
63
|
+
buildizer_bin = 'buildizer'
|
64
|
+
end
|
65
|
+
|
66
|
+
env = buildizer.builder.target_names.map {|t| "BUILDIZER_TARGET=#{t}"}
|
67
|
+
|
68
|
+
conf.merge!(
|
62
69
|
'dist' => 'trusty',
|
63
70
|
'sudo' => 'required',
|
64
71
|
'cache' => 'apt',
|
65
72
|
'language' => 'ruby',
|
66
73
|
'rvm' => '2.2.1',
|
67
74
|
'install' => install,
|
68
|
-
'before_script' =>
|
69
|
-
'script' =>
|
75
|
+
'before_script' => "#{buildizer_bin} prepare",
|
76
|
+
'script' => "#{buildizer_bin} build && #{buildizer_bin} test",
|
70
77
|
'env' => env,
|
71
|
-
'after_success' =>
|
78
|
+
'after_success' => "#{buildizer_bin} deploy",
|
72
79
|
)
|
73
80
|
end
|
74
81
|
|
data/lib/buildizer/cli/main.rb
CHANGED
@@ -51,34 +51,36 @@ module Buildizer
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
desc "deinit", "Deinitialize settings (.buildizer.yml, git pre-commit hook)"
|
55
|
-
shared_options
|
56
|
-
def deinit
|
57
|
-
buildizer.deinit!
|
58
|
-
end
|
59
|
-
|
60
54
|
desc "prepare", "Prepare images for building packages"
|
61
55
|
shared_options
|
62
56
|
def prepare
|
63
|
-
buildizer.prepare
|
57
|
+
buildizer.prepare
|
64
58
|
end
|
65
59
|
|
66
60
|
desc "build", "Build packages"
|
67
61
|
shared_options
|
68
62
|
def build
|
69
|
-
buildizer.build
|
63
|
+
buildizer.build
|
64
|
+
end
|
65
|
+
|
66
|
+
desc "test", "Run integration tests for packages"
|
67
|
+
shared_options
|
68
|
+
method_option :shell, type: :boolean, default: false,
|
69
|
+
desc: "drop into test shell for each target + env"
|
70
|
+
def test
|
71
|
+
buildizer.test
|
70
72
|
end
|
71
73
|
|
72
74
|
desc "deploy", "Deploy packages"
|
73
75
|
shared_options
|
74
76
|
def deploy
|
75
|
-
buildizer.deploy
|
77
|
+
buildizer.deploy
|
76
78
|
end
|
77
79
|
|
78
80
|
desc "verify", "Verify targets params"
|
79
81
|
shared_options
|
80
82
|
def verify
|
81
|
-
buildizer.verify
|
83
|
+
buildizer.verify
|
82
84
|
end
|
83
85
|
end # Main
|
84
86
|
end # Cli
|
@@ -1,20 +1,20 @@
|
|
1
1
|
class Hash
|
2
2
|
def zymbolize_keys
|
3
3
|
map do |key, value|
|
4
|
-
[
|
4
|
+
[_zymbolize(key), value]
|
5
5
|
end.to_h
|
6
6
|
end
|
7
7
|
|
8
8
|
def zymbolize_keys!
|
9
9
|
keys.each do |key|
|
10
|
-
self[
|
10
|
+
self[_zymbolize(key)] = delete(key)
|
11
11
|
end
|
12
12
|
self
|
13
13
|
end
|
14
14
|
|
15
15
|
def zymbolize_keys_deep
|
16
16
|
map do |key, value|
|
17
|
-
[
|
17
|
+
[_zymbolize(key), if value.is_a? Hash
|
18
18
|
value.zymbolize_keys_deep
|
19
19
|
else
|
20
20
|
value
|
@@ -29,7 +29,7 @@ class Hash
|
|
29
29
|
visited.add hash
|
30
30
|
hash.keys.each do |key|
|
31
31
|
value = hash.delete(key)
|
32
|
-
hash[
|
32
|
+
hash[_zymbolize(key)] = value
|
33
33
|
queue << value if value.is_a? Hash and not visited.include? hash
|
34
34
|
end
|
35
35
|
end
|
@@ -42,7 +42,7 @@ class Hash
|
|
42
42
|
|
43
43
|
private
|
44
44
|
|
45
|
-
def
|
45
|
+
def _zymbolize(value)
|
46
46
|
value.respond_to?(:to_sym) ? value.to_sym : value
|
47
47
|
end
|
48
48
|
end # Hash
|
@@ -1,9 +1,9 @@
|
|
1
1
|
class Pathname
|
2
2
|
def load_yaml
|
3
|
-
exist? ? YAML.load(read) : {}
|
3
|
+
exist? ? YAML.load(read) || {} : {}
|
4
4
|
rescue Psych::Exception => err
|
5
|
-
raise Error, error: :input_error,
|
6
|
-
|
5
|
+
raise Buildizer::Error, error: :input_error,
|
6
|
+
message: "bad yaml config file #{self}: #{err.message}"
|
7
7
|
end
|
8
8
|
|
9
9
|
def dump_yaml(cfg)
|
data/lib/buildizer/docker.rb
CHANGED
@@ -8,25 +8,25 @@ module Buildizer
|
|
8
8
|
@cache = cache
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
11
|
+
def os_klass(name, version)
|
12
12
|
({
|
13
13
|
'ubuntu' => {
|
14
|
-
'12.04' =>
|
15
|
-
'14.04' =>
|
16
|
-
'16.04' =>
|
17
|
-
nil =>
|
14
|
+
'12.04' => Os::Ubuntu1204,
|
15
|
+
'14.04' => Os::Ubuntu1404,
|
16
|
+
'16.04' => Os::Ubuntu1604,
|
17
|
+
nil => Os::Ubuntu1404,
|
18
18
|
},
|
19
19
|
'centos' => {
|
20
|
-
'centos6' =>
|
21
|
-
'centos7' =>
|
22
|
-
nil =>
|
20
|
+
'centos6' => Os::Centos6,
|
21
|
+
'centos7' => Os::Centos7,
|
22
|
+
nil => Os::Centos7,
|
23
23
|
},
|
24
|
-
}[
|
24
|
+
}[name] || {})[version]
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
klass =
|
29
|
-
raise Error, message: "unknown os '#{[
|
27
|
+
def new_os(name, version, **kwargs)
|
28
|
+
klass = os_klass(name, version)
|
29
|
+
raise Error, message: "unknown os '#{[name, version].compact.join('-')}'" unless klass
|
30
30
|
klass.new(self, **kwargs)
|
31
31
|
end
|
32
32
|
|
@@ -60,41 +60,40 @@ module Buildizer
|
|
60
60
|
builder.buildizer.command! 'docker logout', desc: "Docker cache account logout"
|
61
61
|
end
|
62
62
|
|
63
|
-
def
|
64
|
-
builder.buildizer.command
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
builder.buildizer.command! "docker rmi #{image.cache_name}",
|
75
|
-
desc: "Remove cache image #{image.cache_name}"
|
76
|
-
end
|
63
|
+
def pull_cache_image(build_image, cache_image)
|
64
|
+
pull_cache_res = builder.buildizer.command(
|
65
|
+
"docker pull #{cache_image.name}",
|
66
|
+
desc: "Try to pull docker cache image #{cache_image.name}"
|
67
|
+
)
|
68
|
+
if pull_cache_res.status.success?
|
69
|
+
builder.buildizer.command! "docker tag -f #{cache_image.name} #{build_image.name}",
|
70
|
+
desc: "Tag cache image #{cache_image.name}" +
|
71
|
+
" as prepared build image #{build_image.name}"
|
72
|
+
builder.buildizer.command! "docker rmi #{cache_image.name}",
|
73
|
+
desc: "Remove cache image #{cache_image.name}"
|
77
74
|
end
|
78
75
|
end
|
79
76
|
|
80
|
-
def
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
desc: "Push cache image #{image.cache_name}"
|
87
|
-
end
|
77
|
+
def cache_build_image(build_image, cache_image)
|
78
|
+
builder.buildizer.command! "docker tag -f #{build_image.name} #{cache_image.name}",
|
79
|
+
desc: "Tag prepared build image #{build_image.name}" +
|
80
|
+
" as cache image #{cache_image.name}"
|
81
|
+
builder.buildizer.command! "docker push #{cache_image.name}",
|
82
|
+
desc: "Push cache image #{cache_image.name}"
|
88
83
|
end
|
89
84
|
|
90
|
-
def
|
91
|
-
|
85
|
+
def make_build_image(target)
|
86
|
+
pull_cache_image(target.build_image, target.cache_image) if target.cache_image
|
87
|
+
|
88
|
+
target.build_image.dockerfile_write!
|
92
89
|
|
93
|
-
|
94
|
-
|
95
|
-
|
90
|
+
builder.buildizer.command! "docker build " +
|
91
|
+
"-t #{target.build_image.name} " +
|
92
|
+
"-f #{target.build_image.dockerfile_path} " +
|
93
|
+
"#{target.build_image.dockerfile_path.dirname}",
|
94
|
+
desc: "Build docker image #{target.build_image.name}"
|
96
95
|
|
97
|
-
|
96
|
+
cache_build_image(target.build_image, target.cache_image) if target.cache_image
|
98
97
|
end
|
99
98
|
|
100
99
|
def container_package_path
|
@@ -117,14 +116,15 @@ module Buildizer
|
|
117
116
|
Pathname.new('/extra')
|
118
117
|
end
|
119
118
|
|
120
|
-
def
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
119
|
+
def run_container!(name: nil, image:, env: {}, desc: nil, docker_opts: {})
|
120
|
+
(name || SecureRandom.uuid).tap do |name|
|
121
|
+
builder.buildizer.command! [
|
122
|
+
"docker run --detach --name #{name}",
|
123
|
+
*Array(_prepare_docker_opts(docker_opts)),
|
124
|
+
*Array(_prepare_container_params(image, env: env)),
|
125
|
+
_wrap_docker_command("while true ; do sleep 1 ; done"),
|
126
|
+
].join(' '), desc: desc
|
127
|
+
end
|
128
128
|
end
|
129
129
|
|
130
130
|
def shutdown_container!(container:)
|
@@ -132,38 +132,74 @@ module Buildizer
|
|
132
132
|
builder.buildizer.command! "docker rm #{container}", desc: "Remove container '#{container}'"
|
133
133
|
end
|
134
134
|
|
135
|
-
def
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
135
|
+
def with_container(**kwargs, &blk)
|
136
|
+
container = run_container!(**kwargs)
|
137
|
+
begin
|
138
|
+
yield container if block_given?
|
139
|
+
ensure
|
140
|
+
shutdown_container!(container: container)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def shell_in_container(container:)
|
145
|
+
system "docker exec -ti #{container} bash -lec 'cd #{container_package_mount_path}; bash'"
|
140
146
|
end
|
141
147
|
|
142
|
-
def
|
143
|
-
builder.buildizer.command
|
148
|
+
def run_in_container(container:, cmd:, desc: nil, cmd_opts: {}, docker_opts: {})
|
149
|
+
builder.buildizer.command [
|
150
|
+
"docker exec",
|
151
|
+
*Array(_prepare_docker_opts(docker_opts)),
|
152
|
+
container,
|
153
|
+
_wrap_docker_command(cmd),
|
154
|
+
].join(' '), timeout: 24*60*60, desc: desc, **cmd_opts
|
155
|
+
end
|
156
|
+
|
157
|
+
def run_in_container!(cmd_opts: {}, **kwargs)
|
158
|
+
cmd_opts[:do_raise] = true
|
159
|
+
cmd_opts[:log_failure] = true
|
160
|
+
run_in_container(cmd_opts: cmd_opts, **kwargs)
|
161
|
+
end
|
162
|
+
|
163
|
+
def run_in_image(image:, cmd:, env: {}, desc: nil, cmd_opts: {}, docker_opts: {})
|
164
|
+
builder.buildizer.command [
|
144
165
|
"docker run --rm",
|
145
|
-
*Array(
|
146
|
-
|
147
|
-
|
166
|
+
*Array(_prepare_docker_opts(docker_opts)),
|
167
|
+
*Array(_prepare_container_params(image, env: env)),
|
168
|
+
_wrap_docker_command(cmd),
|
169
|
+
].join(' '), timeout: 24*60*60, desc: desc, **cmd_opts
|
170
|
+
end
|
171
|
+
|
172
|
+
def run_in_image!(cmd_opts: {}, **kwargs)
|
173
|
+
cmd_opts[:do_raise] = true
|
174
|
+
run_in_image(cmd_opts: cmd_opts, **kwargs)
|
148
175
|
end
|
149
176
|
|
150
|
-
def
|
151
|
-
|
152
|
-
|
177
|
+
def _prepare_container_params(image, env: {})
|
178
|
+
image.extra_path.mkpath
|
179
|
+
image.build_path.mkpath
|
153
180
|
|
154
181
|
[*env.map {|k,v| "-e #{k}=#{v}"},
|
155
182
|
"-v #{builder.buildizer.package_path}:#{container_package_mount_path}:ro",
|
156
|
-
"-v #{
|
157
|
-
"-v #{
|
158
|
-
|
183
|
+
"-v #{image.extra_path}:#{container_extra_path}:ro",
|
184
|
+
"-v #{image.build_path}:#{container_build_path}",
|
185
|
+
image.name].compact
|
159
186
|
end
|
160
187
|
|
161
|
-
def
|
162
|
-
|
188
|
+
def _prepare_docker_opts(docker_opts)
|
189
|
+
docker_opts.map do |k, v|
|
190
|
+
next if v.nil?
|
191
|
+
|
192
|
+
to_opt = ->(value) {"--#{k}=#{value}"}
|
193
|
+
if v.is_a? Array
|
194
|
+
v.map(&to_opt)
|
195
|
+
else
|
196
|
+
to_opt[v]
|
197
|
+
end
|
198
|
+
end.flatten.compact
|
163
199
|
end
|
164
200
|
|
165
|
-
def
|
166
|
-
"'#{
|
201
|
+
def _wrap_docker_command(cmd)
|
202
|
+
"/bin/bash -lec '#{_make_cmd(cmd)}'"
|
167
203
|
end
|
168
204
|
|
169
205
|
def _make_cmd(cmd)
|
data/lib/buildizer/image.rb
CHANGED
@@ -1,4 +1,47 @@
|
|
1
1
|
module Buildizer
|
2
|
-
|
2
|
+
class Image
|
3
|
+
attr_reader :name
|
4
|
+
attr_reader :target
|
5
|
+
|
6
|
+
attr_reader :instructions
|
7
|
+
attr_reader :from
|
8
|
+
|
9
|
+
def initialize(name, target, from: nil)
|
10
|
+
@name = name
|
11
|
+
@target = target
|
12
|
+
|
13
|
+
@instructions = []
|
14
|
+
@from = from
|
15
|
+
|
16
|
+
instruction :FROM, from if from
|
17
|
+
end
|
18
|
+
|
19
|
+
def instruction(instruction, cmd)
|
20
|
+
instructions << [instruction.to_s.upcase, cmd].join(' ')
|
21
|
+
end
|
22
|
+
|
23
|
+
def build_path
|
24
|
+
target.image_build_path
|
25
|
+
end
|
26
|
+
|
27
|
+
def extra_path
|
28
|
+
target.image_extra_path
|
29
|
+
end
|
30
|
+
|
31
|
+
def dockerfile_name
|
32
|
+
"#{name}.dockerfile"
|
33
|
+
end
|
34
|
+
|
35
|
+
def dockerfile_path
|
36
|
+
target.image_work_path.join(dockerfile_name)
|
37
|
+
end
|
38
|
+
|
39
|
+
def dockerfile_dump
|
40
|
+
[instructions, nil].join("\n")
|
41
|
+
end
|
42
|
+
|
43
|
+
def dockerfile_write!
|
44
|
+
dockerfile_path.write! dockerfile_dump
|
45
|
+
end
|
3
46
|
end # Image
|
4
47
|
end # Buildizer
|