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 "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 # Return list of binary RPM files relative to current working directory.
454 # XXX: Should be called after colleting the files from build process by
456 sub listbinaryrpmfiles
{
458 return (glob(File
::Spec
->catfile($self->rpmdir, '*.rpm')));
461 # Distill Requires from rebuilt binary packages and serialize them into file.
462 # Return true on success.
464 sub storebinaryrequires
{
466 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
467 state => 'runrequiresstore');
468 if ($lock->is_done) { return 1; }
470 my @rpms = glob(File
::Spec
->catfile($self->rpmdir, '*.rpm'));
472 $lock->log("No binary RPM packages found in `" . $self->rpmdir
474 return $lock->mark_failed;
477 my $allrequires = {};
478 for my $rpmname (@rpms) {
479 my $rpm = Fedora
::Rebuild
::RPM
->new(name
=> $rpmname);
481 my ($requires, $envr) = $rpm->requires;
483 if (! defined $requires || ! defined $envr) {
484 $lock->log("Could not get run-time requires of RPM `" . $rpmname .
486 return $lock->mark_failed;
488 $$allrequires{$envr} = $requires;
491 if (! $lock->nstorereference($allrequires, $self->runrequiresstore)) {
492 $lock->log("Could not store run-time requires of RPM `". $self->name .
493 "' into `" . $self->runrequiresstore . "' file: $@\n");
494 return $lock->mark_failed;
497 $lock->log(Data
::Dumper
::Dumper
($allrequires));
498 return $lock->mark_done;
501 # Distill Provides from rebuilt binary packages and serialize them into file.
502 # Return true on success.
504 sub storebinaryprovides
{
506 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
507 state => 'providesstore');
508 if ($lock->is_done) { return 1; }
510 my @rpms = glob(File
::Spec
->catfile($self->rpmdir, '*.rpm'));
512 $lock->log("No binary RPM packages found in `" . $self->rpmdir
514 return $lock->mark_failed;
517 my $allprovides = {};
518 for my $rpmname (@rpms) {
519 my $rpm = Fedora
::Rebuild
::RPM
->new(name
=> $rpmname);
521 my ($provides, $envr) = $rpm->provides;
523 if (! defined $provides || !defined $envr) {
524 $lock->log("Could not get provides of RPM `" . $rpmname . "': " .
526 return $lock->mark_failed;
528 $$allprovides{$envr} = $provides;
531 if (! $lock->nstorereference($allprovides, $self->providesstore)) {
532 $lock->log("Could not store provides of RPM `". $self->name .
533 "' into `" . $self->providesstore . "' file: $@\n");
534 return $lock->mark_failed;
537 $lock->log(Data
::Dumper
::Dumper
($allprovides));
538 return $lock->mark_done;
541 # Load run-time requires of already rebuilt binary packages from file.
542 # Return true on success.
543 # Needs `storebinaryrequires'.
544 sub loadbinaryrequires
{
546 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
547 state => 'runrequires');
548 if ($lock->is_done) { return 1; }
550 my $runrequires = $lock->retrievereference($self->runrequiresstore);
551 if (! $runrequires) {
552 $lock->log("Could not load run-time requires of `". $self->name .
553 "' package from `" . $self->runrequiresstore . "' file: $@\n");
554 return $lock->mark_failed;
556 $self->runrequires(shared_clone
($runrequires));
558 $lock->log(Data
::Dumper
::Dumper
($self->runrequires));
559 return $lock->mark_done;
562 # Load provides of already rebuilt binary packages from file.
563 # Return true on success.
564 # Needs `storebinaryprovides'.
565 sub loadbinaryprovides
{
567 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
568 state => 'provides');
569 if ($lock->is_done) { return 1; }
571 my $provides = $lock->retrievereference($self->providesstore);
573 $lock->log("Could not load provides of `". $self->name .
574 "' package from `" . $self->providesstore . "' file: $@\n");
575 return $lock->mark_failed;
577 $self->provides(shared_clone
($provides));
579 $lock->log(Data
::Dumper
::Dumper
($self->provides));
580 return $lock->mark_done;
583 # Increase package revision if not yet done. Commit change if first argument
585 # Return true on success.
588 my ($self, $mode) = @_;
589 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
591 if ($lock->is_done) { return 1; }
593 # Reset git repository
594 if (!$lock->do($self->repodir, 'git', 'reset', '--hard',
595 'origin/' . $self->branch)) {
596 $lock->log("Could not reset git repository in `" . $self->repodir .
598 return $lock->mark_failed;
601 # Pull git repository
602 if (!$lock->do($self->repodir, 'git', 'pull')) {
603 $lock->log("Could not pull git repository in `" . $self->repodir .
605 return $lock->mark_failed;
608 # Increase revision number
609 my $specfile = File
::Spec
->catfile($self->repodir, $self->name . '.spec');
610 if (!$lock->do(undef, 'rpmdev-bumpspec', '-c', $self->message, $specfile)) {
611 $lock->log("Could not increase revison number in `" . $specfile .
613 return $lock->mark_failed;
617 if (!$lock->do($self->repodir, 'git', 'commit', '-a',
618 '-m', $self->message)) {
619 $lock->log("Could not commit changes into git repository `" .
620 $self->repodir . "'.\n");
621 return $lock->mark_failed;
624 if ($mode eq 'koji') {
626 if (!$lock->do($self->repodir, 'git', 'push')) {
627 $lock->log("Could not push changes from repository `" .
628 $self->repodir . "' to server.\n");
629 return $lock->mark_failed;
632 $lock->log("Not pushing changes because of local build mode.\n");
635 return $lock->mark_done;
639 # Submit package for building into Koji and store task ID.
640 # This is pointless in local build mode.
641 # Requires `clone'. Sould be called after `update'.
642 # Return true on success.
645 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
646 state => 'submitbuild');
647 if ($lock->is_done) { return 1; }
649 # Get NEVRA of intended build
650 my $nevra = $self->get_nevra_from_git($lock);
651 if (! defined $nevra) {
652 return $lock->mark_failed;
655 # Check the build is not already in Koji (e.g. by concurrent packager
656 # or after this program restart) but do not conclude anything.
658 if (!$lock->dooutput($self->repodir, \
$buildinfo, 'koji', 'buildinfo',
660 $lock->log("Could not ask Koji for `" . $nevra . "' status " .
661 "before submitting new build.\n");
662 return $lock->mark_failed;
664 if ($buildinfo =~ /No such build/m) {
665 $lock->log("Package not yet submitted for building as expected.\n");
667 # Get task ID of already building package
668 if ($buildinfo =~ /Task:\s*(\d+)/m) {
669 # TODO: We could compare task target and consider as submitted if
670 # equaled to intended target.
672 $lock->log("Package `$nevra' already submitted as task " .
673 "`$task_id'. Previous build failed or somebody builds the " .
674 "package concurrently.\n");
676 $lock->log("Package `$nevra' already in Koji, but task ID " .
677 "could not been determined.\n");
679 $lock->log("Re-submitting the package.\n")
684 if (!$lock->dooutput($self->repodir, \
$task_id, 'fedpkg', 'build',
685 '--nowait', '--target', $self->target)) {
686 $lock->log("Could not submit `" . $nevra . "' into Koji.\n");
687 return $lock->mark_failed;
689 if (not $task_id =~ /Created task:\s*(\d+)/) {
690 $lock->log("Could not parse Koji task ID for `$nevra' build\n");
691 return $lock->mark_failed;
696 if (! $lock->nstorereference(\
$task_id, $self->taskstore)) {
697 $lock->log("Could not store task ID `" . $task_id . "' of `" . $nevra .
698 "' package into `" . $self->taskstore . "' file: $@\n");
699 return $lock->mark_failed;
701 $lock->log("Task ID `" . $task_id . "' stored into `" .
702 $self->taskstore . "' file sucessfully.\n");
705 return $lock->mark_done;
709 # If first argument is:
710 # "koji" wait for package build in Koji,
711 # "local" build locally using fedpkg.
712 # "mock" build locally using mock.
713 # Second argument is reference to array of repository URLs to use as package
714 # base when building the package.
715 # Requires `clone'. Sould be called after `update' or `submitbuild'.
716 # Return true on success.
718 my ($self, $mode, $repositories) = @_;
719 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
721 if ($lock->is_done) { return 1; }
723 my $nevra = $self->get_nevra_from_git($lock);
724 if (! defined $nevra) {
725 return $lock->mark_failed;
728 if ($mode eq 'local') {
729 if (!$lock->do($self->repodir, 'fedpkg', 'local')) {
730 $lock->log("Could not build `" . $nevra . "' locally.\n");
731 return $lock->mark_failed;
733 } elsif ($mode eq 'koji') {
734 # Retrieve task ID of submitted build
735 my $task_id = $lock->retrievereference($self->taskstore);
737 $lock->log("Could not load task ID for `". $nevra .
738 "' build from `" . $self->taskstore . "' file: $@\n");
739 return $lock->mark_failed;
741 $task_id = $$task_id;
743 # Wait for build task result
744 # TODO: How to recognize the process died for other reason
745 # than build failure?
746 if (!$lock->do($self->repodir, 'koji', 'watch-task', $task_id)) {
747 $lock->log("Could not get status of Koji task `" . $task_id .
748 "' for `$nevra' build, or the task failed.\n");
749 return $lock->mark_failed;
751 } elsif ($mode eq 'mock') {
752 my $srpm_name = $self->get_srpm_name($lock);
753 if (! defined $srpm_name) {
754 return $lock->mark_failed;
756 if (!replace_directory
($lock, $self->mockdir)) {
757 return $lock->mark_failed;
759 # FIXME: Specify mock config to match selected dist and branch
761 # FIXME: Inject already rebuilt packages
762 if (!$lock->do(undef, 'mock', '--resultdir', $self->mockdir,
763 '--rebuild', $srpm_name)) {
764 $lock->log("Could not build `" . $nevra . "' in mock.\n");
765 return $lock->mark_failed;
768 $lock->log("Could not build `" . $nevra .
769 "' because of unknown building mode `" . $mode . "'.\n");
770 return $lock->mark_failed;
773 return $lock->mark_done;
777 # Waits for build root rotation. Just built package will be available for
778 # other packages at build time after returning from this fuction.
779 # If first argument is "koji", it will wait for the Koji rotation.
780 # If first argument is "mock", it will create yum repository in directory with
782 # If first argument is "local", this function is void,
783 # Requires `update'. Sould be called after `build'.
784 # Return true on success.
785 sub dowaitforbuildroot
{
786 my ($self, $mode) = @_;
787 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
789 if ($lock->is_done) { return 1; }
791 my $nevra = $self->get_nevra_from_git($lock);
792 if (! defined $nevra) {
793 return $lock->mark_failed;
796 if ($mode eq 'koji') {
797 if (!$lock->do($self->repodir, 'koji', 'wait-repo',
798 '--build=' . $nevra, '--target', $self->target)) {
799 $lock->log("Koji does not contain `" . $nevra .
800 "' package in build root for `" . $self->target .
801 "' build target yet.\n");
802 return $lock->mark_failed;
804 } elsif ($mode eq 'mock') {
805 $lock->log("`" . $nevra .
806 "' built in mock, creating yum repository...\n");
807 if (!$lock->do($self->rpmdir, 'createrepo', '.')) {
808 $lock->log("Could not create yum repository for `" . $nevra .
810 return $lock->mark_failed;
812 $lock->log("`" . $nevra .
813 "' yum repository created successfully.\n");
815 $lock->log("`" . $nevra .
816 "' built locally, not waiting on Koji rotation.\n");
819 return $lock->mark_done;
822 # Set hash of build-time dependencies (requires attribute).
823 # Return undef in case of failure.
824 sub get_buildrequires
{
827 print "Getting BuildRequires for `" . $self->name . "'...\n";
829 # Procede all steps, each must be re-doable
831 $ok = $self->srpm if $ok;
832 $ok = $self->storebuildrequires if $ok;
833 $ok = $self->buildrequires if $ok;
838 print "BuildRequires for `" . $self->name .
839 "' package distilled successfully.\n";
842 print "Could not get BuildRequires for `" . $self->name .
848 # Set hash of run-time requires (Requires attribute).
849 # Return true on success, undef in case of failure.
850 # XXX: Requires `runrequiresstore'
851 sub get_binaryrequires
{
854 print "Getting run-time requires for `" . $self->name . "'...\n";
856 $ok = $self->storebinaryrequires;
857 $ok = $self->loadbinaryrequires if $ok;
860 print "Run-time requires for `" . $self->name .
861 "' package distilled successfully.\n";
864 print "Could not get run-time requires for `" . $self->name .
870 # Set hash of run-time provides (provides attribute).
871 # Return true on success, undef in case of failure.
872 # XXX: Requires `providesstore'
873 sub get_binaryprovides
{
876 print "Getting binary provides for `" . $self->name . "'...\n";
878 $ok = $self->storebinaryprovides;
879 $ok = $self->loadbinaryprovides if $ok;
882 print "Provides for `" . $self->name .
883 "' package distilled successfully.\n";
886 print "Could not get Provides for `" . $self->name . "' package.\n";
891 # Set hash of run-time requires (Requires attribute) and provides
892 # (provides attribute). Common wrapper for getbinaryrequires() and
893 # getbinaryprovides().
894 # Return true on success, undef in case of failure.
895 # XXX: Requires `runrequiresstore' and `providesstore'
896 sub get_binarydependencies
{
899 print "Getting binary dependencies for `" . $self->name . "'...\n";
901 $ok = $self->get_binaryrequires;
902 $ok = $self->get_binaryprovides if $ok;
905 print "Binary dependencies for `" . $self->name .
906 "' package distilled successfully.\n";
909 print "Could not get binary dependencies for `" . $self->name .
915 # Rebuild a package without waiting for propagation to next build root.
916 # First argument defines build mode:
917 # "koji" publish commit and build in Koji,
918 # "local" build locally without pushing commits to server,
919 # "mock" build in mock without pushing commits to server.
920 # Second argument is reference to array of repository URLs to use as package
921 # base when building the package.
923 my ($self, $mode, $repositories) = @_;
925 print "Rebuilding `" . $self->name . "'...\n";
927 # Proceed all steps, each must be re-doable
929 $ok = $self->update($mode) if $ok;
930 $ok = $self->submitbuild if ($ok and $mode eq 'koji');
931 $ok = $self->build($mode, $repositories) if $ok;
932 $ok = $self->binaryrpm($mode) if $ok;
933 $ok = $self->get_binaryprovides if $ok;
934 $ok = $self->get_binaryrequires if $ok;
937 print "`" . $self->name . "' rebuild finished successfully.\n";
939 print "`" . $self->name . "' rebuild failed.\n";
944 # Wait for the package propagated into new build root.
945 # If first argument is "koji", waits for Koji build root rotation,
946 # Otherwise waits locally (no-op).
947 # XXX: Requires `update', should be called after rebuilding package.
948 sub waitforbuildroot
{
949 my ($self, $mode) = @_;
951 print "Waiting for `" . $self->name . "' to get to build root...\n";
953 $ok = $self->dowaitforbuildroot($mode);
956 print "`" . $self->name . "' propagated successfully.\n";
958 print "`" . $self->name . "' propagation failed.\n";