1 package Fedora
::Rebuild
::Package
;
9 use Fedora
::Rebuild
::Package
::StateLock
;
10 use Fedora
::Rebuild
::RPM
;
14 use version
0.77; our $VERSION = version
->declare("v0.8.0");
16 has
'name' => (is
=> 'ro', isa
=> 'Str', required
=> 1);
17 # Build-time dependencies
18 has
'requires' => (is
=> 'rw', isa
=> 'HashRef', lazy_build
=> 1,
20 # Run-time dependencies hashed by binary package ENVR.
21 has
'runrequires' => (is
=> 'rw', isa
=> 'HashRef', lazy_build
=> 1,
23 # Run-time provides hashes by binary package ENVR.
24 has
'provides' => (is
=> 'rw', isa
=> 'HashRef', lazy_build
=> 1,
26 has
'workdir' => (is
=> 'ro', isa
=> 'Str', required
=> 1);
28 # "f14", "f15" etc. Use "rawhide" for latest one.
29 has
'dist' => (is
=> 'ro', isa
=> 'Str', required
=> 1);
31 # "dist-f14", "dist-f15" etc. Use "dist-rawhide" for latest one.
32 has
'target' => (is
=> 'ro', isa
=> 'Str', required
=> 1);
33 has
'message' => (is
=> 'ro', isa
=> 'Str', required
=> 1);
35 has
'packagedir' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
37 has
'repodir' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
39 has
'mockdir' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
41 has
'rpmdir' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
43 has
'requiresstore' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
45 has
'runrequiresstore' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
47 has
'providesstore' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
49 has
'taskstore' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
51 has
'branch' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
54 # Make object shared between threads.
55 # XXX: Not all attributes are shared automatically.
59 return shared_clone
($class->$orig(@_));
62 # Clean package locks bound to attributes
65 for my $state ('buildrequires', 'runrequires', 'provides') {
66 Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
67 state => $state)->mark_failed;
71 # BuildRequires. Shared.
72 # Initialize to empty hash. Call get_buildrequires() to populate.
75 my $requires :shared
= shared_clone
({});
79 # Run-time Requires. Shared.
80 # Initialize to empty hash. Call get_runrequires() to populate.
81 sub _build_runrequires
{
83 my $runrequires :shared
= shared_clone
({});
87 # Run-time provides. Shared.
88 # Initialize to empty hash. Call rebuild() or get_binaryprovides() to populate.
91 my $provides :shared
= shared_clone
({});
95 sub _build_packagedir
{
97 my $directory = File
::Spec
->catfile($self->workdir, $self->name);
98 if (! -d
$directory) {
99 File
::Path
::make_path
($directory) or
100 die "Could not create directory $directory: $!";
107 return File
::Spec
->catfile($self->packagedir, 'repository');
112 return File
::Spec
->catfile($self->packagedir, 'mock');
117 return File
::Spec
->catfile($self->packagedir, 'RPMS');
120 sub _build_requiresstore
{
122 return File
::Spec
->catfile($self->packagedir, 'buildrequires.store');
125 sub _build_runrequiresstore
{
127 return File
::Spec
->catfile($self->packagedir, 'runrequires.store');
130 sub _build_providesstore
{
132 return File
::Spec
->catfile($self->packagedir, 'provides.store');
135 sub _build_taskstore
{
137 return File
::Spec
->catfile($self->packagedir, 'task.store');
142 if ($self->dist eq 'rawhide') {
150 # Clones package repository and switch to proper branch if not yet done.
151 # Return true on success.
154 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
156 if ($lock->is_done) { return 1; }
158 # XXX: fedpkg creates subdirectory named like package. The package name
159 # could clash with our file structure. Thus we need to clone into secure
160 # directory and move repository content to fixed name $self->repodir after
163 if (-d
$self->repodir) { File
::Path
::remove_tree
($self->repodir); }
164 my $tempdir = File
::Spec
->catfile($self->packagedir, 'tmp');
165 my $temprepodir = File
::Spec
->catfile($tempdir, $self->name);
166 if (-d
$tempdir) { File
::Path
::remove_tree
($tempdir); }
167 if (!File
::Path
::make_path
($tempdir)) {
168 $lock->log("Could not create directory `" . $tempdir . "': $!\n");
169 return $lock->mark_failed;
172 if (!$lock->do($tempdir, 'fedpkg', 'clone', $self->name)) {
173 $lock->log("Could not clone `" . $self->name . "' repository.\n");
174 return $lock->mark_failed;
177 if (!rename($temprepodir, $self->repodir)) {
178 $lock->log("Could not move `" . $temprepodir . "' content to to `" .
179 $self->repodir . "'.\n");
180 return $lock->mark_failed;
182 File
::Path
::remove_tree
($tempdir);
184 if (!$lock->do($self->repodir, 'fedpkg', 'switch-branch', $self->branch)) {
185 $lock->log("Could not switch `" . $self->name .
186 "' repository to branch `" . $self->branch . "'.\n");
187 return $lock->mark_failed;
190 return $lock->mark_done;
193 # Builds SRPM locally. Return true on success.
194 # If first argument is true, recreate SRPM forcefully.
197 my ($self, $force) = @_;
198 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
200 if ($force) { $lock->remove_lock; }
201 if ($lock->is_done) { return 1; }
203 if (!$lock->do($self->repodir, 'fedpkg', 'srpm')) {
204 $lock->log("Could not build SRPM for `" . $self->name .
205 "' package locally.\n");
206 return $lock->mark_failed;
209 return $lock->mark_done;
212 # Get current package NEVRA from sources in repository.
213 # First argument is state lock where process of getting NEVRA including
214 # potential failure is logged.
215 # XXX: The state is not marked as failed in case of error,
216 # Return NEVRA string or undef in case of error.
217 sub get_nevra_from_git
{
218 my ($self, $lock) = @_;
221 if (!$lock->dooutput($self->repodir, \
$nevra, 'fedpkg', 'verrel') ||
223 $lock->log("Could not get NEVRA from `" . $self->name .
224 "' git repository package.\n");
228 # Consider last line only becuase of bug in fedpkg
229 # <https://bugzilla.redhat.com/show_bug.cgi?id=721389>.
230 my @lines = (split qr{$/}, $nevra);
236 # Get current package SRPM name.
237 # If the SRPM file does not exist, it will be re-created.
238 # First argument is state lock where process of building SRPM including
239 # potential failure is logged.
240 # XXX: The state is not marked as failed in case of error,
241 # Return SRPM file name string or undef in case of error.
243 my ($self, $lock) = @_;
245 my $nevra = $self->get_nevra_from_git($lock);
246 if (! defined $nevra) {
250 my $srpmname = File
::Spec
->catfile($self->repodir, $nevra . '.src.rpm');
251 if (! -f
$srpmname ) {
252 $lock->log("SRPM package `" . $srpmname . "' is missing, " .
253 "trying to create SRPM again...\n");
254 if (!$self->srpm(1) || ! -f
$srpmname) {
255 $lock->log("`Could not recreate SRPM package '" . $srpmname .
263 # Create a directory. If it exists, it will remove it before.
264 # First argument is the directory, second argument is lock to log errors into.
265 # Return true, false in case of error.
266 # XXX: This is not a method
267 sub replace_directory
{
268 my ($lock, $directory) = @_;
269 if (-d
$directory) { File
::Path
::remove_tree
($directory); }
270 if (!File
::Path
::make_path
($directory)) {
271 $lock->log("Could not create directory `" . $directory . "': $!\n");
277 # Copy files into existing directory.
278 # First argument lock for logggin,
279 # second argument is destinatinon directory,
280 # The last is list of files to be copied.
281 # Return true in sucesss, false in case of error.
282 # XXX: This is not a method
283 sub copy_files_into_directory
{
284 my ($lock, $directory, @files) = @_;
285 for my $file (@files) {
287 if (!copy
($file, $directory)) {
288 $lock->log("Could not copy `". $file . "' into `". $directory .
292 $lock->log("`" . $file . "' copied into `" . $directory . "'\n");
297 # Destile BuildRequires from local SRPM and serialize them into file.
298 # Return true on success.
300 # FIXME: does not work after cleaning clone or doing update.
301 sub storebuildrequires
{
303 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
304 state => 'buildrequiresstore');
305 if ($lock->is_done) { return 1; }
307 my $nevra = $self->get_nevra_from_git($lock);
308 if (! defined $nevra) {
309 return $lock->mark_failed;
312 my $srpmname = File
::Spec
->catfile($self->repodir, $nevra . '.src.rpm');
313 if (! -f
$srpmname ) {
314 $lock->log("SRPM package `" . $srpmname . "' is missing, " .
315 "trying to create SRPM again...\n");
316 if (!$self->srpm(1) || ! -f
$srpmname) {
317 $lock->log("`Could not recreate SRPM package '" . $srpmname .
319 return $lock->mark_failed;
323 my $rpm = Fedora
::Rebuild
::RPM
->new(name
=> $srpmname);
324 my ($requires, $envra) = $rpm->requires;
325 if (! defined $requires) {
326 $lock->log("Could not get requires of SRPM `" . $srpmname . "': ". $@
328 return $lock->mark_failed;
331 if (! $lock->nstorereference($requires, $self->requiresstore)) {
332 $lock->log("Could not store requires of SRPM `". $srpmname .
333 "' into `" . $self->requiresstore . "' file: $@\n");
334 return $lock->mark_failed;
337 $lock->log(Data
::Dumper
::Dumper
($requires) . "\n");
338 return $lock->mark_done;
341 # Destile BuildRequires from local SRPM. Return true on success.
342 # Needs `buildrequiresstore'.
345 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
346 state => 'buildrequires');
347 if ($lock->is_done) { return 1; }
349 my $requires = $lock->retrievereference($self->requiresstore);
351 $lock->log("Could not load requires of `". $self->name .
352 "' package from `" . $self->requiresstore . "' file: $@\n");
353 return $lock->mark_failed;
355 $self->requires(shared_clone
($requires));
357 $lock->log(Data
::Dumper
::Dumper
($self->requires) . "\n");
358 return $lock->mark_done;
361 # Record verdict from dependency solver whether the package is rebuildable.
362 # This step is always redone.
363 sub log_is_rebuildable
{
364 my ($self, $is_rebuildable, $message) = @_;
365 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
366 state => 'is_rebuildable');
369 $lock->log("Solver result for possibility of rebuilding SRPM for `" .
370 $self->name . "': $message\n");
371 if (! $is_rebuildable) {
372 $lock->log("According dependency solver, this package is not " .
373 "rebuildable now.\n");
374 return $lock->mark_failed;
377 $lock->log("According dependency solver, this package is " .
378 "rebuildable now.\n");
379 return $lock->mark_done;
382 # Get binary RPM packages for the source package.
383 # If first argument is:
384 # 'koji' download them from Koji,
385 # 'local' from local build,
386 # 'mock' from mock result directory.
387 # Requires `clone'. Sould be called after `build'.
388 # Return true on success.
390 my ($self, $mode) = @_;
391 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
393 if ($lock->is_done) { return 1; }
395 if (!replace_directory
($lock, $self->rpmdir)) {
396 return $lock->mark_failed;
399 # TODO: Get current architecture by rpmGetArchInfo() from librpm
400 my @archs = qw(x86_64 noarch);
401 if ($mode eq 'koji') {
402 $lock->log("Getting binary RPM packages from Koji:\n");
404 my $nevra = $self->get_nevra_from_git($lock);
405 if (! defined $nevra) {
406 return $lock->mark_failed;
409 # TODO: Get all archs, remove SRPM
410 if (!$lock->do($self->rpmdir, 'koji', 'download-build',
411 (map {'--arch=' . $_ } @archs), $nevra)) {
412 $lock->log("Could get binary RPM packages for `" . $nevra . "'\n");
413 return $lock->mark_failed;
415 } elsif ($mode eq 'local') {
416 $lock->log("Getting binary RPM packages from local build:\n");
418 my @rpms = map { glob(File
::Spec
->catfile($self->repodir, $_,
421 $lock->log("No binary RPM packages found under `" .
422 $self->repodir . "'\n");
423 return $lock->mark_failed;
426 if (!copy_files_into_directory
($lock, $self->rpmdir, @rpms)) {
427 return $lock->mark_failed;
429 } elsif ($mode eq 'mock') {
430 $lock->log("Getting binary RPM packages from mock build:\n");
432 my @rpms = map { glob(File
::Spec
->catfile($self->mockdir,
433 ('*.' . $_ . '.rpm'))) } @archs;
435 $lock->log("No binary RPM packages found under `" .
436 $self->mockdir . "'\n");
437 return $lock->mark_failed;
440 if (!copy_files_into_directory
($lock, $self->rpmdir, @rpms)) {
441 return $lock->mark_failed;
444 $lock->log("Could get binary RPM packages for `" . $self->name .
445 "' source package because of unknown building mode `" . $mode .
447 return $lock->mark_failed;
450 return $lock->mark_done;
453 # Distill Requires from rebuilt binary packages and serialize them into file.
454 # Return true on success.
456 sub storebinaryrequires
{
458 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
459 state => 'runrequiresstore');
460 if ($lock->is_done) { return 1; }
462 my @rpms = glob(File
::Spec
->catfile($self->rpmdir, '*.rpm'));
464 $lock->log("No binary RPM packages found in `" . $self->rpmdir
466 return $lock->mark_failed;
469 my $allrequires = {};
470 for my $rpmname (@rpms) {
471 my $rpm = Fedora
::Rebuild
::RPM
->new(name
=> $rpmname);
473 my ($requires, $envr) = $rpm->requires;
475 if (! defined $requires || ! defined $envr) {
476 $lock->log("Could not get run-time requires of RPM `" . $rpmname .
478 return $lock->mark_failed;
480 $$allrequires{$envr} = $requires;
483 if (! $lock->nstorereference($allrequires, $self->runrequiresstore)) {
484 $lock->log("Could not store run-time requires of RPM `". $self->name .
485 "' into `" . $self->runrequiresstore . "' file: $@\n");
486 return $lock->mark_failed;
489 $lock->log(Data
::Dumper
::Dumper
($allrequires));
490 return $lock->mark_done;
493 # Distill Provides from rebuilt binary packages and serialize them into file.
494 # Return true on success.
496 sub storebinaryprovides
{
498 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
499 state => 'providesstore');
500 if ($lock->is_done) { return 1; }
502 my @rpms = glob(File
::Spec
->catfile($self->rpmdir, '*.rpm'));
504 $lock->log("No binary RPM packages found in `" . $self->rpmdir
506 return $lock->mark_failed;
509 my $allprovides = {};
510 for my $rpmname (@rpms) {
511 my $rpm = Fedora
::Rebuild
::RPM
->new(name
=> $rpmname);
513 my ($provides, $envr) = $rpm->provides;
515 if (! defined $provides || !defined $envr) {
516 $lock->log("Could not get provides of RPM `" . $rpmname . "': " .
518 return $lock->mark_failed;
520 $$allprovides{$envr} = $provides;
523 if (! $lock->nstorereference($allprovides, $self->providesstore)) {
524 $lock->log("Could not store provides of RPM `". $self->name .
525 "' into `" . $self->providesstore . "' file: $@\n");
526 return $lock->mark_failed;
529 $lock->log(Data
::Dumper
::Dumper
($allprovides));
530 return $lock->mark_done;
533 # Load run-time requires of already rebuilt binary packages from file.
534 # Return true on success.
535 # Needs `storebinaryrequires'.
536 sub loadbinaryrequires
{
538 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
539 state => 'runrequires');
540 if ($lock->is_done) { return 1; }
542 my $runrequires = $lock->retrievereference($self->runrequiresstore);
543 if (! $runrequires) {
544 $lock->log("Could not load run-time requires of `". $self->name .
545 "' package from `" . $self->runrequiresstore . "' file: $@\n");
546 return $lock->mark_failed;
548 $self->runrequires(shared_clone
($runrequires));
550 $lock->log(Data
::Dumper
::Dumper
($self->runrequires));
551 return $lock->mark_done;
554 # Load provides of already rebuilt binary packages from file.
555 # Return true on success.
556 # Needs `storebinaryprovides'.
557 sub loadbinaryprovides
{
559 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
560 state => 'provides');
561 if ($lock->is_done) { return 1; }
563 my $provides = $lock->retrievereference($self->providesstore);
565 $lock->log("Could not load provides of `". $self->name .
566 "' package from `" . $self->providesstore . "' file: $@\n");
567 return $lock->mark_failed;
569 $self->provides(shared_clone
($provides));
571 $lock->log(Data
::Dumper
::Dumper
($self->provides));
572 return $lock->mark_done;
575 # Increase package revision if not yet done. Commit change if first argument
577 # Return true on success.
580 my ($self, $mode) = @_;
581 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
583 if ($lock->is_done) { return 1; }
585 # Reset git repository
586 if (!$lock->do($self->repodir, 'git', 'reset', '--hard',
587 'origin/' . $self->branch)) {
588 $lock->log("Could not reset git repository in `" . $self->repodir .
590 return $lock->mark_failed;
593 # Pull git repository
594 if (!$lock->do($self->repodir, 'git', 'pull')) {
595 $lock->log("Could not pull git repository in `" . $self->repodir .
597 return $lock->mark_failed;
600 # Increase revision number
601 my $specfile = File
::Spec
->catfile($self->repodir, $self->name . '.spec');
602 if (!$lock->do(undef, 'rpmdev-bumpspec', '-c', $self->message, $specfile)) {
603 $lock->log("Could not increase revison number in `" . $specfile .
605 return $lock->mark_failed;
609 if (!$lock->do($self->repodir, 'git', 'commit', '-a',
610 '-m', $self->message)) {
611 $lock->log("Could not commit changes into git repository `" .
612 $self->repodir . "'.\n");
613 return $lock->mark_failed;
616 if ($mode eq 'koji') {
618 if (!$lock->do($self->repodir, 'git', 'push')) {
619 $lock->log("Could not push changes from repository `" .
620 $self->repodir . "' to server.\n");
621 return $lock->mark_failed;
624 $lock->log("Not pushing changes because of local build mode.\n");
627 return $lock->mark_done;
631 # Submit package for building into Koji and store task ID.
632 # This is pointless in local build mode.
633 # Requires `clone'. Sould be called after `update'.
634 # Return true on success.
637 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
638 state => 'submitbuild');
639 if ($lock->is_done) { return 1; }
641 # Get NEVRA of intended build
642 my $nevra = $self->get_nevra_from_git($lock);
643 if (! defined $nevra) {
644 return $lock->mark_failed;
647 # Check the build is not already in Koji (e.g. by concurrent packager
648 # or after this program restart) but do not conclude anything.
650 if (!$lock->dooutput($self->repodir, \
$buildinfo, 'koji', 'buildinfo',
652 $lock->log("Could not ask Koji for `" . $nevra . "' status " .
653 "before submitting new build.\n");
654 return $lock->mark_failed;
656 if ($buildinfo =~ /No such build/m) {
657 $lock->log("Package not yet submitted for building as expected.\n");
659 # Get task ID of already building package
660 if ($buildinfo =~ /Task:\s*(\d+)/m) {
661 # TODO: We could compare task target and consider as submitted if
662 # equaled to intended target.
664 $lock->log("Package `$nevra' already submitted as task " .
665 "`$task_id'. Previous build failed or somebody builds the " .
666 "package concurrently.\n");
668 $lock->log("Package `$nevra' already in Koji, but task ID " .
669 "could not been determined.\n");
671 $lock->log("Re-submitting the package.\n")
676 if (!$lock->dooutput($self->repodir, \
$task_id, 'fedpkg', 'build',
677 '--nowait', '--target', $self->target)) {
678 $lock->log("Could not submit `" . $nevra . "' into Koji.\n");
679 return $lock->mark_failed;
681 if (not $task_id =~ /Created task:\s*(\d+)/) {
682 $lock->log("Could not parse Koji task ID for `$nevra' build\n");
683 return $lock->mark_failed;
688 if (! $lock->nstorereference(\
$task_id, $self->taskstore)) {
689 $lock->log("Could not store task ID `" . $task_id . "' of `" . $nevra .
690 "' package into `" . $self->taskstore . "' file: $@\n");
691 return $lock->mark_failed;
693 $lock->log("Task ID `" . $task_id . "' stored into `" .
694 $self->taskstore . "' file sucessfully.\n");
697 return $lock->mark_done;
701 # If first argument is:
702 # "koji" wait for package build in Koji,
703 # "local" build locally using fedpkg.
704 # "mock" build locally using mock.
705 # Requires `clone'. Sould be called after `update' or `submitbuild'.
706 # Return true on success.
708 my ($self, $mode) = @_;
709 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
711 if ($lock->is_done) { return 1; }
713 my $nevra = $self->get_nevra_from_git($lock);
714 if (! defined $nevra) {
715 return $lock->mark_failed;
718 if ($mode eq 'local') {
719 if (!$lock->do($self->repodir, 'fedpkg', 'local')) {
720 $lock->log("Could not build `" . $nevra . "' locally.\n");
721 return $lock->mark_failed;
723 } elsif ($mode eq 'koji') {
724 # Retrieve task ID of submitted build
725 my $task_id = $lock->retrievereference($self->taskstore);
727 $lock->log("Could not load task ID for `". $nevra .
728 "' build from `" . $self->taskstore . "' file: $@\n");
729 return $lock->mark_failed;
731 $task_id = $$task_id;
733 # Wait for build task result
734 # TODO: How to recognize the process died for other reason
735 # than build failure?
736 if (!$lock->do($self->repodir, 'koji', 'watch-task', $task_id)) {
737 $lock->log("Could not get status of Koji task `" . $task_id .
738 "' for `$nevra' build, or the task failed.\n");
739 return $lock->mark_failed;
741 } elsif ($mode eq 'mock') {
742 my $srpm_name = $self->get_srpm_name($lock);
743 if (! defined $srpm_name) {
744 return $lock->mark_failed;
746 if (!replace_directory
($lock, $self->mockdir)) {
747 return $lock->mark_failed;
749 # FIXME: Specify mock config to match selected dist and branch
751 # FIXME: Inject already rebuilt packages
752 if (!$lock->do(undef, 'mock', '--resultdir', $self->mockdir,
753 '--rebuild', $srpm_name)) {
754 $lock->log("Could not build `" . $nevra . "' in mock.\n");
755 return $lock->mark_failed;
758 $lock->log("Could not build `" . $nevra .
759 "' because of unknown building mode `" . $mode . "'.\n");
760 return $lock->mark_failed;
763 return $lock->mark_done;
767 # Waits for build root rotation. Just built package will be available for
768 # other packages at build time after returning from this fuction.
769 # If first argument is "koji", it will wait for the Koji rotation.
770 # If first argument is "mock", it will create yum repository in directory with
772 # If first argument is "local", this function is void,
773 # Requires `update'. Sould be called after `build'.
774 # Return true on success.
775 sub dowaitforbuildroot
{
776 my ($self, $mode) = @_;
777 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
779 if ($lock->is_done) { return 1; }
781 my $nevra = $self->get_nevra_from_git($lock);
782 if (! defined $nevra) {
783 return $lock->mark_failed;
786 if ($mode eq 'koji') {
787 if (!$lock->do($self->repodir, 'koji', 'wait-repo',
788 '--build=' . $nevra, '--target', $self->target)) {
789 $lock->log("Koji does not contain `" . $nevra .
790 "' package in build root for `" . $self->target .
791 "' build target yet.\n");
792 return $lock->mark_failed;
794 } elsif ($mode eq 'mock') {
795 $lock->log("`" . $nevra .
796 "' built in mock, creating yum repository...\n");
797 if (!$lock->do($self->rpmdir, 'createrepo', '.')) {
798 $lock->log("Could not create yum repository for `" . $nevra .
800 return $lock->mark_failed;
802 $lock->log("`" . $nevra .
803 "' yum repository created successfully.\n");
805 $lock->log("`" . $nevra .
806 "' built locally, not waiting on Koji rotation.\n");
809 return $lock->mark_done;
812 # Set hash of build-time dependencies (requires attribute).
813 # Return undef in case of failure.
814 sub get_buildrequires
{
817 print "Getting BuildRequires for `" . $self->name . "'...\n";
819 # Procede all steps, each must be re-doable
821 $ok = $self->srpm if $ok;
822 $ok = $self->storebuildrequires if $ok;
823 $ok = $self->buildrequires if $ok;
828 print "BuildRequires for `" . $self->name .
829 "' package distilled successfully.\n";
832 print "Could not get BuildRequires for `" . $self->name .
838 # Set hash of run-time requires (Requires attribute).
839 # Return true on success, undef in case of failure.
840 # XXX: Requires `runrequiresstore'
841 sub get_binaryrequires
{
844 print "Getting run-time requires for `" . $self->name . "'...\n";
846 $ok = $self->storebinaryrequires;
847 $ok = $self->loadbinaryrequires if $ok;
850 print "Run-time requires for `" . $self->name .
851 "' package distilled successfully.\n";
854 print "Could not get run-time requires for `" . $self->name .
860 # Set hash of run-time provides (provides attribute).
861 # Return true on success, undef in case of failure.
862 # XXX: Requires `providesstore'
863 sub get_binaryprovides
{
866 print "Getting binary provides for `" . $self->name . "'...\n";
868 $ok = $self->storebinaryprovides;
869 $ok = $self->loadbinaryprovides if $ok;
872 print "Provides for `" . $self->name .
873 "' package distilled successfully.\n";
876 print "Could not get Provides for `" . $self->name . "' package.\n";
881 # Set hash of run-time requires (Requires attribute) and provides
882 # (provides attribute). Common wrapper for getbinaryrequires() and
883 # getbinaryprovides().
884 # Return true on success, undef in case of failure.
885 # XXX: Requires `runrequiresstore' and `providesstore'
886 sub get_binarydependencies
{
889 print "Getting binary dependencies for `" . $self->name . "'...\n";
891 $ok = $self->get_binaryrequires;
892 $ok = $self->get_binaryprovides if $ok;
895 print "Binary dependencies for `" . $self->name .
896 "' package distilled successfully.\n";
899 print "Could not get binary dependencies for `" . $self->name .
905 # Rebuild a package without waiting for propagation to next build root.
906 # First argument defines build mode:
907 # "koji" publish commit and build in Koji,
908 # "local" build locally without pushing commits to server,
909 # "mock" build in mock without pushing commits to server.
911 my ($self, $mode) = @_;
913 print "Rebuilding `" . $self->name . "'...\n";
915 # Procede all steps, each must be re-doable
917 $ok = $self->update($mode) if $ok;
918 $ok = $self->submitbuild if ($ok and $mode eq 'koji');
919 $ok = $self->build($mode) if $ok;
920 $ok = $self->binaryrpm($mode) if $ok;
921 $ok = $self->get_binaryprovides if $ok;
922 $ok = $self->get_binaryrequires if $ok;
925 print "`" . $self->name . "' rebuild finished successfully.\n";
927 print "`" . $self->name . "' rebuild failed.\n";
932 # Wait for the package propagated into new build root.
933 # If first argument is "koji", waits for Koji build root rotation,
934 # Otherwise waits locally (no-op).
935 # XXX: Requires `update', should be called after rebuilding package.
936 sub waitforbuildroot
{
937 my ($self, $mode) = @_;
939 print "Waiting for `" . $self->name . "' to get to build root...\n";
941 $ok = $self->dowaitforbuildroot($mode);
944 print "`" . $self->name . "' propagated successfully.\n";
946 print "`" . $self->name . "' propagation failed.\n";