aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Iurt/File.pm
blob: 5029cb843cf709ee39c1060430ed495c06fe6027 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package Iurt::File;

use base qw(Exporter);
use Iurt::Config qw(get_mandatory_arch);
use File::Copy 'move';
use File::Path 'make_path';
use Iurt::Util qw(plog);
use MDK::Common qw(find member partition);
use strict;

our @EXPORT = qw(
    check_upload_tree 
    cleanup_failed_build
);

sub check_upload_tree {
    my ($todo, $func, $o_post) = @_;

    # Squash double slashes for cosmetics
    $todo =~ s!/+!/!g;

    opendir(my $dir, $todo);
    plog('INFO', "check dir: $todo");

    foreach my $f (readdir $dir) {
	$f =~ /^\.{1,2}$/ and next;
	if (-d "$todo/$f") {
	    plog('DEBUG', "checking target $todo/$f");
	    opendir my $target_dir, "$todo/$f";

	    foreach my $m (readdir $target_dir) {
		$m =~ /^\.{1,2}$/ and next;
		if (-d "$todo/$f/$m") {
		    plog('DEBUG', "checking media $todo/$f/$m");
		    opendir my $media_dir, "$todo/$f/$m";

		    foreach my $s (readdir $media_dir) {
			$s =~ /^\.{1,2}$/ and next;
			if (-d "$todo/$f/$m/$s") {
			    if ($func) {
				opendir my $submedia_dir, "$todo/$f/$m/$s";
				foreach my $r (readdir $submedia_dir) {
				    $r =~ /^\.{1,2}$/ and next;
				    $func->($todo, $f, $m, $s, $r);
				}
			    }
			    # cleaning
			    if ($o_post) {
				opendir my $submedia_dir, "$todo/$f/$m/$s";
				foreach my $r (readdir $submedia_dir) {
				    $r =~ /^\.{1,2}$/ and next;
				    $o_post->($todo, $f, $m, $s, $r);
				}
			    }
			} else {
			    # may need to check also here for old target
			}
		    }
		}
	    }
	}
    }
}
 
sub cleanup_failed_build {
    my ($todo_dir, $done_dir, $fail_dir, $prefix, $ent, $config) = @_;

    my $fatal_failure;
    my $is_noarch;
    my $mandatory_arch = get_mandatory_arch($config, $ent->{target});
    my $arch_list = get_target_arch($config, $ent->{target});
    my @processed_arches;
    my @failed_arches;

    foreach my $arch (@$arch_list, "noarch") {
        my $prefix_arch = "$done_dir/${prefix}_$arch";
        if (-f "$prefix_arch.fail") {
            push @processed_arches, $arch;
            push @failed_arches, $arch;
            $arch eq "noarch" and $is_noarch = 1;
            if (member($arch, @$mandatory_arch, "noarch")) {
                plog('DEBUG', "failure for mandatory arch $arch, aborting build");
                $fatal_failure = 1;
            } else {
                plog('DEBUG', "failure for non-mandatory arch $arch");
            }
            $arch eq "noarch" and $is_noarch = 1;
        } elsif (-f "$prefix_arch.done" || -f "$prefix_arch.excluded") {
            push @processed_arches, $arch;
            $arch eq "noarch" and $is_noarch = 1;
        }
    }

    my $all_processed = $is_noarch || (() = sort(@$arch_list)) ~~ (() = sort(@processed_arches));
    my ($failed_rpms, $kept_rpms);
    if ($fatal_failure) {
	$failed_rpms = $ent->{rpms};
    } else {
	plog('DEBUG', "no fatal failure, keeping other builds going");
        my $failed_arch_pattern = join("|", @failed_arches);
	($failed_rpms, $kept_rpms) = partition { /\.($failed_arch_pattern)\.rpm$/ } @{$ent->{rpms}};
    }

    foreach my $rpm (@$failed_rpms) {
	my $file = "$done_dir/${prefix}_$rpm";
	plog('DEBUG', "moving built rpm $file to $fail_dir/");
	move($file, "$fail_dir/${prefix}_$rpm");
    }

    if ($fatal_failure) {
        # abort all remaining builds
        delete $ent->{rpms};
    } else {
	# keep rpms for other architectures
	$ent->{rpms} = $kept_rpms;
    }

    if ($fatal_failure || (@failed_arches && $all_processed)) {
        # no need to keep the src.rpm in todo, move it to fail
        foreach my $srpm (@{$ent->{srpms}}) {
            my $file = "$todo_dir/${prefix}_$srpm";
            plog('DEBUG', "moving $file to $fail_dir/");
            move($file, "$fail_dir/${prefix}_$srpm");
            if ($fatal_failure) {
                # If one arch has been generated, we also have a src.rpm in done
                $file = "$done_dir/${prefix}_$srpm";
                if (-f $file) {
                    plog('DEBUG', "deleting $file");
                    unlink $file;
                }
            }
        }
    }

    if ($fatal_failure && -d "$done_dir/$prefix") {
	make_path("$fail_dir/$prefix");
	foreach my $file (glob "$done_dir/$prefix/*") {
	    plog('DEBUG', "moving $file to $fail_dir/$prefix/");
	    move($file, "$fail_dir/$prefix/");
	}
    }
}