Class: Dodebui::Build

Inherits:
Object
  • Object
show all
Defined in:
lib/dodebui/build.rb

Overview

Handles the build process of a package

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(distribution) ⇒ Build

Returns a new instance of Build.



10
11
12
13
# File 'lib/dodebui/build.rb', line 10

def initialize(distribution)
  @distribution = distribution
  @cli = distribution.cli
end

Instance Attribute Details

#distributionObject (readonly)

Returns the value of attribute distribution.



8
9
10
# File 'lib/dodebui/build.rb', line 8

def distribution
  @distribution
end

Instance Method Details

#buildObject



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/dodebui/build.rb', line 120

def build
  build_container_create_start

  build_apt_proxy

  build_dependencies

  build_package

  build_chown

  @container.stop

  @container.remove

  true
rescue RuntimeError => e
  build_error(e)
end

#build_apt_proxyObject



79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/dodebui/build.rb', line 79

def build_apt_proxy
  return if @cli.apt_proxy.nil?
  logger.info("Setting apt_proxy #{@distribution.codename}")
  stdout, stderr, ret_val = @container.exec([
    'bash',
    '-c',
    @distribution.apt_proxy
  ])
  write_log('apt_proxy', stdout, stderr)
  logger.warn(
    "Failed setting apt proxy #{@distribution.codename}"
  ) if ret_val != 0
end

#build_chownObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/dodebui/build.rb', line 93

def build_chown
  uid = Process.uid
  gid = Process.gid
  logger.info(
    'Changing owner of build dir to' \
    " uid=#{uid} gid=#{gid} #{@distribution.codename}"
  )
  stdout, stderr, ret_val = @container.exec([
    'chown',
    '-R',
    format('%d:%d', uid, gid),
    '/_build'
  ])
  write_log('chown', stdout, stderr)
  logger.warn(
    "Failed changing owner of build dir #{@distribution.codename}"
  ) if ret_val != 0
end

#build_container_create_startObject



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/dodebui/build.rb', line 40

def build_container_create_start
  logger.info("Creating container #{@distribution.codename}")
  @container = Docker::Container.create(
    'Image' => @distribution.image_name,
    'Cmd' => %w(sleep 3600),
    'WorkingDir' => '/_build/source'
  )
  logger.info("Starting container #{@distribution.codename}")
  @container.start('Binds' => [
    "#{build_dir}:/_build"
  ])
end

#build_dependenciesObject



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/dodebui/build.rb', line 53

def build_dependencies
  logger.info("Installing dependencies #{@distribution.codename}")
  stdout, stderr, ret_val = @container.exec([
    '/usr/lib/pbuilder/pbuilder-satisfydepends-aptitude'
  ])
  write_log('apt_install_deps', stdout, stderr)
  if ret_val != 0
    logger.warn("Failed installing dependencies #{@distribution.codename}")
    fail
  end
  logger.info("Finished installing dependencies #{@distribution.codename}")
end

#build_dirObject



149
150
151
152
153
154
155
156
157
158
# File 'lib/dodebui/build.rb', line 149

def build_dir
  File.expand_path(
    File.join(
      @cli.wd,
      '..',
      '_build',
      "#{distribution.os}_#{distribution.codename}"
    )
  )
end

#build_error(e) ⇒ Object



112
113
114
115
116
117
118
# File 'lib/dodebui/build.rb', line 112

def build_error(e)
  logger.warn("Error building #{@distribution.image_name}: #{e}")
  return false if @container.nil?
  logger.warn("Use container id=#{@container.id} to debug")
  @container.stop
  false
end

#build_packageObject



66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/dodebui/build.rb', line 66

def build_package
  logger.info("Building package #{@distribution.codename}")
  stdout, stderr, ret_val = @container.exec([
    'dpkg-buildpackage'
  ])
  write_log('build', stdout, stderr)
  if ret_val != 0
    logger.warn("Failed building package #{@distribution.codename}")
    fail
  end
  logger.info("Finished building package #{@distribution.codename}")
end

#cache_dirObject



140
141
142
143
144
145
146
147
# File 'lib/dodebui/build.rb', line 140

