buildizer 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/.gitignore +1 -0
- data/Gemfile.lock +4 -4
- data/lib/buildizer.rb +5 -0
- data/lib/buildizer/builder/base.rb +112 -69
- data/lib/buildizer/builder/fpm.rb +27 -50
- data/lib/buildizer/builder/native.rb +3 -4
- data/lib/buildizer/builder/patch.rb +40 -0
- data/lib/buildizer/cli.rb +6 -0
- data/lib/buildizer/docker.rb +101 -40
- data/lib/buildizer/image/base.rb +12 -0
- data/lib/buildizer/image/centos.rb +48 -16
- data/lib/buildizer/image/ubuntu.rb +31 -0
- data/lib/buildizer/image/ubuntu1604.rb +13 -0
- data/lib/buildizer/packager.rb +39 -24
- data/lib/buildizer/refine.rb +8 -2
- data/lib/buildizer/target/base.rb +77 -5
- data/lib/buildizer/target/fpm.rb +52 -5
- data/lib/buildizer/target/native.rb +9 -0
- data/lib/buildizer/target/package_name_mod.rb +17 -0
- data/lib/buildizer/target/patch.rb +33 -0
- data/lib/buildizer/version.rb +1 -1
- metadata +6 -2
@@ -9,10 +9,9 @@ module Buildizer
|
|
9
9
|
Target::Native
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
super
|
14
|
-
|
15
|
-
end
|
12
|
+
def check_params!(params)
|
13
|
+
super
|
14
|
+
_required_params! :package_version, params
|
16
15
|
end
|
17
16
|
|
18
17
|
def build_instructions(target)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Buildizer
|
2
|
+
module Builder
|
3
|
+
class Patch < Base
|
4
|
+
def build_type
|
5
|
+
'patch'
|
6
|
+
end
|
7
|
+
|
8
|
+
def target_klass
|
9
|
+
Target::Patch
|
10
|
+
end
|
11
|
+
|
12
|
+
def initial_target_params
|
13
|
+
super.tap do |params|
|
14
|
+
params[:patch] = Array(packager.buildizer_conf['patch'])
|
15
|
+
params[:patch_version] = packager.buildizer_conf['patch_version']
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def do_merge_params(into, params)
|
20
|
+
super.tap do |res|
|
21
|
+
res[:patch] = (into[:patch] + Array(params['patch'])).uniq
|
22
|
+
res[:patch_version] = into[:patch_version] || params['patch_version']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def check_params!(params)
|
27
|
+
super
|
28
|
+
_required_params! :patch_version, params
|
29
|
+
end
|
30
|
+
|
31
|
+
def build_instructions(target)
|
32
|
+
target.image.patch_build_instructions(self, target)
|
33
|
+
end
|
34
|
+
|
35
|
+
def build_dep(target)
|
36
|
+
target.image.patch_build_dep(self, target)
|
37
|
+
end
|
38
|
+
end # Patch
|
39
|
+
end # Builder
|
40
|
+
end # Buildizer
|
data/lib/buildizer/cli.rb
CHANGED
data/lib/buildizer/docker.rb
CHANGED
@@ -1,17 +1,11 @@
|
|
1
1
|
module Buildizer
|
2
2
|
class Docker
|
3
3
|
attr_reader :builder
|
4
|
-
attr_reader :
|
5
|
-
attr_reader :password
|
6
|
-
attr_reader :email
|
7
|
-
attr_reader :server
|
4
|
+
attr_reader :cache
|
8
5
|
|
9
|
-
def initialize(builder,
|
6
|
+
def initialize(builder, cache: nil)
|
10
7
|
@builder = builder
|
11
|
-
@
|
12
|
-
@password = password
|
13
|
-
@email = email
|
14
|
-
@server = server
|
8
|
+
@cache = cache
|
15
9
|
end
|
16
10
|
|
17
11
|
def image_klass(os_name, os_version)
|
@@ -19,6 +13,7 @@ module Buildizer
|
|
19
13
|
'ubuntu' => {
|
20
14
|
'12.04' => Image::Ubuntu1204,
|
21
15
|
'14.04' => Image::Ubuntu1404,
|
16
|
+
'16.04' => Image::Ubuntu1604,
|
22
17
|
nil => Image::Ubuntu1404,
|
23
18
|
},
|
24
19
|
'centos' => {
|
@@ -35,61 +30,127 @@ module Buildizer
|
|
35
30
|
klass.new(self, **kwargs)
|
36
31
|
end
|
37
32
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
|
33
|
+
def with_cache(&blk)
|
34
|
+
warn("No docker cache account settings " +
|
35
|
+
"(BUILDIZER_DOCKER_CACHE, BUILDIZER_DOCKER_CACHE_USERNAME, " +
|
36
|
+
"BUILDIZER_DOCKER_CACHE_PASSWORD, BUILDIZER_DOCKER_CACHE_EMAIL, " +
|
37
|
+
"BUILDIZER_DOCKER_CACHE_SERVER) [WARN]") unless cache
|
38
|
+
|
39
|
+
cache_login! if cache
|
40
|
+
begin
|
41
|
+
yield if block_given?
|
42
|
+
ensure
|
43
|
+
cache_logout! if cache
|
44
|
+
end
|
42
45
|
end
|
43
46
|
|
44
|
-
def
|
45
|
-
|
46
|
-
end
|
47
|
+
def cache_login!
|
48
|
+
raise Error, error: :logical_error, message: "no docker cache account info" unless cache
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
|
50
|
+
cmd = ["docker login"]
|
51
|
+
cmd << "--email=#{cache[:email]}" if cache[:email]
|
52
|
+
cmd << "--username=#{cache[:username]}" if cache[:username]
|
53
|
+
cmd << "--password=#{cache[:password]}" if cache[:password]
|
54
|
+
cmd << "--server=#{cache[:server]}" if cache[:server]
|
55
|
+
builder.packager.command! cmd.join(' '), desc: "Docker cache account login"
|
51
56
|
end
|
52
57
|
|
53
|
-
def
|
54
|
-
|
58
|
+
def cache_logout!
|
59
|
+
raise Error, error: :logical_error, message: "no docker cache account info" unless cache
|
60
|
+
builder.packager.command! 'docker logout', desc: "Docker cache account logout"
|
55
61
|
end
|
56
62
|
|
57
|
-
def
|
58
|
-
|
59
|
-
|
60
|
-
image_build_path(image).join('Dockerfile').write [*image.instructions, nil].join("\n")
|
61
|
-
builder.packager.command! "docker build -t #{image.name} #{image_build_path(image)}", desc: "Docker build image #{image.name}"
|
63
|
+
def pull_image(image)
|
64
|
+
builder.packager.command!("docker pull #{image.base_image}",
|
65
|
+
desc: "Docker pull #{image.base_image}")
|
62
66
|
|
63
|
-
|
67
|
+
builder.packager.command("docker pull #{image.name}",
|
68
|
+
desc: "Docker pull #{image.name}") if cache
|
64
69
|
end
|
65
70
|
|
66
|
-
def
|
67
|
-
builder.
|
71
|
+
def push_image(image)
|
72
|
+
builder.packager.command("docker push #{image.name}",
|
73
|
+
desc: "Docker push #{image.name}") if cache
|
68
74
|
end
|
69
75
|
|
70
|
-
def
|
71
|
-
|
76
|
+
def build_image!(target)
|
77
|
+
pull_image target.image
|
78
|
+
|
79
|
+
target.image_work_path.join('Dockerfile').write [*target.image.instructions, nil].join("\n")
|
80
|
+
builder.packager.command! "docker build -t #{target.image.name} #{target.image_work_path}",
|
81
|
+
desc: "Docker build image #{target.image.name}"
|
82
|
+
|
83
|
+
push_image target.image
|
72
84
|
end
|
73
85
|
|
74
86
|
def container_package_path
|
75
87
|
Pathname.new('/package')
|
76
88
|
end
|
77
89
|
|
90
|
+
def container_package_archive_path
|
91
|
+
Pathname.new('/package.tar.gz')
|
92
|
+
end
|
93
|
+
|
94
|
+
def container_package_mount_path
|
95
|
+
Pathname.new('/.package')
|
96
|
+
end
|
97
|
+
|
78
98
|
def container_build_path
|
79
|
-
|
99
|
+
Pathname.new('/build')
|
80
100
|
end
|
81
101
|
|
82
|
-
def
|
83
|
-
|
102
|
+
def container_extra_path
|
103
|
+
Pathname.new('/extra')
|
104
|
+
end
|
84
105
|
|
106
|
+
def run_target_container!(target:, env: {})
|
107
|
+
container = SecureRandom.uuid
|
108
|
+
builder.packager.command! [
|
109
|
+
"docker run --detach --name #{container}",
|
110
|
+
*Array(_common_docker_params(target, env)),
|
111
|
+
_wrap_docker_run("while true ; do sleep 1 ; done"),
|
112
|
+
].join(' '), desc: "Run container '#{container}' from docker image '#{target.image.name}'"
|
113
|
+
container
|
114
|
+
end
|
115
|
+
|
116
|
+
def shutdown_container!(container:)
|
117
|
+
builder.packager.command! "docker kill #{container}", desc: "Kill container '#{container}'"
|
118
|
+
builder.packager.command! "docker rm #{container}", desc: "Remove container '#{container}'"
|
119
|
+
end
|
120
|
+
|
121
|
+
def run_in_container!(container:, cmd:, desc: nil)
|
122
|
+
builder.packager.command! [
|
123
|
+
"docker exec #{container}",
|
124
|
+
_wrap_docker_exec(cmd),
|
125
|
+
].join(' '), timeout: 24*60*60, desc: desc
|
126
|
+
end
|
127
|
+
|
128
|
+
def run_in_image!(target:, cmd:, env: {}, desc: nil)
|
85
129
|
builder.packager.command! [
|
86
130
|
"docker run --rm",
|
87
|
-
*
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
131
|
+
*Array(_common_docker_params(target, env)),
|
132
|
+
_wrap_docker_run(cmd),
|
133
|
+
].join(' '), timeout: 24*60*60, desc: desc
|
134
|
+
end
|
135
|
+
|
136
|
+
def _common_docker_params(target, env)
|
137
|
+
[*env.map {|k,v| "-e #{k}=#{v}"},
|
138
|
+
"-v #{builder.packager.package_path}:#{container_package_mount_path}:ro",
|
139
|
+
"-v #{target.image_extra_path}:#{container_extra_path}:ro",
|
140
|
+
"-v #{target.image_build_path}:#{container_build_path}",
|
141
|
+
target.image.name]
|
142
|
+
end
|
143
|
+
|
144
|
+
def _wrap_docker_exec(cmd)
|
145
|
+
"/bin/bash -lec '#{_make_cmd(cmd)}'"
|
146
|
+
end
|
147
|
+
|
148
|
+
def _wrap_docker_run(cmd)
|
149
|
+
"'#{['set -e', _make_cmd(cmd)].join('; ')}'"
|
150
|
+
end
|
151
|
+
|
152
|
+
def _make_cmd(cmd)
|
153
|
+
Array(cmd).join('; ')
|
93
154
|
end
|
94
155
|
end # Docker
|
95
156
|
end # Buildizer
|
data/lib/buildizer/image/base.rb
CHANGED
@@ -52,9 +52,21 @@ module Buildizer
|
|
52
52
|
instructions << [instruction.to_s.upcase, cmd].join(' ')
|
53
53
|
end
|
54
54
|
|
55
|
+
def patch_build_dep(builder, target)
|
56
|
+
target_package_spec(target)
|
57
|
+
end
|
58
|
+
|
55
59
|
def native_build_instructions(builder, target)
|
56
60
|
raise
|
57
61
|
end
|
62
|
+
|
63
|
+
def patch_build_instructions(builder, target)
|
64
|
+
raise
|
65
|
+
end
|
66
|
+
|
67
|
+
def target_package_spec(target)
|
68
|
+
raise
|
69
|
+
end
|
58
70
|
end # Base
|
59
71
|
end # Image
|
60
72
|
end # Buildizer
|
@@ -48,23 +48,55 @@ module Buildizer
|
|
48
48
|
instruction :RUN, "bash -lec \"echo -e '#{repo}' >> /etc/yum.repos.d/CentOS-Extra-Buildizer.repo\""
|
49
49
|
end
|
50
50
|
|
51
|
+
def target_spec_name(target)
|
52
|
+
"#{target.base_package_name}.spec"
|
53
|
+
end
|
54
|
+
|
55
|
+
def rpmdev_setuptree_instructions(builder, target)
|
56
|
+
"rpmdev-setuptree"
|
57
|
+
end
|
58
|
+
|
59
|
+
def build_rpm_instructions(builder, target)
|
60
|
+
["cd ~/rpmbuild/SPECS/",
|
61
|
+
"rpmbuild -bb #{target_spec_name(target)}",
|
62
|
+
["find ~/rpmbuild/RPMS -name '*.rpm' ",
|
63
|
+
"-exec mv {} #{builder.docker.container_build_path} \\;"].join]
|
64
|
+
end
|
65
|
+
|
51
66
|
def native_build_instructions(builder, target)
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
67
|
+
[*Array(rpmdev_setuptree_instructions(builder, target)),
|
68
|
+
"cp #{builder.docker.container_package_archive_path} ~/rpmbuild/SOURCES/",
|
69
|
+
"cp #{builder.docker.container_package_path.join(target_spec_name(target))} ~/rpmbuild/SPECS/",
|
70
|
+
*Array(build_rpm_instructions(builder, target))]
|
71
|
+
end
|
72
|
+
|
73
|
+
def patch_build_instructions(builder, target)
|
74
|
+
rpmchange_cmd = "rpmchange %{cmd} --specfile ~/rpmbuild/SPECS/#{target_spec_name(target)} %{args}"
|
75
|
+
get_release_cmd = rpmchange_cmd % {cmd: :tag, args: "--name release"}
|
76
|
+
set_release_cmd = rpmchange_cmd % {cmd: :tag, args: "--name release --value %{value}"}
|
77
|
+
changelog_cmd = rpmchange_cmd % {
|
78
|
+
cmd: :changelog,
|
79
|
+
args: "--append --name \"%{name}\" --email \"%{email}\" --message \"%{message}\""
|
80
|
+
}
|
81
|
+
|
82
|
+
[*Array(rpmdev_setuptree_instructions(builder, target)),
|
83
|
+
"yumdownloader --source #{target_package_spec(target)}",
|
84
|
+
"rpm -i *.rpm",
|
85
|
+
"gem install rpmchange",
|
86
|
+
set_release_cmd % {value: "$(#{get_release_cmd})buildizer#{target.package_version}"},
|
87
|
+
*target.patch.map {|patch| "cp #{patch} ~/rpmbuild/SOURCES/"},
|
88
|
+
*target.patch.map {|patch|
|
89
|
+
rpmchange_cmd % {cmd: :append,
|
90
|
+
args: "--section prep --value \"patch -p1 < %{_sourcedir}/#{patch}\""}
|
91
|
+
},
|
92
|
+
changelog_cmd % {name: target.maintainer,
|
93
|
+
email: target.maintainer_email,
|
94
|
+
message: 'Patch by buildizer'},
|
95
|
+
*Array(build_rpm_instructions(builder, target))]
|
96
|
+
end
|
97
|
+
|
98
|
+
def target_package_spec(target)
|
99
|
+
[target.package_name, target.package_version].compact.join('-')
|
68
100
|
end
|
69
101
|
end # Centos
|
70
102
|
end # Image
|
@@ -34,6 +34,37 @@ module Buildizer
|
|
34
34
|
res << '--deb-no-default-config-files'
|
35
35
|
end
|
36
36
|
end
|
37
|
+
|
38
|
+
def build_deb_instructions(builder, target)
|
39
|
+
["DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -b -us -uc -j#{builder.build_jobs}",
|
40
|
+
"cp ../*.deb #{builder.docker.container_build_path}"]
|
41
|
+
end
|
42
|
+
|
43
|
+
def native_build_instructions(builder, target)
|
44
|
+
source_archive_name = "#{target.package_name}_#{target.package_upstream_version}.orig.tar.gz"
|
45
|
+
|
46
|
+
[["ln -fs #{target.container_package_archive_path} ",
|
47
|
+
"#{target.container_package_path.dirname.join(source_archive_name)}"].join,
|
48
|
+
"cd #{target.container_package_path}",
|
49
|
+
*Array(build_deb_instructions(builder, target))]
|
50
|
+
end
|
51
|
+
|
52
|
+
def patch_build_instructions(builder, target)
|
53
|
+
["apt-get source #{target_package_spec(target)}",
|
54
|
+
'cd $(ls *.orig.tar* | ruby -ne "puts \$_.split(\\".orig.tar\\").first.gsub(\\"_\\", \\"-\\")")',
|
55
|
+
["DEBFULLNAME=\"#{target.maintainer}\" DEBEMAIL=\"#{target.maintainer_email}\" ",
|
56
|
+
"debchange --newversion ",
|
57
|
+
"$(dpkg-parsechangelog | grep \"Version:\" | cut -d\" \" -f2-)buildizer#{target.patch_version} ",
|
58
|
+
"--distribution #{os_codename} \"Patch by buildizer\""].join,
|
59
|
+
*target.patch.map {|patch| "cp ../#{patch} debian/patches/"},
|
60
|
+
*target.patch.map {|patch| "sed -i \"/#{Regexp.escape(patch)}/d\" debian/patches/series"},
|
61
|
+
*target.patch.map {|patch| "echo #{patch} >> debian/patches/series"},
|
62
|
+
*Array(build_deb_instructions(builder, target))]
|
63
|
+
end
|
64
|
+
|
65
|
+
def target_package_spec(target)
|
66
|
+
[target.package_name, target.package_version].compact.join('=')
|
67
|
+
end
|
37
68
|
end # Ubuntu
|
38
69
|
end # Image
|
39
70
|
end # Buildizer
|
data/lib/buildizer/packager.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
module Buildizer
|
2
2
|
class Packager
|
3
|
+
using Refine
|
4
|
+
|
3
5
|
attr_reader :package_path
|
4
6
|
attr_reader :buildizer_conf_path
|
5
7
|
attr_reader :options_path
|
6
8
|
attr_reader :travis_path
|
9
|
+
attr_reader :work_path
|
7
10
|
attr_reader :debug
|
8
11
|
|
9
12
|
def initialize(options: {}, debug: false)
|
@@ -11,8 +14,9 @@ module Buildizer
|
|
11
14
|
@buildizer_conf_path = package_path.join('Buildizer')
|
12
15
|
@options_path = package_path.join('.buildizer.yml')
|
13
16
|
@travis_path = package_path.join('.travis.yml')
|
17
|
+
@work_path = Pathname.new(ENV['BUILDIZER_WORK_PATH'] || '~/.buildizer').expand_path
|
14
18
|
@_options = options
|
15
|
-
@debug = debug
|
19
|
+
@debug = ENV['BUILDIZER_DEBUG'].nil? ? debug : ENV['BUILDIZER_DEBUG'].to_s.on?
|
16
20
|
end
|
17
21
|
|
18
22
|
def initialized?
|
@@ -53,6 +57,10 @@ module Buildizer
|
|
53
57
|
builder.deploy
|
54
58
|
end
|
55
59
|
|
60
|
+
def verify!
|
61
|
+
builder.verify
|
62
|
+
end
|
63
|
+
|
56
64
|
def buildizer_conf
|
57
65
|
@buildizer_conf ||= (YAML.load((buildizer_conf_path.read rescue "")) || {})
|
58
66
|
end
|
@@ -155,12 +163,13 @@ git add -v .travis.yml
|
|
155
163
|
buildizer_conf['package_version']
|
156
164
|
end
|
157
165
|
|
158
|
-
def
|
159
|
-
ENV['
|
166
|
+
def package_version_tag_required_for_deploy?
|
167
|
+
ENV['BUILDIZER_REQUIRE_TAG'].to_s.on?
|
160
168
|
end
|
161
169
|
|
162
|
-
def
|
163
|
-
|
170
|
+
def package_version_tag
|
171
|
+
res = ENV['TRAVIS_TAG'] || ENV['CI_BUILD_TAG']
|
172
|
+
if res.nil? then res elsif res.empty? then nil else res end
|
164
173
|
end
|
165
174
|
|
166
175
|
def before_prepare
|
@@ -199,40 +208,46 @@ git add -v .travis.yml
|
|
199
208
|
buildizer_conf['image']
|
200
209
|
end
|
201
210
|
|
202
|
-
def
|
203
|
-
|
211
|
+
def package_cloud_repo
|
212
|
+
ENV['PACKAGECLOUD'].to_s.split(',')
|
204
213
|
end
|
205
214
|
|
206
|
-
def
|
207
|
-
ENV['PACKAGECLOUD_TOKEN']
|
208
|
-
|
209
|
-
|
215
|
+
def package_cloud_org
|
216
|
+
default_token = ENV['PACKAGECLOUD_TOKEN']
|
217
|
+
package_cloud_repo.map {|repo| repo.split('/').first}.uniq.map do |org|
|
218
|
+
[org, ENV["PACKAGECLOUD_TOKEN_#{org.upcase}"] || default_token]
|
219
|
+
end.to_h
|
210
220
|
end
|
211
221
|
|
212
|
-
def
|
213
|
-
|
214
|
-
|
222
|
+
def package_cloud
|
223
|
+
tokens = package_cloud_org
|
224
|
+
package_cloud_repo.map do |repo|
|
225
|
+
org = repo.split('/').first
|
226
|
+
token = tokens[org]
|
227
|
+
{org: org, repo: repo, token: token}
|
215
228
|
end
|
216
229
|
end
|
217
230
|
|
218
|
-
def
|
219
|
-
ENV['
|
220
|
-
|
221
|
-
|
231
|
+
def docker_cache
|
232
|
+
return unless org = ENV['BUILDIZER_DOCKER_CACHE']
|
233
|
+
{username: ENV['BUILDIZER_DOCKER_CACHE_USERNAME'],
|
234
|
+
password: ENV['BUILDIZER_DOCKER_CACHE_PASSWORD'],
|
235
|
+
email: ENV['BUILDIZER_DOCKER_CACHE_EMAIL'],
|
236
|
+
server: ENV['BUILDIZER_DOCKER_CACHE_SERVER'],
|
237
|
+
org: org}
|
222
238
|
end
|
223
239
|
|
224
|
-
def
|
225
|
-
|
226
|
-
raise Error, error: :input_error, message: "BUILDIZER_DOCKER_EMAIL env variable required"
|
227
|
-
end
|
240
|
+
def maintainer
|
241
|
+
buildizer_conf['maintainer']
|
228
242
|
end
|
229
243
|
|
230
244
|
def builder
|
231
245
|
@builder ||= begin
|
232
246
|
build_type = buildizer_conf['build_type']
|
233
|
-
raise Error, error: :input_error, message: "
|
247
|
+
raise Error, error: :input_error, message: "build_type is not defined" unless build_type
|
234
248
|
klass = {fpm: Builder::Fpm,
|
235
|
-
native: Builder::Native
|
249
|
+
native: Builder::Native,
|
250
|
+
patch: Builder::Patch}[build_type.to_s.to_sym]
|
236
251
|
raise Error, error: :input_error, message: "unknown build_type '#{build_type}'" unless klass
|
237
252
|
klass.new(self)
|
238
253
|
end
|