73
66
print "Selected architecture " . $conf->get('ARCH') . "\n"
74
67
if $conf->get('DEBUG' && defined($conf->get('ARCH')));
77
$conf->get('MAILTO_HASH')->{$conf->get('DISTRIBUTION')})
78
if $conf->get('MAILTO_HASH')->{$conf->get('DISTRIBUTION')};
80
# see debsign for priorities, we will follow the same order
81
$conf->set('SIGNING_OPTIONS',
82
"-m".$conf->get('MAINTAINER_NAME')."")
83
if defined $conf->get('MAINTAINER_NAME');
84
$conf->set('SIGNING_OPTIONS',
85
"-e".$conf->get('UPLOADER_NAME')."")
86
if defined $conf->get('UPLOADER_NAME');
87
$conf->set('SIGNING_OPTIONS',
88
"-k".$conf->get('KEY_ID')."")
89
if defined $conf->get('KEY_ID');
90
$conf->set('MAINTAINER_NAME', $conf->get('UPLOADER_NAME')) if defined $conf->get('UPLOADER_NAME');
91
$conf->set('MAINTAINER_NAME', $conf->get('KEY_ID')) if defined $conf->get('KEY_ID');
93
if (!defined($conf->get('MAINTAINER_NAME')) &&
94
$conf->get('BIN_NMU')) {
95
die "A maintainer name, uploader name or key ID must be specified in .sbuildrc,\nor use -m, -e or -k, when performing a binNMU\n";
71
$SIG{'INT'} = \&main::shutdown;
72
$SIG{'TERM'} = \&main::shutdown;
73
$SIG{'ALRM'} = \&main::shutdown;
74
$SIG{'PIPE'} = \&main::shutdown;
78
$jobs{$_} = Sbuild::Build->new($_, $conf);
79
$jobs{$_}->set('Pkg Status Trigger', \&write_jobs_file)
98
# variables for scripts:
99
open_log($conf->get('DISTRIBUTION'), $conf);
100
$SIG{'INT'} = \&shutdown;
101
$SIG{'TERM'} = \&shutdown;
102
$SIG{'ALRM'} = \&shutdown;
103
$SIG{'PIPE'} = \&shutdown;
106
foreach $dscfile (@ARGV) {
108
# TODO: Append to build list, to allow parallel builds.
109
my $build = Sbuild::Build->new($dscfile, $conf);
110
$main::build_object = $build;
112
$build->set('Pkg Start Time', time);
114
$main::build_object->write_jobs_file("");
115
$build->parse_manual_srcdeps(map { m,(?:.*/)?([^_/]+)[^/]*, } @ARGV);
117
if ($build->get('Invalid Source')) {
118
$build->log("Invalid source: $dscfile\n");
119
$build->log("Skipping " . $build->get('Package') . " \n");
120
$build->set('Pkg Status', 'skipped');
125
if ($conf->get('CHROOT_MODE') eq 'schroot') {
126
$chroot_info = Sbuild::ChrootInfoSchroot->new($conf);
128
$chroot_info = Sbuild::ChrootInfoSudo->new($conf);
131
my $session = $chroot_info->create($conf->get('DISTRIBUTION'),
132
$conf->get('CHROOT'),
135
if (!$session->begin_session()) {
136
$build->log("Error creating chroot session: skipping " .
137
$build->get('Package') . "\n");
138
$build->set('Pkg Status', 'skipped');
142
$build->set('Session', $session);
143
$build->set('Arch', $build->chroot_arch());
145
$build->set('Chroot Dir', $session->get('Location'));
146
$build->set('Chroot Build Dir',
147
tempdir($conf->get('USERNAME') . '-' .
148
$build->get('Package_SVersion') . '-' .
149
$build->get('Arch') . '-XXXXXX',
150
DIR => $session->get('Build Location')));
151
# TODO: Don't hack the build location in; add a means to customise
152
# the chroot directly.
153
$session->set('Build Location', $build->get('Chroot Build Dir'));
156
my $tpkg = basename($build->get('Package_Version'));
157
# TODO: This should be 'Pkg Start Time', set in build().
158
my $date = strftime("%Y%m%d-%H%M",localtime);
160
if ($conf->get('BIN_NMU')) {
161
$tpkg =~ /^([^_]+)_([^_]+)(.*)$/;
162
$tpkg = $1 . "_" . binNMU_version($2,$conf->get('BIN_NMU_VERSION'));
163
$build->set('binNMU Name', $tpkg);
167
# TODO: Get package name from build object
168
next if !$build->open_build_log($tpkg);
171
# Needed so chroot commands log to build log
172
$session->set('Log Stream', $build->get('Log Stream'));
174
# Chroot execution defaults
175
my $chroot_defaults = $session->get('Defaults');
176
$chroot_defaults->{'DIR'} =
177
$session->strip_chroot_path($session->get('Build Location'));
178
$chroot_defaults->{'STREAMIN'} = $devnull;
179
$chroot_defaults->{'STREAMOUT'} = $build->get('Log Stream');
180
$chroot_defaults->{'STREAMERR'} = $build->get('Log Stream');
181
$chroot_defaults->{'ENV'}->{'LC_ALL'} = 'POSIX';
182
$chroot_defaults->{'ENV'}->{'SHELL'} = $programs{'SHELL'};
184
$build->set('Session', $session);
186
$build->set('Pkg Status', 'failed'); # assume for now
187
$main::current_job = $build->get('Package_Version');
188
$build->set('Additional Deps', []);
189
$main::build_object->write_jobs_file("currently building");
190
if ($build->should_skip()) {
191
$build->set('Pkg Status', 'skipped');
197
if ($conf->get('APT_UPDATE')) {
198
$session->run_apt_command(
199
{ COMMAND => [$conf->get('APT_GET'), 'update'],
205
$build->log("apt-get update failed\n");
206
$build->set('Pkg Status', 'skipped');
211
$build->set('Pkg Fail Stage', 'fetch-src');
212
if (!$build->fetch_source_files()) {
217
if ($conf->get('SETUP_HOOK')) {
218
my $pipe = $session->pipe_command({
219
COMMAND => [$conf->get('SETUP_HOOK')],
220
ENV => $build->get_env('SBUILD_BUILD_'),
229
$build->log("setup-hook failed\n");
230
$build->set('Pkg Status', 'skipped');
231
goto cleanup_packages;
235
$build->set('Pkg Fail Stage', 'install-deps');
236
if (!$build->install_deps()) {
237
$build->log("Source-dependencies not satisfied; skipping " .
238
$build->get('Package') . "\n");
239
goto cleanup_packages;
242
$build->set('Pkg Status', 'successful')
244
$build->write_jobs_file($build->get('Pkg Status'));
245
$build->append_to_FINISHED();
248
if (defined ($session->get('Session Purged')) &&
249
$session->get('Session Purged') == 1) {
250
$build->log("Not removing build depends: cloned chroot in use\n");
252
$build->uninstall_deps();
254
$build->remove_srcdep_lock_file();
256
$build->analyze_fail_stage();
257
$main::build_object->write_jobs_file($build->get('Pkg Status'));
259
$session->end_session();
261
$build->set('Session', undef);
263
$build->close_build_log();
266
$build->set('binNMU Name', undef);
267
$main::current_job = "";
268
if ($conf->get('BATCH_MODE') and (-f $conf->get('HOME') . '/EXIT-DAEMON-PLEASE') ) {
81
write_jobs_file(); # Will now update on trigger.
83
# Run each job. Potential for parallelising this step.
84
foreach (keys %jobs) {
87
my $job = $jobs{$jobname};
88
$current_job = $jobname;
92
if (should_skip($job)) {
93
$job->set('Pkg Status', 'skipped');
98
# Give back if build failed
99
analyze_fail_stage($job);
101
dump_main_state() if $conf->get('DEBUG');
103
if ($conf->get('BATCH_MODE') &&
104
(-f $conf->get('HOME') . '/EXIT-DAEMON-PLEASE')) {
269
105
main::shutdown("NONE (flag file exit)");
271
dump_main_state() if $conf->get('DEBUG');
272
$main::build_object->write_jobs_file("");
275
109
close_log($conf);
276
unlink($main::build_object->get('Jobs File'))
110
unlink($conf->get('JOB_FILE'))
277
111
if $conf->get('BATCH_MODE');
278
112
unlink("SBUILD-FINISHED") if $conf->get('BATCH_MODE');
279
if ($conf->get('SBUILD_MODE') eq "user" && defined($main::build_object)) {
280
exit ($main::build_object->get('Pkg Status') ne "successful") ? 1 : 0;
113
if ($conf->get('SBUILD_MODE') eq "user" && defined($current_job) &&
114
defined($jobs{$current_job})) {
115
exit ($jobs{$current_job}->get('Pkg Status') ne "successful") ? 1 : 0;
120
# only called from main loop, but depends on job state.
121
sub write_jobs_file () {
122
if ($conf->get('BATCH_MODE')) {
124
my $file = $conf->get('JOB_FILE');
127
return if !open( F, ">$file" );
128
foreach (keys %jobs) {
131
print F $job->get('Package_OVersion') . ": " .
132
$job->get('Pkg Status') . "\n";
138
sub append_to_FINISHED ($) {
143
if ($conf->get('BATCH_MODE')) {
144
open(F, ">>SBUILD-FINISHED");
145
print F $job->get('Package_OVersion');
150
sub add_givenback ($$) {
154
if ($conf->get('BATCH_MODE')) {
155
my $pkgv = $build->get('Package_OVersion');
158
$build->lock_file("SBUILD-GIVEN-BACK", 0);
160
if (open( F, ">>SBUILD-GIVEN-BACK" )) {
161
print F "$pkgv $time\n";
165
$build->log("Can't open SBUILD-GIVEN-BACK: $!\n");
168
$build->unlock_file("SBUILD-GIVEN-BACK");
172
sub should_skip ($) {
175
if ($conf->get('BATCH_MODE')) {
176
my $pkgv = $build->get('Package_OVersion');
178
$pkgv = $build->fixup_pkgv($pkgv);
179
$build->lock_file("SKIP", 0);
180
goto unlock if !open( F, "SKIP" );
184
if (!open( F, ">SKIP" )) {
185
print "Can't open SKIP for writing: $!\n",
186
"Would write: @pkgs\nminus $pkgv\n";
193
print "$pkgv found in SKIP file -- skipping building it\n";
201
$build->unlock_file("SKIP");
206
sub analyze_fail_stage ($) {
209
if ($conf->get('BATCH_MODE')) {
210
my $pkgv = $build->get('Package_OVersion');
212
return if $build->get('Pkg Status') ne "failed";
213
return if !$build->get_conf('AUTO_GIVEBACK');
214
if (isin( $build->get('Pkg Fail Stage'),
215
qw(find-dsc fetch-src unpack-check check-space install-deps-env))) {
216
$build->set('Pkg Status', "given-back");
217
$build->log("Giving back package $pkgv after failure in ".
218
"$build->{'Pkg Fail Stage'} stage.\n");
220
$cmd = "ssh -l " . $build->get_conf('AUTO_GIVEBACK_USER') . " " .
221
$build->get_conf('AUTO_GIVEBACK_HOST') . " "
222
if $build->get_conf('AUTO_GIVEBACK_HOST');
223
$cmd .= "-S " . $build->get_conf('AUTO_GIVEBACK_SOCKET') . " "
224
if $build->get_conf('AUTO_GIVEBACK_SOCKET');
225
$cmd .= "wanna-build --give-back --no-down-propagation ".
226
"--dist=" . $build->get_conf('DISTRIBUTION') . " ";
227
$cmd .= "--database=" . $build->get_conf('WANNABUILD_DATABASE') . " "
228
if $build->get_conf('WANNABUILD_DATABASE');
229
$cmd .= "--user=" . $build->get_conf('AUTO_GIVEBACK_WANNABUILD_USER') . " "
230
if $build->get_conf('AUTO_GIVEBACK_WANNABUILD_USER');
234
$build->log("wanna-build failed with status $?\n");
237
$build->add_givenback($build, time);
238
$build->write_stats('give-back', 1);
285
244
sub shutdown ($) {
286
245
my $signame = shift;
287
my($job,@npkgs,@pkgs);
290
249
$SIG{'INT'} = 'IGNORE';
292
251
$SIG{'TERM'} = 'IGNORE';
293
252
$SIG{'ALRM'} = 'IGNORE';
294
253
$SIG{'PIPE'} = 'IGNORE';
295
$main::build_object->log("sbuild received SIG$signame -- shutting down\n");
297
goto not_ni_shutdown if !$conf->get('BATCH_MODE');
299
# most important: dump out names of unfinished jobs to REDO
300
foreach $job (@ARGV) {
302
$job2 = $main::build_object->fixup_pkgv($job2);
303
push( @npkgs, $job2 )
304
if !$main::job_state{$job} || $job eq $main::current_job;
306
print LOG "The following jobs were not finished: @npkgs\n";
309
if (-f "REDO.lock") {
310
# if lock file exists, write to a different file -- timing may
314
if (open( F, "<$f" )) {
318
if (open( F, ">>$f" )) {
319
foreach $job (@npkgs) {
320
next if grep( /^\Q$job\E\s/, @pkgs );
321
if (not defined $main::build_object->get_conf('BIN_NMU_VERSION')) {
323
$main::build_object->get_conf('DISTRIBUTION') . "\n";
326
$main::build_object->get_conf('DISTRIBUTION')
328
$main::build_object->get_conf('BIN_NMU_VERSION')
330
$main::build_object->get_conf('BIN_NMU') . "\n";
336
print "Cannot open $f: $!\n";
338
open( F, ">SBUILD-REDO-DUMPED" );
340
print LOG "SBUILD-REDO-DUMPED created\n";
341
unlink( "SBUILD-FINISHED" );
343
# next: say which packages should be uninstalled
344
@pkgs = keys %{$main::build_object->get('Changes')->{'installed'}};
346
if (open( F, ">>NEED-TO-UNINSTALL" )) {
350
print "The following packages still need to be uninstalled ",
351
"(--purge):\n@pkgs\n";
355
# next: kill currently running command (if one)
356
if ($main::build_object->get('Sub PID')) {
357
print "Killing " . $main::build_object->get('Sub Task') .
358
" subprocess " . $main::build_object->get('Sub PID') . "\n";
359
$main::build_object->get('Session')->run_command(
360
{ COMMAND => ['perl', '-e',
361
"\"kill( \\\"TERM\\\", " .
362
$main::build_object->get('Sub PID') .
369
$main::build_object->remove_srcdep_lock_file();
371
# close logs and send mails
372
if ( $main::current_job && defined($main::build_object->get('Session'))) {
255
$jobs{$current_job}->log("sbuild received SIG$signame -- shutting down\n");
257
if ($conf->get('BATCH_MODE')) {
259
# Dump names of unfinished jobs to REDO
260
foreach (keys %jobs) {
263
push(@npkgs, $job->get('Package_OVersion'))
264
if $job->get('Pkg Status') ne "successful";
266
print "The following jobs were not finished: @npkgs\n";
269
if (-f "REDO.lock") {
270
# if lock file exists, write to a different file -- timing may
274
if (open(F, "<$f")) {
278
if (open(F, ">>$f")) {
280
next if grep( /^\Q$_\E\s/, @pkgs );
282
$jobs{$current_job}->get_conf('DISTRIBUTION');
283
print F " " . $jobs{$current_job}->get_conf('BIN_NMU_VERSION')
284
. " " . $jobs{$current_job}->get_conf('BIN_NMU')
285
if (defined $jobs{$current_job}->get_conf('BIN_NMU_VERSION'));
291
print "Cannot open $f: $!\n";
293
open(F, ">SBUILD-REDO-DUMPED");
295
print "SBUILD-REDO-DUMPED created\n";
297
unlink("SBUILD-FINISHED");
299
# next: say which packages should be uninstalled
300
@pkgs = keys %{$jobs{$current_job}->get('Changes')->{'installed'}};
302
if (open( F, ">>NEED-TO-UNINSTALL" )) {
306
print "The following packages still need to be uninstalled ",
307
"(--purge):\n@pkgs\n";
311
# Kill currently running command (if any)
312
if ($jobs{$current_job}->get('Sub PID')) {
313
print "Killing " . $jobs{$current_job}->get('Sub Task') .
314
" subprocess " . $jobs{$current_job}->get('Sub PID') . "\n";
315
$jobs{$current_job}->get('Session')->run_command(
316
{ COMMAND => ['perl', '-e',
317
"\"kill( \\\"TERM\\\", " .
318
$jobs{$current_job}->get('Sub PID') .
325
$jobs{$current_job}->remove_srcdep_lock_file();
327
# Close logs and send mails
328
if ( $current_job && defined($jobs{$current_job}->get('Session'))) {
373
329
if ($conf->get('PURGE_BUILD_DIRECTORY') eq "always") {
374
$main::build_object->log("Purging " . $main::build_object->get('Chroot Build Dir') . "\n");
375
my $bdir = $main::build_object->get('Session')->strip_chroot_path($main::build_object->get('Chroot Build Dir'));
376
$main::build_object->get('Session')->run_command(
330
$jobs{$current_job}->log("Purging " . $jobs{$current_job}->get('Chroot Build Dir') . "\n");
331
my $bdir = $jobs{$current_job}->get('Session')->strip_chroot_path($jobs{$current_job}->get('Chroot Build Dir'));
332
$jobs{$current_job}->get('Session')->run_command(
377
333
{ COMMAND => [$Sbuild::Sysconfig::programs{'RM'},