dodebui-former03 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c5f6481fe1c287c4f2938ee7d9c1f140ecc2a851
4
+ data.tar.gz: bb7f4ea900128a70e1440e6bc1fa5b7e48b5ee5b
5
+ SHA512:
6
+ metadata.gz: d5493b9b5282d1f7630e85bcef3048e8321cc60488d3a97b2b37b2f5ee2be96eb902d757abdb90670901ea4a2908c98de23fa002e0f5b39bc3bc0edb52ec3adc
7
+ data.tar.gz: d6ea57d4eaaf587c7174ba167a94cf6a193c10a9033a60ffd80574059e47ef5560a1b0175e4526386d8c241b6c0052b0ce2a607b57cd646694d153669662070b
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
@@ -0,0 +1,4 @@
1
+ Metrics/ClassLength:
2
+ Max: 250
3
+ Metrics/MethodLength:
4
+ Max: 20
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in dodebui.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Christian Simon
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,66 @@
1
+ # Dodebui
2
+
3
+ Debian Docker builder
4
+
5
+ This tool helps to build Debian binary packages for multiple distribution
6
+ releases.
7
+
8
+ ## Features
9
+
10
+ ### Implemented
11
+
12
+ * build multiple a package for multiple releases in parallel
13
+ * use docker containers for isolation
14
+ * install dependencies automatically
15
+ * use a apt cache for minimizing download times
16
+
17
+ ### Planned
18
+
19
+ * Cache images after dependency installation for faster build times
20
+
21
+ ## Installation
22
+
23
+ Add this Gemfile to your debian packge:
24
+
25
+ ```ruby
26
+ source 'https://rubygems.org'
27
+ gem 'dodebui'
28
+ ```
29
+
30
+ And then execute:
31
+
32
+ $ bundle install
33
+
34
+ Now create your Dodebuifile in project root:
35
+
36
+ ```ruby
37
+ # vim: ft=ruby
38
+
39
+ # Configure distributions to build
40
+ @build_distributions = [
41
+ 'debian:wheezy',
42
+ 'debian:jessie',
43
+ 'debian:squeeze',
44
+ 'ubuntu:precise',
45
+ 'ubuntu:trusty',
46
+ ]
47
+
48
+ # Configure a apt-proxy (warmly recommended)
49
+ #@apt_proxy = 'http://my-apt-proxy.com/'
50
+ ```
51
+
52
+ ## Usage
53
+
54
+ $ bundle exec dodebui
55
+
56
+ ## Example project
57
+
58
+ https://github.com/simonswine/dodebui-package-hello
59
+
60
+ ## Contributing
61
+
62
+ 1. Fork it ( https://github.com/[my-github-username]/dodebui/fork )
63
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
64
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
65
+ 4. Push to the branch (`git push origin my-new-feature`)
66
+ 5. Create a new Pull Request
@@ -0,0 +1,3 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rubocop/rake_task'
3
+ RuboCop::RakeTask.new
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'dodebui/cli'
3
+ Dodebui::Cli.new.run
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dodebui/version'
5
+
6
+ desc = 'Docker Debian builder (DoDeBui): '
7
+ desc += 'Builds debian packages in Docker containers'
8
+
9
+ Gem::Specification.new do |spec|
10
+ spec.name = 'dodebui-former03'
11
+ spec.version = Dodebui::VERSION
12
+ spec.authors = ['Christian Simon']
13
+ spec.email = ['simon@swine.de']
14
+ spec.summary = desc
15
+ spec.description = desc
16
+ spec.homepage = 'https://github.com/simonswine/dodebui'
17
+ spec.license = 'GPLv3'
18
+ spec.files = `git ls-files -z`.split("\x0")
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_dependency 'docker-api'
24
+ spec.add_development_dependency 'bundler', '~> 1.7'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'rubocop', '~> 0.30'
27
+ end
@@ -0,0 +1,4 @@
1
+ require 'dodebui/version'
2
+ # rubocop:disable Style/AvoidFor
3
+ module Dodebui
4
+ end
@@ -0,0 +1,237 @@
1
+ require 'dodebui/template_namespace'
2
+ require 'open3'
3
+ require 'erb'
4
+
5
+ module Dodebui
6
+ # Handles the build process of a package
7
+ class Build
8
+ attr_reader :distribution
9
+
10
+ def initialize(distribution)
11
+ @distribution = distribution
12
+ @cli = distribution.cli
13
+ end
14
+
15
+ def local_expect(desc, *args)
16
+ Open3.popen3(*args) do |_i, o, e, t|
17
+ if args[0].is_a? Hash
18
+ cmd = args[1]
19
+ else
20
+ cmd = args[0]
21
+ end
22
+ ret_val = t.value.exitstatus
23
+ if ret_val == 0
24
+ logger.debug("#{desc} (cmd=#{cmd}): succeed")
25
+ else
26
+ output = "Exec failed cmd=#{cmd} ret_val=#{ret_val}"
27
+ output += "stdout=#{o.read} stderr=#{e.read}"
28
+ fail output
29
+ end
30
+ end
31
+ end
32
+
33
+ def write_log(name, o, e)
34
+ o_path = File.join(build_dir, "#{name}.stdout.log")
35
+ e_path = File.join(build_dir, "#{name}.stderr.log")
36
+ File.open(o_path, 'w') { |file| file.write(o.join '') }
37
+ File.open(e_path, 'w') { |file| file.write(e.join '') }
38
+ end
39
+
40
+ def build_container_create_start
41
+ logger.info("Creating container #{@distribution.codename}")
42
+ @container = Docker::Container.create(
43
+ 'Image' => @distribution.image_name,
44
+ 'Cmd' => %w(sleep 3600),
45
+ 'WorkingDir' => '/_build/source'
46
+ )
47
+ logger.info("Starting container #{@distribution.codename}")
48
+ @container.start('Binds' => [
49
+ "#{build_dir}:/_build"
50
+ ])
51
+ end
52
+
53
+ def build_dependencies
54
+ logger.info("Installing dependencies #{@distribution.codename}")
55
+ stdout, stderr, ret_val = @container.exec([
56
+ '/usr/lib/pbuilder/pbuilder-satisfydepends-aptitude'
57
+ ])
58
+ write_log('apt_install_deps', stdout, stderr)
59
+ if ret_val != 0
60
+ logger.warn("Failed installing dependencies #{@distribution.codename}")
61
+ fail
62
+ end
63
+ logger.info("Finished installing dependencies #{@distribution.codename}")
64
+ end
65
+
66
+ def build_package
67
+ logger.info("Building package #{@distribution.codename}")
68
+ stdout, stderr, ret_val = @container.exec([
69
+ 'dpkg-buildpackage'
70
+ ])
71
+ write_log('build', stdout, stderr)
72
+ if ret_val != 0
73
+ logger.warn("Failed building package #{@distribution.codename}")
74
+ fail
75
+ end
76
+ logger.info("Finished building package #{@distribution.codename}")
77
+ end
78
+
79
+ def build_apt_proxy
80
+ return if @cli.apt_proxy.nil?
81
+ logger.info("Setting apt_proxy #{@distribution.codename}")
82
+ stdout, stderr, ret_val = @container.exec([
83
+ 'bash',
84
+ '-c',
85
+ @distribution.apt_proxy
86
+ ])
87
+ write_log('apt_proxy', stdout, stderr)
88
+ logger.warn(
89
+ "Failed setting apt proxy #{@distribution.codename}"
90
+ ) if ret_val != 0
91
+ end
92
+
93
+ def build_chown
94
+ uid = Process.uid
95
+ gid = Process.gid
96
+ logger.info(
97
+ 'Changing owner of build dir to' \
98
+ " uid=#{uid} gid=#{gid} #{@distribution.codename}"
99
+ )
100
+ stdout, stderr, ret_val = @container.exec([
101
+ 'chown',
102
+ '-R',
103
+ format('%d:%d', uid, gid),
104
+ '/_build'
105
+ ])
106
+ write_log('chown', stdout, stderr)
107
+ logger.warn(
108
+ "Failed changing owner of build dir #{@distribution.codename}"
109
+ ) if ret_val != 0
110
+ end
111
+
112
+ def build_error(e)
113
+ logger.warn("Error building #{@distribution.image_name}: #{e}")
114
+ return false if @container.nil?
115
+ logger.warn("Use container id=#{@container.id} to debug")
116
+ @container.stop
117
+ false
118
+ end
119
+
120
+ def build
121
+ build_container_create_start
122
+
123
+ build_apt_proxy
124
+
125
+ build_dependencies
126
+
127
+ build_package
128
+
129
+ build_chown
130
+
131
+ @container.stop
132
+
133
+ @container.remove
134
+
135
+ true
136
+ rescue RuntimeError => e
137
+ build_error(e)
138
+ end
139
+
140
+ def cache_dir
141
+ File.expand_path(
142
+ File.join(
143
+ '/var/lib/dodebui',
144
+ "#{distribution.os}_#{distribution.codename}"
145
+ )
146
+ )
147
+ end
148
+
149
+ def build_dir
150
+ File.expand_path(
151
+ File.join(
152
+ @cli.wd,
153
+ '..',
154
+ '_build',
155
+ "#{distribution.os}_#{distribution.codename}"
156
+ )
157
+ )
158
+ end
159
+
160
+ def source
161
+ source_copy
162
+ source_changelog
163
+ source_templates
164
+ end
165
+
166
+ def logger
167
+ @cli.logger
168
+ end
169
+
170
+ def source_dir
171
+ File.join(build_dir, 'source')
172
+ end
173
+
174
+ def source_template_namespace
175
+ TemplateNamespace.new(
176
+ os: @distribution.os,
177
+ codename: @distribution.codename,
178
+ codename_int: @distribution.codename_int
179
+ )
180
+ end
181
+
182
+ def source_template_eval(path)
183
+ logger.debug "Evaluate template #{path}"
184
+ erb = ERB.new(
185
+ File.read(path),
186
+ nil,
187
+ '-'
188
+ )
189
+ erb.result(source_template_namespace.priv_binding)
190
+ end
191
+
192
+ def source_templates
193
+ return if @cli.source_templates.nil?
194
+ @cli.source_templates.each do |template|
195
+ src = File.join(source_dir, template)
196
+ dest = src[0...-4]
197
+ File.open(dest, 'w') do |file|
198
+ file.write(source_template_eval(src))
199
+ end
200
+ sh "chmod +x #{template}" if template == 'debian/rules'
201
+ end
202
+ end
203
+
204
+ def source_copy
205
+ logger.debug "Start copying sources to #{source_dir}"
206
+ FileUtils.mkdir_p build_dir
207
+ FileUtils.rm_rf source_dir
208
+ FileUtils.cp_r @cli.wd, source_dir
209
+ logger.debug "Finished copying sources to #{source_dir}"
210
+ end
211
+
212
+ def source_changelog_dch(path)
213
+ output = 'dch --changelog %{path} -l "+%{cn_str}%{cn}" -D "%{cn}" '
214
+ output += '--force-distribution '
215
+ output += '"Build a changelog entry for %{cn} %{cn}"'
216
+
217
+ output % {
218
+ cn: @distribution.codename,
219
+ cn_str: @distribution.codename_str,
220
+ path: path
221
+ }
222
+ end
223
+
224
+ def source_changelog
225
+ path = File.join(source_dir, 'debian/changelog')
226
+ logger.debug "Modify changelog file #{path}"
227
+ local_expect(
228
+ 'append distribution build to changelog',
229
+ {
230
+ 'DEBFULLNAME' => 'Jenkins Autobuilder',
231
+ 'DEBEMAIL' => 'jenkins@former03.de'
232
+ },
233
+ source_changelog_dch(path)
234
+ )
235
+ end
236
+ end
237
+ end
@@ -0,0 +1,147 @@
1
+ require 'dodebui/version'
2
+ require 'dodebui/distribution'
3
+ require 'logger'
4
+ require 'docker'
5
+
6
+ module Dodebui
7
+ ## commandline interface for dodebui
8
+ class Cli
9
+ attr_accessor :source_templates, :build_distributions, :apt_proxy
10
+ attr_reader :wd
11
+
12
+ def self.logger
13
+ @logger ||= Logger.new(STDOUT)
14
+ end
15
+
16
+ def initialize
17
+ @dodebuifiles ||= ['Dodebuifile']
18
+ @original_dir = Dir.getwd
19
+ @distributions_sem = Mutex.new
20
+ end
21
+
22
+ def dodebuifile?
23
+ @dodebuifiles.each do |fn|
24
+ return fn if File.exist?(fn)
25
+ end
26
+ nil
27
+ end
28
+
29
+ def find_dodebuifile_location # :nodoc:
30
+ here = Dir.pwd
31
+ until (fn = dodebuifile?)
32
+ Dir.chdir('..')
33
+ return nil if Dir.pwd == here
34
+ here = Dir.pwd
35
+ end
36
+ [fn, here]
37
+ ensure
38
+ Dir.chdir(@original_dir)
39
+ end
40
+
41
+ def load_dodebiufile
42
+ dodebuifile, location = find_dodebuifile_location
43
+ fail 'No Dodebuifile found' if dodebuifile.nil?
44
+ @dodebuifile = File.join(location, dodebuifile)
45
+ @wd = location
46
+ Cli.logger.info("Working directory #{@wd}")
47
+ Cli.logger.info("Config file #{@dodebuifile}")
48
+ load_dodebiufile_raw @dodebuifile
49
+ end
50
+
51
+ def load_dodebiufile_raw(path)
52
+ File.open(path, 'r') do |infile|
53
+ code = infile.read
54
+ eval(code) # rubocop:disable Lint/Eval
55
+ end
56
+ end
57
+
58
+ def check_outcome
59
+ return if @distributions.length == build_distributions.length
60
+ logger.error(
61
+ "Only built #{@distributions.length} out of " \
62
+ "#{build_distributions.length}"
63
+ )
64
+ exit 1
65
+ end
66
+
67
+ def run
68
+ Cli.logger.info("Initializing dodebui #{VERSION}")
69
+
70
+ load_dodebiufile
71
+
72
+ test_docker
73
+
74
+ prepare_distributions build_distributions
75
+
76
+ prepare_sources
77
+
78
+ build
79
+
80
+ check_outcome
81
+ end
82
+
83
+ def test_docker
84
+ Docker.options[:read_timeout] = 3600
85
+ data = Docker.version
86
+ Cli.logger.info(
87
+ "Connecting to Docker server successful (version #{data['Version']})"
88
+ )
89
+ end
90
+
91
+ def logger
92
+ Cli.logger
93
+ end
94
+
95
+ def prepare_distributions(distributions = [])
96
+ @distributions = distributions.map do |name|
97
+ Distribution.new(name, self)
98
+ end
99
+ ensure_images_updated
100
+ end
101
+
102
+ def ensure_images_updated
103
+ # ensure images are up to date
104
+ threads = []
105
+ @distributions.each do |dist|
106
+ threads << Thread.new do
107
+ begin
108
+ dist.ensure_image_updated
109
+ rescue => e
110
+ logger.warn(
111
+ "Failed ensuring a updated image '#{dist.image_name}': #{e}"
112
+ )
113
+ @distributions_sem.synchronize do
114
+ @distributions -= [dist]
115
+ end
116
+ end
117
+ end
118
+ end
119
+ # wait for all threads
120
+ threads.each(&:join)
121
+ end
122
+
123
+ def prepare_sources
124
+ @distributions.each do |dist|
125
+ dist.build.source
126
+ end
127
+ end
128
+
129
+ def build
130
+ threads = []
131
+ @distributions.each do |dist|
132
+ threads << Thread.new do
133
+ begin
134
+ dist.build.build
135
+ rescue => e
136
+ logger.warn("Failed building on image '#{dist.image_name}': #{e}")
137
+ @distributions_sem.synchronize do
138
+ @distributions -= [dist]
139
+ end
140
+ end
141
+ end
142
+ end
143
+ # wait for all threads
144
+ threads.each(&:join)
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,188 @@
1
+ require 'date'
2
+ require 'docker'
3
+ require 'dodebui/build'
4
+ # docker debian build
5
+ module Dodebui
6
+ MAX_IMAGE_AGE = 86_400
7
+
8
+ DISTRIBUTIONS = {
9
+ debian: [
10
+ :squeeze,
11
+ :wheezy,
12
+ :jessie
13
+ ],
14
+ ubuntu: [
15
+ :precise,
16
+ :quantal,
17
+ :raring,
18
+ :saucy,
19
+ :trusty,
20
+ :xenial
21
+ ]
22
+ }
23
+
24
+ # handle distribution releases
25
+ class Distribution
26
+ attr_reader :os, :codename, :cli
27
+ def initialize(name, cli)
28
+ @cli = cli
29
+ # convert string
30
+ if name.is_a? String
31
+ split = name.split(':')
32
+ os = split[0].to_sym
33
+ codename = split[1].to_sym
34
+ end
35
+
36
+ if (!DISTRIBUTIONS.key? os) || (!DISTRIBUTIONS[os].include? codename)
37
+ fail "Operating system #{os} with codename #{codename} not found"
38
+ end
39
+ @os = os
40
+ @codename = codename
41
+ end
42
+
43
+ def logger
44
+ @cli.logger
45
+ end
46
+
47
+ def codename_str
48
+ format('%02d', codename_int)
49
+ end
50
+
51
+ def codename_int
52
+ DISTRIBUTIONS[os].index(codename) + 1
53
+ end
54
+
55
+ def image_age(i)
56
+ age = DateTime.now - DateTime.parse(i.info['Created'])
57
+ (age * 24 * 60 * 60).to_i
58
+ end
59
+
60
+ def ensure_image_updated
61
+ # Test if image_name exists
62
+ @image = Docker::Image.get(image_name)
63
+ if image_age(@image) > MAX_IMAGE_AGE
64
+ logger.info "Image #{image_name} is outdated renew it"
65
+ @image = create_image
66
+ end
67
+ rescue Docker::Error::NotFoundError
68
+ @image = create_image
69
+ end
70
+
71
+ def pbuilder_files
72
+ [
73
+ 'pbuilder-satisfydepends-aptitude',
74
+ 'pbuilder-satisfydepends-checkparams',
75
+ 'pbuilder-satisfydepends-funcs'
76
+ ]
77
+ end
78
+
79
+ def share_path
80
+ File.expand_path(
81
+ File.join(
82
+ File.expand_path(
83
+ File.dirname(__FILE__)
84
+ ),
85
+ '../../share'
86
+ )
87
+ )
88
+ end
89
+
90
+ def pbuilder_dir
91
+ '/usr/lib/pbuilder'
92
+ end
93
+
94
+ def apt_proxy
95
+ (
96
+ 'echo ' \
97
+ '"Acquire::http::Proxy ' \
98
+ '\"%s\";" ' \
99
+ '> ' \
100
+ '/etc/apt/apt.conf.d/01proxy'
101
+ ) % @cli.apt_proxy
102
+ end
103
+
104
+ def create_image_dockerfile_contents
105
+ dockerfile = "FROM #{base_image_name}\n"
106
+
107
+ # append proxy if needed
108
+ dockerfile += "RUN #{apt_proxy}\n" unless @cli.apt_proxy.nil?
109
+
110
+ dockerfile += (
111
+ "ENV DEBIAN_FRONTEND=noninteractive\n" \
112
+ "RUN apt-get update && \\ \n" \
113
+ " apt-get -y dist-upgrade && \\ \n" \
114
+ " apt-get -y install wget curl build-essential aptitude \n" \
115
+ "RUN mkdir -p #{pbuilder_dir}\n"
116
+ )
117
+
118
+ # add pbuilder dep resolver
119
+ pbuilder_files.each do |file|
120
+ dockerfile += "ADD #{file} #{pbuilder_dir}/#{file}\n"
121
+ end
122
+
123
+ # make dep resolver executable
124
+ dockerfile += 'RUN chmod +x '
125
+ dockerfile += "#{pbuilder_dir}/pbuilder-satisfydepends-aptitude\n"
126
+ dockerfile
127
+ end
128
+
129
+ def create_image_copy_dep_resolver(dir)
130
+ pbuilder_files.each do |file|
131
+ src = File.join(share_path, 'pbuilder', file)
132
+ dest = File.join(dir, file)
133
+ logger.debug("Copy file from #{src} to #{dest}")
134
+ FileUtils.cp src, dest
135
+ end
136
+ end
137
+
138
+ def create_image_build(dir)
139
+ image = Docker::Image.build_from_dir(
140
+ dir,
141
+ nocache: true
142
+ )
143
+
144
+ logger.info(
145
+ "Finished building a new image #{image_name} from #{base_image_name}"
146
+ )
147
+ image.tag(
148
+ repo: repo_name,
149
+ tag: @codename.to_s,
150
+ force: true
151
+ )
152
+ end
153
+
154
+ def create_image
155
+ logger.info("Start building a new image from #{base_image_name}")
156
+
157
+ # build docker build directory
158
+ Dir.mktmpdir do |dir|
159
+ # Write docker file
160
+ dockerfile_path = File.join(dir, 'Dockerfile')
161
+ File.open(dockerfile_path, 'w') do |file|
162
+ file.write(create_image_dockerfile_contents)
163
+ end
164
+
165
+ create_image_copy_dep_resolver(dir)
166
+
167
+ # build image
168
+ create_image_build(dir)
169
+ end
170
+ end
171
+
172
+ def build
173
+ @build ||= Build.new self
174
+ end
175
+
176
+ def repo_name
177
+ "dodebui_#{@os}"
178
+ end
179
+
180
+ def base_image_name
181
+ "#{@os}:#{@codename}"
182
+ end
183
+
184
+ def image_name
185
+ "#{repo_name}:#{@codename}"
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,14 @@
1
+ module Dodebui
2
+ # namespace for evaluationg templates
3
+ class TemplateNamespace
4
+ def initialize(hash)
5
+ hash.each do |key, value|
6
+ singleton_class.send(:define_method, key) { value }
7
+ end
8
+ end
9
+
10
+ def priv_binding
11
+ binding
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,4 @@
1
+ # version of gem
2
+ module Dodebui
3
+ VERSION = '0.0.4'
4
+ end
@@ -0,0 +1,121 @@
1
+ #!/bin/bash
2
+ # pbuilder -- personal Debian package builder
3
+ # Copyright (C) 2001,2002,2003,2005-2007 Junichi Uekawa
4
+ # Copyright (C) 2007 Loïc Minier
5
+ #
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
+ #
20
+ # module to satisfy build dependencies; aptitude flavor
21
+
22
+ set -e
23
+
24
+ export PBUILDER_PKGLIBDIR="${PBUILDER_PKGLIBDIR:-$PBUILDER_ROOT/usr/lib/pbuilder}"
25
+
26
+ . "$PBUILDER_PKGLIBDIR"/pbuilder-satisfydepends-funcs
27
+
28
+
29
+ # filter out dependencies sent on input not for this arch; deps can have
30
+ # multiple lines; output is on a single line or "" if empty
31
+ function filter_arch_deps() {
32
+ local arch="$1"
33
+ local INSTALLPKGMULTI
34
+ local INSTALLPKG
35
+
36
+ # split on ","
37
+ sed 's/[[:space:]]*,[[:space:]]*/\n/g' |
38
+ while read INSTALLPKGMULTI; do
39
+ echo "$INSTALLPKGMULTI" |
40
+ # split on "|"
41
+ sed 's/[[:space:]]*|[[:space:]]*/\n/g' |
42
+ while read INSTALLPKG; do
43
+ if echo "$INSTALLPKG" | grep -q '\['; then
44
+ if checkbuilddep_archdeps "$INSTALLPKG" "$ARCH"; then
45
+ continue
46
+ fi
47
+ fi
48
+ # output the selected package
49
+ echo "$INSTALLPKG"
50
+ done |
51
+ # remove the arch list and add " | " between entries
52
+ sed 's/\[.*\]//; $,$! s/$/ |/' |
53
+ xargs --no-run-if-empty
54
+ done |
55
+ # add ", " between entries
56
+ sed '$,$! s/$/,/' |
57
+ xargs --no-run-if-empty
58
+ }
59
+
60
+ function checkbuilddep_internal () {
61
+ # Use this function to fulfill the dependency (almost)
62
+ local ARCH=$($CHROOTEXEC dpkg-architecture -qDEB_HOST_ARCH)
63
+ local BUILD_DEP_DEB_DIR
64
+ local BUILD_DEP_DEB_CONTROL
65
+ local DEPENDS
66
+ local CONFLICTS
67
+ echo " -> Attempting to satisfy build-dependencies"
68
+ DEPENDS="$(get_build_deps | filter_arch_deps "$ARCH")"
69
+ CONFLICTS="$(get_build_conflicts | filter_arch_deps "$ARCH")"
70
+ echo " -> Creating pbuilder-satisfydepends-dummy package"
71
+ BUILD_DEP_DEB_DIR="/tmp/satisfydepends-aptitude"
72
+ BUILD_DEP_DEB_CONTROL="$BUILD_DEP_DEB_DIR/pbuilder-satisfydepends-dummy/DEBIAN/control"
73
+ $CHROOTEXEC mkdir -p "$BUILD_DEP_DEB_DIR/pbuilder-satisfydepends-dummy/DEBIAN/"
74
+ $CHROOTEXEC sh -c "cat >\"$BUILD_DEP_DEB_CONTROL\"" <<EOF
75
+ Package: pbuilder-satisfydepends-dummy
76
+ Version: 0.invalid.0
77
+ Architecture: $ARCH
78
+ Maintainer: Debian Pbuilder Team <pbuilder-maint@lists.alioth.debian.org>
79
+ Description: Dummy package to satisfy dependencies with aptitude - created by pbuilder
80
+ This package was created automatically by pbuilder to satisfy the
81
+ build-dependencies of the package being currently built.
82
+ EOF
83
+ if [ -n "$DEPENDS" ]; then
84
+ $CHROOTEXEC sh -c "echo \"Depends: $DEPENDS\" >>\"$BUILD_DEP_DEB_CONTROL\""
85
+ fi
86
+ if [ -n "$CONFLICTS" ]; then
87
+ $CHROOTEXEC sh -c "echo \"Conflicts: $CONFLICTS\" >>\"$BUILD_DEP_DEB_CONTROL\""
88
+ fi
89
+ $CHROOTEXEC sh -c "cat \"$BUILD_DEP_DEB_CONTROL\""
90
+ $CHROOTEXEC sh -c "dpkg-deb -b \"$BUILD_DEP_DEB_DIR/pbuilder-satisfydepends-dummy\""
91
+ $CHROOTEXEC dpkg -i "$BUILD_DEP_DEB_DIR/pbuilder-satisfydepends-dummy.deb" || true
92
+ $CHROOTEXEC aptitude -y --without-recommends -o APT::Install-Recommends=false "${PBUILDER_APTITUDE_CHECK_OPTS[@]}" -o Aptitude::ProblemResolver::StepScore=100 install pbuilder-satisfydepends-dummy
93
+ # check whether the aptitude's resolver kept the package
94
+ if ! $CHROOTEXEC dpkg -l pbuilder-satisfydepends-dummy 2>/dev/null | grep -q ^ii; then
95
+ echo "Aptitude couldn't satisfy the build dependencies"
96
+ exit 1
97
+ fi
98
+ echo " -> Finished parsing the build-deps"
99
+ }
100
+
101
+
102
+ function print_help () {
103
+ # print out help message
104
+ cat <<EOF
105
+ pbuilder-satisfydepends -- satisfy dependencies
106
+ Copyright 2002-2007 Junichi Uekawa <dancer@debian.org>
107
+
108
+ --help: give help
109
+ --control: specify control file (debian/control, *.dsc)
110
+ --chroot: operate inside chroot
111
+ --binary-all: include binary-all
112
+ --binary-arch: include binary-arch only
113
+ --echo: echo mode, do nothing. (--force-version required for most operation)
114
+ --force-version: skip version check.
115
+ --continue-fail: continue even when failed.
116
+
117
+ EOF
118
+ }
119
+
120
+ . "$PBUILDER_PKGLIBDIR"/pbuilder-satisfydepends-checkparams
121
+
@@ -0,0 +1,94 @@
1
+ #!/bin/bash
2
+ # pbuilder -- personal Debian package builder
3
+ # Copyright (C) 2001,2002,2003,2005-2007 Junichi Uekawa
4
+ #
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 2 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
+ #
19
+ # module to satisfy build dependencies; parse command line parameters
20
+
21
+
22
+ DEBIAN_CONTROL=debian/control
23
+ CHROOT=""
24
+ CHROOTEXEC=""
25
+ BINARY_ARCH="no"
26
+ FORCEVERSION=""
27
+ CONTINUE_FAIL="no"
28
+ CHROOTEXEC_AFTER_INTERNAL_CHROOTEXEC=no
29
+
30
+ # aptitude flag to ignore key verification
31
+ PBUILDER_APTITUDE_CHECK_OPTS=(
32
+ '-o'
33
+ 'Aptitude::CmdLine::Ignore-Trust-Violations=true' )
34
+ # apt flag to ignore key verification
35
+ PBUILDER_APT_GET_CHECK_OPTS="--force-yes"
36
+
37
+ while [ -n "$1" ]; do
38
+ case "$1" in
39
+ --control|-c)
40
+ DEBIAN_CONTROL="$2"
41
+ shift; shift
42
+ ;;
43
+
44
+ # --chroot option and --internal-chrootexec options and --echo options somewhat conflict with each other.
45
+
46
+ --chroot)
47
+ CHROOT="$2"
48
+ CHROOTEXEC="chroot $2 "
49
+ if [ ${CHROOTEXEC_AFTER_INTERNAL_CHROOTEXEC} = maybe ]; then
50
+ echo '--chroot specified after --internal-chrootexec' >&2
51
+ exit 1
52
+ fi
53
+ shift; shift
54
+ ;;
55
+ --internal-chrootexec)
56
+ CHROOTEXEC="$2"
57
+ CHROOTEXEC_AFTER_INTERNAL_CHROOTEXEC=maybe
58
+ shift; shift
59
+ ;;
60
+ --echo)
61
+ CHROOTEXEC="echo $CHROOTEXEC"
62
+ CHROOTEXEC_AFTER_INTERNAL_CHROOTEXEC=maybe
63
+ shift
64
+ ;;
65
+
66
+ --binary-all)
67
+ BINARY_ARCH="no"
68
+ shift
69
+ ;;
70
+ --binary-arch)
71
+ BINARY_ARCH="yes"
72
+ shift
73
+ ;;
74
+ --continue-fail)
75
+ CONTINUE_FAIL="yes"
76
+ shift
77
+ ;;
78
+ --force-version)
79
+ FORCEVERSION="yes"
80
+ shift;
81
+ ;;
82
+ --check-key)
83
+ unset PBUILDER_APTITUDE_CHECK_OPTS
84
+ unset PBUILDER_APT_GET_CHECK_OPTS
85
+ shift;
86
+ ;;
87
+ --help|-h|*)
88
+ print_help
89
+ exit 1
90
+ ;;
91
+ esac
92
+ done
93
+
94
+ checkbuilddep_internal
@@ -0,0 +1,206 @@
1
+ #!/bin/bash
2
+ # pbuilder -- personal Debian package builder
3
+ # Copyright (C) 2001,2002,2003,2005-2007 Junichi Uekawa
4
+ # Copyright (C) 2007 Loïc Minier
5
+ #
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
+ #
20
+ # module to satisfy build dependencies; common functions
21
+
22
+
23
+ package_versions() {
24
+ local PACKAGE="$1"
25
+ LC_ALL=C $CHROOTEXEC /usr/bin/apt-cache show "$PACKAGE" | sed -n 's/^Version: //p'
26
+ }
27
+
28
+ candidate_version() {
29
+ local PACKAGE="$1"
30
+ LC_ALL=C $CHROOTEXEC apt-cache policy "$PACKAGE" | sed -n 's/ *Candidate: //p'
31
+ }
32
+
33
+ checkbuilddep_versiondeps() {
34
+ local PACKAGE="$1"
35
+ local COMPARESTRING="$2"
36
+ local DEPSVERSION="$3"
37
+ local PACKAGEVERSIONS=$( package_versions "$PACKAGE" | xargs)
38
+ # no versioned provides.
39
+ if [ "${FORCEVERSION}" = "yes" ]; then
40
+ return 0;
41
+ fi
42
+ for PACKAGEVERSION in $PACKAGEVERSIONS ; do
43
+ if dpkg --compare-versions "$PACKAGEVERSION" "$COMPARESTRING" "$DEPSVERSION"; then
44
+ # satisfies depends
45
+ return 0;
46
+ fi
47
+ done
48
+ echo " Tried versions: $PACKAGEVERSIONS"
49
+ # cannot satisfy depends
50
+ return 1;
51
+ }
52
+
53
+ get_source_control_field() {
54
+ local field="$1"
55
+
56
+ sed -n -e "s/^$field://i" -e '
57
+ t store
58
+ /^-----BEGIN PGP SIGNED MESSAGE-----$/ {
59
+ : pgploop
60
+ n
61
+ /^$/ d
62
+ b pgploop
63
+ }
64
+ /^$/q
65
+ d
66
+ : store
67
+ H
68
+ : loop
69
+ n
70
+ /^#/ b loop
71
+ /^[ \t]/ b store
72
+ x
73
+ # output on single line
74
+ s/\n//g
75
+ # change series of tabs and spaces into a space
76
+ s/[\t ]\+/ /g
77
+ # normalize space before and after commas
78
+ s/ *, */, /g
79
+ # normalize space before and after pipes
80
+ s/ *| */ | /g
81
+ # normalize space before and after parentheses
82
+ s/ *( */ (/g
83
+ s/ *) */)/g
84
+ # normalize space before and after brackets
85
+ s/ *\[ */ [/g
86
+ s/ *\] */]/g
87
+ # normalize space after exclamation mark
88
+ s/! */!/g
89
+ # normalize space between operator and version
90
+ s/(\(>>\|>=\|>\|==\|=\|<=\|<<\|<\|!=\) *\([^)]*\))/(\1 \2)/g
91
+ # normalize space at beginning and end of line
92
+ s/^ *//
93
+ s/ *$//
94
+ p' \
95
+ "$DEBIAN_CONTROL"
96
+ }
97
+
98
+ get_build_deps() {
99
+ local output
100
+
101
+ output="`get_source_control_field "Build-Depends"`"
102
+ output="${output%, }"
103
+ if [ "$BINARY_ARCH" = no ]; then
104
+ output="${output:+$output, }`get_source_control_field "Build-Depends-Indep"`"
105
+ output="${output%, }"
106
+ fi
107
+ echo "$output"
108
+ }
109
+
110
+ get_build_conflicts() {
111
+ local output
112
+
113
+ output="`get_source_control_field "Build-Conflicts"`"
114
+ if [ "$BINARY_ARCH" = no ]; then
115
+ output="${output:+$output, }`get_source_control_field "Build-Conflicts-Indep"`"
116
+ fi
117
+ echo "$output"
118
+ }
119
+
120
+ checkbuilddep_archdeps() {
121
+ # returns FALSE on INSTALL
122
+ local INSTALLPKG="$1"
123
+ local ARCH="$2"
124
+ # architectures listed between [ and ] for this dep
125
+ local DEP_ARCHES="$(echo "$INSTALLPKG" | sed 's/.*\[\(.*\)\].*/\1/')"
126
+ # check for !$ARCH in DEP_ARCHES
127
+ if echo "$DEP_ARCHES" | egrep -q "(^|[[:space:]/]+)\![[:space:]/]*$ARCH($|[[:space:]/]+)"; then
128
+ return 0;
129
+ fi
130
+ # check for a "!" which would mean there's a !<otherarch> and hence $ARCH
131
+ # is included
132
+ if ! echo "$DEP_ARCHES" | grep -q '!'; then
133
+ # check for $ARCH in DEP_ARCHES
134
+ if ! echo "$DEP_ARCHES" | egrep -q "(^|[[:space:]/]+)$ARCH($|[[:space:]/]+)"; then
135
+ return 0;
136
+ fi
137
+ fi
138
+ return 1;
139
+ }
140
+
141
+ checkbuilddep_provides() {
142
+ local PACKAGENAME="$1"
143
+ # PROVIDED needs to be used outside of this function.
144
+ PROVIDED=$($CHROOTEXEC /usr/bin/apt-cache showpkg $PACKAGENAME | awk '{p=0}/^Reverse Provides:/,/^$/{p=1}{if(p && ($0 !~ "Reverse Provides:")){PACKAGE=$1}} END{print PACKAGE}')
145
+ }
146
+
147
+ # returns either "package=version", to append to an apt-get install line, or
148
+ # package
149
+ versioneddep_to_aptcmd() {
150
+ local INSTALLPKG="$1"
151
+
152
+ local PACKAGE
153
+ local PACKAGE_WITHVERSION
154
+ local PACKAGEVERSIONS
155
+ local CANDIDATE_VERSION
156
+ local COMPARESTRING
157
+ local DEPSVERSION
158
+
159
+ PACKAGE="$(echo "$INSTALLPKG" | sed -e 's/^[/]*//' -e 's/[[/(].*//')"
160
+ PACKAGE_WITHVERSION="$PACKAGE"
161
+
162
+ # if not versionned, we skip directly to outputting $PACKAGE
163
+ if echo "$INSTALLPKG" | grep '[(]' > /dev/null; then
164
+ # package versions returned by APT, in reversed order
165
+ PACKAGEVERSIONS="$( package_versions "$PACKAGE" | tac | xargs )"
166
+ CANDIDATE_VERSION="$( candidate_version "$PACKAGE" )"
167
+
168
+ COMPARESTRING="$(echo "$INSTALLPKG" | tr "/" " " | sed 's/^.*( *\(<<\|<=\|>=\|=\|<\|>>\|>\) *\(.*\)).*$/\1/')"
169
+ DEPSVERSION="$(echo "$INSTALLPKG" | tr "/" " " | sed 's/^.*( *\(<<\|<=\|>=\|=\|<\|>>\|>\) *\(.*\)).*$/\2/')"
170
+ # if strictly versionned, we skip to outputting that version
171
+ if [ "=" = "$COMPARESTRING" ]; then
172
+ PACKAGE_WITHVERSION="$PACKAGE=$DEPSVERSION"
173
+ else
174
+ # try the candidate version, then all available versions (asc)
175
+ for VERSION in $CANDIDATE_VERSION $PACKAGEVERSIONS; do
176
+ if dpkg --compare-versions "$VERSION" "$COMPARESTRING" "$DEPSVERSION"; then
177
+ if [ $VERSION != $CANDIDATE_VERSION ]; then
178
+ PACKAGE_WITHVERSION="$PACKAGE=$VERSION"
179
+ fi
180
+ break;
181
+ fi
182
+ done
183
+ fi
184
+ fi
185
+
186
+ echo "$PACKAGE_WITHVERSION"
187
+ }
188
+
189
+ print_help() {
190
+ # print out help message
191
+ cat <<EOF
192
+ pbuilder-satisfydepends -- satisfy dependencies
193
+ Copyright 2002-2007 Junichi Uekawa <dancer@debian.org>
194
+
195
+ --help: give help
196
+ --control: specify control file (debian/control, *.dsc)
197
+ --chroot: operate inside chroot
198
+ --binary-all: include binary-all
199
+ --binary-arch: include binary-arch only
200
+ --echo: echo mode, do nothing. (--force-version required for most operation)
201
+ --force-version: skip version check.
202
+ --continue-fail: continue even when failed.
203
+
204
+ EOF
205
+ }
206
+
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dodebui-former03
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Christian Simon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-11-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: docker-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.30'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.30'
69
+ description: 'Docker Debian builder (DoDeBui): Builds debian packages in Docker containers'
70
+ email:
71
+ - simon@swine.de
72
+ executables:
73
+ - dodebui
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".rubocop.yml"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - bin/dodebui
84
+ - dodebui.gemspec
85
+ - lib/dodebui.rb
86
+ - lib/dodebui/build.rb
87
+ - lib/dodebui/cli.rb
88
+ - lib/dodebui/distribution.rb
89
+ - lib/dodebui/template_namespace.rb
90
+ - lib/dodebui/version.rb
91
+ - share/pbuilder/pbuilder-satisfydepends-aptitude
92
+ - share/pbuilder/pbuilder-satisfydepends-checkparams
93
+ - share/pbuilder/pbuilder-satisfydepends-funcs
94
+ homepage: https://github.com/simonswine/dodebui
95
+ licenses:
96
+ - GPLv3
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 2.5.1
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: 'Docker Debian builder (DoDeBui): Builds debian packages in Docker containers'
118
+ test_files: []