generate-build-manifest 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #!/usr/bin/perl
  2. # © 2015 Cyril Brulebois <cyril@debamax.com>, for the Tails project.
  3. # © 2016 Tails developers <tails@boum.org>
  4. use strict;
  5. use warnings;
  6. use File::Slurp;
  7. use List::MoreUtils qw(uniq);
  8. use YAML::XS;
  9. # NOTE: For reference, the first one is generated by debootstrap
  10. # (>= 1.0.73), while the other two are generated by the apt-get
  11. # wrapper installed in the chroot during the build.
  12. my %package_type = qw(
  13. deburis binary
  14. binuris binary
  15. srcuris source
  16. );
  17. ### Various usability checks:
  18. sub usage {
  19. die "Usage: $0 debootstrap-dir manifest-file";
  20. }
  21. my $debootstrap = shift @ARGV
  22. or usage;
  23. my $manifest = shift @ARGV
  24. or usage;
  25. if (! -d $debootstrap) {
  26. print "E: $debootstrap isn't a directory\n";
  27. usage;
  28. }
  29. if (-f "$debootstrap/unknown") {
  30. print "E: actions unsupported by the apt-get wrapper were logged ",
  31. "in $debootstrap/unknown. Aborting.";
  32. exit 1;
  33. }
  34. my $extra_packages_file = 'config/build-manifest-extra-packages.yml';
  35. my $extra_packages;
  36. if (-e $extra_packages_file) {
  37. my $yaml = read_file($extra_packages_file);
  38. my $extra_packages_data = Load $yaml
  39. or die "E: failed to load $extra_packages_file: $!";
  40. $extra_packages = $extra_packages_data->{packages};
  41. }
  42. ### Read (package, version, uri) tuples and generate a single (package, version) list:
  43. my $data;
  44. foreach my $type (keys %package_type) {
  45. my $path = "$debootstrap/$type";
  46. if (! -f $path ) {
  47. print "E: $path is missing, wrong debootstrap-dir parameter? (got: $debootstrap)\n";
  48. usage;
  49. }
  50. print "I: processing $path\n";
  51. foreach my $line (read_file($path)) {
  52. chomp $line;
  53. my ($package, $version, $uri) = split / /, $line;
  54. # Store package_version_arch to ease sort+uniq for deduplication:
  55. my $arch = 'source';
  56. if ($package_type{$type} eq 'binary') {
  57. if ($uri =~ /_([^_]+)\.deb$/) {
  58. $arch = $1;
  59. }
  60. else {
  61. die "unable to determine architecture for uri=$uri";
  62. }
  63. }
  64. push @{ $data->{ packages_tmp }->{ $package_type{$type} } }, "${package}_${version}_${arch}";
  65. }
  66. # Add extra packages
  67. if ($extra_packages->{$package_type{$type}}) {
  68. foreach my $pkginfo (@{ $extra_packages->{$package_type{$type}} }) {
  69. my $package = $pkginfo->{package};
  70. my $version = $pkginfo->{version};
  71. my $arch = $package_type{$type} eq 'binary'
  72. ? $pkginfo->{arch}
  73. : 'source';
  74. push @{ $data->{ packages_tmp }->{ $package_type{$type} } },
  75. "${package}_${version}_${arch}";
  76. }
  77. }
  78. }
  79. ### Extract list of (origin, reference) from the build configuration
  80. ### (the resolved serials, stored under tmp by "apt-snapshots-serials prepare-build"):
  81. my %origin_reference;
  82. while (my $origin_dir = glob('tmp/APT_snapshots.d/*')) {
  83. my $origin_name = $origin_dir;
  84. $origin_name =~ s{\A tmp/APT_snapshots[.]d/}{}xms;
  85. $origin_reference{$origin_name} = read_file("$origin_dir/serial");
  86. chomp $origin_reference{$origin_name};
  87. $data->{origin_references}->{ $origin_name }->{reference} = $origin_reference{ $origin_name } || 'unknown';
  88. }
  89. ### Deduplicate:
  90. foreach my $type (uniq values %package_type) {
  91. foreach my $entry (uniq sort @{ $data->{ packages_tmp }->{ $type } }) {
  92. if ($entry =~ m{^(.+)_(.+)_(.+)$}) {
  93. my ($package, $version, $arch) = ($1, $2, $3);
  94. my $item = { package => $package, version => $version, arch => $arch, };
  95. # Reduce clutter:
  96. delete $item->{arch}
  97. if $type eq 'source';
  98. push @{ $data->{ packages }->{ $type } }, $item;
  99. }
  100. }
  101. }
  102. delete $data->{ packages_tmp };
  103. my $yaml = Dump $data;
  104. write_file($manifest, $yaml);