dodebui-former03 0.0.4

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.
@@ -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: []