aboutsummaryrefslogtreecommitdiff
path: root/brep/handler/ci/ci-load.in
blob: da5fb911ce4930eb64bfa79706f6aca00d4c25f0 (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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#!/usr/bin/env bash

# file      : brep/handler/ci/ci-load.in
# copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
# license   : MIT; see accompanying LICENSE file

# Package CI request handler that loads the packages into the brep database.
#
# --result-url <url>
#  Result URL base for the response. If specified, the handler will append the
#  brep tenant id to this value and include the resulting URL in the response
#  message.
#
# <loader-path>
#  Loader program (normally brep-load(1)).
#
# <loader-options>
#  Loader options (normally --db-*).
#
usage="usage: $0 [--result-url <url>] <loader-path> [<loader-options>] <dir>"

verbose= #true

# Repository information fetch timeout (seconds).
#
fetch_timeout=60

trap "{ exit 1; }" ERR
set -o errtrace # Trap ERR in functions.

@import brep/handler/handler@
@import brep/handler/ci/ci@

# The handler's own options.
#
result_url=
while [ $# -gt 0 ]; do
  case $1 in
    --result-url)
      shift
      result_url="${1%/}"
      shift
      ;;
    *)
      break
      ;;
  esac
done

# The loader path.
#
loader="$1"

if [ -z "$loader" ]; then
  error "$usage"
fi

shift

# Assume that the remaining arguments except the last one are the loader
# options.
#
loader_options=()
while [ $# -gt 1 ]; do
  loader_options+=("$1")
  shift
done

# CI request data directory (last argument).
#
data_dir="$1"

if [ -z "$data_dir" ]; then
  error "$usage"
fi

if [ ! -d "$data_dir" ]; then
  error "'$data_dir' does not exist or is not a directory"
fi

reference="$(basename "$data_dir")"

# Parse the CI request manifest and obtain the repository URL, package names
# with optional versions, as well as the simulate value.
#
manifest_parser_start "$data_dir/request.manifest"

repository=
packages=()
simulate=

while IFS=: read -ru "$manifest_parser_ofd" -d '' n v; do
  case "$n" in
    repository) repository="$v"  ;;
    package)    packages+=("$v") ;;
    simulate)   simulate="$v"    ;;
  esac
done

manifest_parser_finish

if [ -z "$repository" ]; then
  error "repository manifest value expected"
fi

if [ -n "$simulate" -a "$simulate" != "success" ]; then
  exit_with_manifest 400 "unrecognized simulation outcome '$simulate'"
fi

# Produce the bpkg-build(1)-like package spec for tracing.
#
# The spec normally contains the full commit id and so feels too hairy to
# include in the result manifest message.
#
spec=
for p in "${packages[@]}"; do
  if [ -n "$spec" ]; then
    spec="$spec,"
  fi
  spec="$spec$p"
done

if [ -n "$spec" ]; then
  spec="$spec@"
fi

spec="$spec$repository"

message_suffix=
if [ -n "$result_url" ]; then
  message_suffix=": $result_url"
fi

# Exit with the 'CI request is queued' response if simulating.
#
# Note that we can't assume a real repository URL is specified if simulating
# so trying to query the repository info is not a good idea.
#
if [ -n "$simulate" ]; then
  run rm -r "$data_dir"

  trace "CI request for '$spec' is simulated$message_suffix"
  exit_with_manifest 200 "CI request is queued$message_suffix"
fi

# Dump the repositories.manifest and packages.manifest files.
#
run mkdir "$data_dir/cache"
dump_repository_manifests "$repository" "$data_dir/cache" "$fetch_timeout"

# In most cases all the requested for CI packages belong to the same project,
# which would be nice to use as the repository display name. However, that
# would require parsing packages.manifest just to get this information. Which
# feels like a bit of an overkill. So for now let's just use the leaf
# component of the repository URL since it will be the same as the project
# name in most (sane) cases.
#
# First, strip the URL query and fragment parts, then prefix, and, finally,
# extension.
#
display_name="$(sed -r \
-e 's%^([^?#]*).*$%\1%' \
-e 's%^.*/([^/]+)/?$%\1%' \
-e 's%(\.[^.]*)$%%' \
<<<"$repository")"

# Create the brep-load(1) loadtab file.
#
loadtab="$data_dir/loadtab"
run echo "$repository $display_name cache:cache" >"$loadtab"

# Load the repository into the brep package database.
#
# Note that for now we load all the packages the repository contains without
# regard to the request manifest package values. Later, we could add filtering
# of the packages.manifest file against the request manifest values. While at
# it, we could also deduce the repository display name (see above). @@ TODO
#
run "$loader" "${loader_options[@]}" --force --shallow "$loadtab"

# @@ TMP TENANCY: before we add tenancy support we also need to manually
#    cleanup the build database. We will assume the cleanup code to optionally
#    be present in a separate bash script which path is deduced from the
#    handler's own path by adding the -clean suffix.
#
cleaner="$0-clean"
if [ -f "$cleaner" ]; then

  # Let's pass the CI request data directory to the cleaner, so it can create
  # temporary files in this directory.
  #
  run "$cleaner" "$data_dir"
fi

# Remove the no longer needed CI request data directory.
#
run rm -r "$data_dir"

trace "CI request for '$spec' is queued$message_suffix"
exit_with_manifest 200 "CI request is queued$message_suffix"