summaryrefslogtreecommitdiff
path: root/repo/bin/generate-archive-lists
blob: b17a14c791e60f3ad9f244f201c2a5fb1025239a (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
#!/bin/bash

set -eu
set -o pipefail

# S3 bucket
S3="s3://apt-archive.postgresql.org/pub/repos/apt"

PATH=$PATH:/srv/apt/repo/bin

cd /srv/apt/archive/pub/repos/apt

export PGSERVICE=pgapt

DIST_ARCHS="SELECT distinct distribution, architecture FROM distribution WHERE last_update > now() - '2 days'::interval ORDER BY 1, 2;"
DISTS="SELECT distinct distribution FROM srcdistribution WHERE last_update > now() - '2 days'::interval ORDER BY 1;"

# generate Packages files
psql -AXt -F ' ' -c "$DIST_ARCHS" | \
while read distribution architecture; do
  [ -t 1 ] && echo "$distribution-archive/$architecture ..."
  DIR="dists/$distribution-archive/main/binary-$architecture"
  mkdir -p $DIR
  PACKAGES="SELECT concat_ws(E'\n', format(E'%s\nTimestamp: %s\n', p.control, h.time)) FROM packagehist h JOIN package p ON (h.package, h.version, h.arch) = (p.package, p.version, p.arch) WHERE (h.distribution, h.architecture) = ('$distribution', '$architecture');"
  psql -AXtc "$PACKAGES" > $DIR/Packages # generate both uncompressed and compressed version
  rm -f $DIR/Packages.bz2
  bzip2 --keep $DIR/Packages
done

# generate Sources and InRelease files
psql -AXt -F ' ' -c "$DISTS" | \
while read distribution; do
  [ -t 1 ] && echo "$distribution-archive/source ..."
  DIR="dists/$distribution-archive/main/source"
  mkdir -p $DIR
  PACKAGES="SELECT concat_ws(E'\n', format(E'%s\nTimestamp: %s\n', s.control, h.time)) FROM sourcehist h JOIN source s ON (h.source, h.srcversion) = (s.source, s.srcversion) WHERE h.distribution = '$distribution';"
  psql -AXtc "$PACKAGES" > $DIR/Sources # generate both uncompressed and compressed version
  rm -f $DIR/Sources.bz2
  bzip2 --keep $DIR/Sources

  # generate InRelease files for this distribution (includes Packages files from above)
  DIR="dists/$distribution-archive"
  (
    cd $DIR
    rm -f InRelease
    RELEASE="$(apt-ftparchive release \
      -o APT::FTPArchive::Release::Origin=apt-archive.postgresql.org \
      -o APT::FTPArchive::Release::Label='PostgreSQL for Debian/Ubuntu archive repository' \
      -o APT::FTPArchive::Release::Suite=$distribution-archive \
      -o APT::FTPArchive::Release::Codename=$distribution-archive \
      .)"
    echo "$RELEASE" | gpg --clearsign > InRelease

    # remove uncompressed files after they have been scanned
    rm main/source/Sources main/*/Packages
  )
  indexhtml $DIR
  indexhtml $DIR/main
  for dir in $DIR/main/*/; do
    indexhtml $dir
  done
done

indexhtml dists

# upload to S3 and invalidate cache for the dists/ dir
aws s3 sync --quiet /srv/apt/archive/pub/repos/apt/dists $S3/dists
aws cloudfront create-invalidation --distribution-id E2CPN16I5GL3S7 --path "/pub/repos/apt/dists/*" > /dev/null

cd /srv/apt/archive/pub/repos/apt

# generate index files for package pool directories
PACKAGES=$(psql -XAtc "SELECT source FROM src WHERE upload IS NULL")
for PACKAGE in $PACKAGES; do
  case $PACKAGE in
    lib*) INITIAL="$(echo $PACKAGE | cut -c 1-4)" ;;
    *)    INITIAL="$(echo $PACKAGE | cut -c 1)" ;;
  esac
  DIRECTORY="pool/main/$INITIAL/$PACKAGE"

  QUERY="SELECT c->>'directory' || '/' || sf.filename AS path, sf.filename, NULL::text AS size, s.time
    FROM source s
    JOIN sourcefile sf ON (s.source, s.srcversion) = (sf.source, sf.srcversion)
    WHERE s.source = '$PACKAGE'
  UNION ALL SELECT p.c->>'filename', regexp_replace(p.c->>'filename', '.*/', ''), p.c->>'size', p.time
    FROM package p
    WHERE p.source = '$PACKAGE'
  ORDER BY filename"
  FORMAT="WITH q AS ($QUERY)
    SELECT format(E'<a href=\"/pub/repos/apt/%s\">%s</a> %s %s <br /> \\n',
      regexp_replace(path, '\\+', '%2B', 'g'),
      filename,
      time,
      size || ' bytes')
    FROM q"

  mkdir -p "$DIRECTORY"

  (
    echo "<tt>"
    echo "<a href=\"../index.html\">../</a> <br />"
    psql -XAtc "$FORMAT"
    echo "</tt>"
  ) > "$DIRECTORY/index.html"

  upload-to-s3 "$DIRECTORY/index.html"
  aws cloudfront create-invalidation --distribution-id E2CPN16I5GL3S7 --path "/pub/repos/apt/$DIRECTORY/index.html" > /dev/null

  indexhtml "pool/main/$INITIAL"
  upload-to-s3 "pool/main/$INITIAL/index.html"

  psql -Xqc "UPDATE src SET upload = true WHERE source = '$PACKAGE'"
done

# alert about any failed uploads
psql -XAt <<EOF
SELECT 'failed sourcefile upload:', source, srcversion FROM sourcefile WHERE upload IS FALSE;
SELECT 'failed package upload:', package, version, arch FROM package WHERE upload IS FALSE;
SELECT 'failed pool/main/p/package/index.html upload:', * FROM src WHERE upload IS FALSE;
EOF