def cache_dir
  File.expand_path(
    File.join(
      '/var/lib/dodebui',
      "#{distribution.os}_#{distribution.codename}"
    )
  )
end

#local_expect(desc, *args) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/dodebui/build.rb', line 15

def local_expect(desc, *args)
  Open3.popen3(*args) do |_i, o, e, t|
    if args[0].is_a? Hash
      cmd = args[1]
    else
      cmd = args[0]
    end
    ret_val = t.value.exitstatus
    if ret_val == 0
      logger.debug("#{desc} (cmd=#{cmd}): succeed")
    else
      output = "Exec failed cmd=#{cmd} ret_val=#{ret_val}"
      output += "stdout=#{o.read} stderr=#{e.read}"
      fail output
    end
  end
end

#loggerObject



166
167
168
# File 'lib/dodebui/build.rb', line 166

def logger
  @cli.logger
end

#sourceObject



160
161
162
163
164
# File 'lib/dodebui/build.rb', line 160

def source
  source_copy
  source_changelog
  source_templates
end

#source_changelogObject



224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/dodebui/build.rb', line 224

def source_changelog
  path = File.join(source_dir, 'debian/changelog')
  logger.debug "Modify changelog file #{path}"
  local_expect(
    'append distribution build to changelog',
    {
      'DEBFULLNAME' => 'Jenkins Autobuilder',
      'DEBEMAIL' => '[email protected]'
    },
    source_changelog_dch(path)
  )
end

#source_changelog_dch(path) ⇒ Object



212
213
214
215
216
217
218
219
220
221
222
# File 'lib/dodebui/build.rb', line 212

def source_changelog_dch(path)
  output = 'dch --changelog %{path} -l "+%{cn_str}%{cn}" -D "%{cn}" '
  output += '--force-distribution '
  output += '"Build a changelog entry for %{cn} %{cn}"'

  output % {
    cn: @distribution.codename,
    cn_str: @distribution.codename_str,
    path: path
  }
end

#source_copyObject



204
205
206
207
208
209
210
# File 'lib/dodebui/build.rb', line 204

def source_copy
  logger.debug "Start copying sources to #{source_dir}"
  FileUtils.mkdir_p build_dir
  FileUtils.rm_rf source_dir
  FileUtils.cp_r @cli.wd, source_dir
  logger.debug "Finished copying sources to #{source_dir}"
end

#source_dirObject



170
171
172
# File 'lib/dodebui/build.rb', line 170

def source_dir
  File.join(build_dir, 'source')
end

#source_template_eval(path) ⇒ Object



182
183
184
185
186
187
188
189
190
# File 'lib/dodebui/build.rb', line 182

def source_template_eval(path)
  logger.debug "Evaluate template #{path}"
  erb = ERB.new(
    File.read(path),
    nil,
    '-'
  )
  erb.result(source_template_namespace.priv_binding)
end

#source_template_namespaceObject



174
175
176
177
178
179
180
# File 'lib/dodebui/build.rb', line 174

def source_template_namespace
  TemplateNamespace.new(
    os: @distribution.os,
    codename: @distribution.codename,
    codename_int: @distribution.codename_int
  )
end

#source_templatesObject



192
193
194
195
196
197
198
199
200
201
202
# File 'lib/dodebui/build.rb', line 192

def source_templates
  return if @cli.source_templates.nil?
  @cli.source_templates.each do |template|
    src = File.join(source_dir, template)
    dest = src[0...-4]
    File.open(dest, 'w') do |file|
      file.write(source_template_eval(src))
    end
    sh "chmod +x #{template}" if template == 'debian/rules'
  end
end

#write_log(name, o, e) ⇒ Object



33
34
35
36
37
38
# File 'lib/dodebui/build.rb', line 33

def write_log(name, o, e)
  o_path = File.join(build_dir, "#{name}.stdout.log")
  e_path = File.join(build_dir, "#{name}.stderr.log")
  File.open(o_path, 'w') { |file| file.write(o.join '') }
  File.open(e_path, 'w') { |file| file.write(e.join '') }
end