aboutsummaryrefslogtreecommitdiff
path: root/brep
diff options
context:
space:
mode:
Diffstat (limited to 'brep')
-rw-r--r--brep/handler/ci/ci-load.in62
-rw-r--r--brep/handler/submit/submit.bash.in33
-rw-r--r--brep/handler/upload/upload-bindist.in92
3 files changed, 170 insertions, 17 deletions
diff --git a/brep/handler/ci/ci-load.in b/brep/handler/ci/ci-load.in
index dbdc450..6029b7b 100644
--- a/brep/handler/ci/ci-load.in
+++ b/brep/handler/ci/ci-load.in
@@ -10,6 +10,11 @@
# brep tenant id to this value and include the resulting URL in the response
# message.
#
+# --cancel-url <url>
+# CI task canceling 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)).
#
@@ -36,6 +41,7 @@ shopt -s nullglob # Expand no-match globs to nothing rather than themselves.
# The handler's own options.
#
result_url=
+cancel_url=
while [[ "$#" -gt 0 ]]; do
case $1 in
--result-url)
@@ -43,6 +49,11 @@ while [[ "$#" -gt 0 ]]; do
result_url="${1%/}"
shift
;;
+ --cancel-url)
+ shift
+ cancel_url="${1%/}"
+ shift
+ ;;
*)
break
;;
@@ -108,6 +119,14 @@ declare -A packages
#
spec=
+# Third party service information which, if specified, needs to be associated
+# with the being created tenant.
+#
+service_id=
+service_type=
+service_data=
+service_load=
+
while IFS=: read -ru "$manifest_parser_ofd" -d '' n v; do
case "$n" in
repository) repository="$v" ;;
@@ -122,6 +141,18 @@ while IFS=: read -ru "$manifest_parser_ofd" -d '' n v; do
fi
spec="$spec$v"
;;
+
+ service-id) service_id="$v" ;;
+ service-type) service_type="$v" ;;
+ service-data) service_data="$v" ;;
+
+ service-action)
+ if [[ "$v" == "load" ]]; then
+ service_load=true
+ elif [[ "$v" != "start" ]]; then
+ error "unrecognized service action '$v'"
+ fi
+ ;;
esac
done
@@ -141,6 +172,12 @@ if [[ -n "$simulate" && "$simulate" != "success" ]]; then
exit_with_manifest 400 "unrecognized simulation outcome '$simulate'"
fi
+# Use the generated reference if the tenant service id is not specified.
+#
+if [[ -n "$service_type" && -z "$service_id" ]]; then
+ service_id="$reference"
+fi
+
message_suffix=
if [[ -n "$result_url" ]]; then
message_suffix=": $result_url/@$reference" # Append the tenant id.
@@ -306,6 +343,22 @@ if [[ -n "$interactive" ]]; then
loader_options+=(--interactive "$interactive")
fi
+# Pass the tenant service information, if specified, to the loader.
+#
+if [[ -n "$service_id" ]]; then
+ loader_options+=(--service-id "$service_id" --service-type "$service_type")
+
+ if [[ -n "$service_data" ]]; then
+ loader_options+=(--service-data "$service_data")
+ fi
+
+ # Load the pre-created tenant rather than create a new one.
+ #
+ if [[ "$service_load" ]]; then
+ loader_options+=(--existing-tenant)
+ fi
+fi
+
run "$loader" "${loader_options[@]}" "$loadtab"
# Remove the no longer needed CI request data directory.
@@ -313,4 +366,11 @@ run "$loader" "${loader_options[@]}" "$loadtab"
run rm -r "$data_dir"
trace "CI request for '$spec' is queued$message_suffix"
-exit_with_manifest 200 "CI request is queued$message_suffix"
+
+msg="CI request is queued$message_suffix"
+
+if [[ -n "$cancel_url" ]]; then
+ msg="$msg"$'\n'"To cancel CI request: $cancel_url=$reference&reason="
+fi
+
+exit_with_manifest 200 "$msg"
diff --git a/brep/handler/submit/submit.bash.in b/brep/handler/submit/submit.bash.in
index 30a09f8..7826809 100644
--- a/brep/handler/submit/submit.bash.in
+++ b/brep/handler/submit/submit.bash.in
@@ -52,7 +52,24 @@ function extract_package_manifest () # <archive> <manifest>
# not fail due to this package down the road. Note that we also make sure
# that all the manifest values are known (see bpkg-pkg-verify for details).
#
- if ! run_silent bpkg pkg-verify --deep --manifest "$arc" >"$man"; then
+ local cmd=(bpkg pkg-verify --deep --manifest "$arc")
+ trace_cmd "${cmd[@]}"
+
+ # Note that we used to just advise the user to run bpkg-pkg-verify locally
+ # for the details on the potential failure. That, however, may not always be
+ # helpful since the user can use a different version of the toolchain and so
+ # may observe a different behavior. Thus, we add the bpkg-pkg-verify error
+ # message to the response, turning it into an info. This way the user may
+ # potentially see the following bdep-publish diagnostics:
+ #
+ # error: package archive is not valid
+ # info: unable to satisfy constraint (build2 >= 0.17.0-) for package libhello-1.0.0.tar.gz
+ # info: available build2 version is 0.16.0
+ # info: run bpkg pkg-verify for details
+ # info: reference: 308e155764c8
+ #
+ local e
+ if ! e="$("${cmd[@]}" 2>&1 >"$man")"; then
# Perform the sanity check to make sure that bpkg is runnable.
#
@@ -60,7 +77,19 @@ function extract_package_manifest () # <archive> <manifest>
error "unable to run bpkg"
fi
- exit_with_manifest 400 "archive is not a valid package (run bpkg pkg-verify for details)"
+ # Note that bpkg-pkg-verify diagnostics may potentially contain the
+ # archive absolute path. Let's sanitize this diagnostics by stripping the
+ # archive directory path, if present. Also note that to use sed for that
+ # we first need to escape the special regex characters and slashes in the
+ # archive directory path (see sed's basic regular expressions for
+ # details).
+ #
+ local d="$(sed 's/[[\.*^$/]/\\&/g' <<<"$(dirname "$arc")/")"
+
+ e="$(sed -e "s/$d//g" -e 's/^error:/ info:/' <<<"$e")"
+ e=$'package archive is not valid\n'"$e"$'\n info: run bpkg pkg-verify for details'
+
+ exit_with_manifest 400 "$e"
fi
}
diff --git a/brep/handler/upload/upload-bindist.in b/brep/handler/upload/upload-bindist.in
index ba05bc3..05d0bcf 100644
--- a/brep/handler/upload/upload-bindist.in
+++ b/brep/handler/upload/upload-bindist.in
@@ -22,15 +22,19 @@
# sanitized, having the "bindist", <instance>, <os-release-name-id>, and
# <os-release-name-id><os-release-version-id> dash-separated sub-components
# removed. If the component becomes empty as a result of the sanitization,
-# then "default" is assumed. For example, the following symlink paths:
+# then the target CPU is assumed, if the package is not architecture-
+# independent, and "noarch" otherwise. If the sanitized component is not
+# empty, the package is not architecture-independent, and the resulting
+# component doesn't containt the target CPU, then prepend it with the <cpu>-
+# prefix. For example, the following symlink paths:
#
# .../archive/windows10/foo/libfoo/1.0.0/bindist-archive-windows10-release
# .../archive/windows10/foo/libfoo/1.0.0/bindist-archive-windows10
#
# are reduced to:
#
-# .../archive/windows10/foo/libfoo/1.0.0/release
-# .../archive/windows10/foo/libfoo/1.0.0/default
+# .../archive/windows10/foo/libfoo/1.0.0/x86_64-release
+# .../archive/windows10/foo/libfoo/1.0.0/x86_64
#
# To achieve this the handler performs the following steps (<dir> is passed as
# last argument by brep and is a subdirectory of upload-data):
@@ -175,6 +179,7 @@ name=
version=
project=
package_config=
+target=
tenant=
while IFS=: read -ru "$manifest_parser_ofd" -d '' n v; do
@@ -186,6 +191,7 @@ while IFS=: read -ru "$manifest_parser_ofd" -d '' n v; do
version) version="$v" ;;
project) project="$v" ;;
package-config) package_config="$v" ;;
+ target) target="$v" ;;
tenant) tenant="$v" ;;
esac
done
@@ -220,15 +226,50 @@ if [[ -z "$package_config" ]]; then
error "package-config manifest value expected"
fi
-# Let's disallow dots in the package-config manifest value since the latter
-# serves as the package configuration symlink name and the dot can be
-# misinterpreted by brep as an extension separator, which the implementation
-# relies upon.
+if [[ -z "$target" ]]; then
+ error "target manifest value expected"
+fi
+
+# Let's disallow the leading dot in the package-config manifest value since
+# the latter serves as the package configuration symlink name and brep skips
+# symlinks with the leading dots assuming them as hidden (see
+# mod/mod-package-version-details.cxx for details).
+#
+if [[ "$package_config" == "."* ]]; then
+ exit_with_manifest 400 "package-config manifest value may not start with dot"
+fi
+
+# Extract the CPU component from the target triplet and deduce the binary
+# distribution-specific CPU representation which is normally used in the
+# package file names.
#
-if [[ "$package_config" == *"."* ]]; then
- exit_with_manifest 400 "package-config manifest value may not contain dot"
+cpu="$(sed -n -re 's/^([^-]+)-.+/\1/p' <<<"$target")"
+
+if [[ -z "$cpu" ]]; then
+ error "CPU expected in target triplet '$target'"
fi
+# Use CPU extracted from the target triplet as a distribution-specific
+# representation, unless this is Debian or Fedora (see bpkg's
+# system-package-manager-{fedora,debian}.cxx for details).
+#
+cpu_dist="$cpu"
+
+case $instance in
+ debian)
+ case $cpu in
+ x86_64) cpu_dist="amd64" ;;
+ aarch64) cpu_dist="arm64" ;;
+ i386 | i486 | i586 | i686) cpu_dist="i386" ;;
+ esac
+ ;;
+ fedora)
+ case $cpu in
+ i386 | i486 | i586 | i686) cpu_dist="i686" ;;
+ esac
+ ;;
+esac
+
# Unpack the archive.
#
run tar -xf "$data_dir/$archive" -C "$data_dir"
@@ -283,6 +324,10 @@ fi
# Parse the package file manifest list and cache the file paths.
#
+# While at it, detect if the package is architecture-specific or not by
+# checking if any package file names contain the distribution-specific CPU
+# representation (as a sub-string).
+#
# Note that while we currently only need the package file paths, we can make
# use of their types and system names in the future. Thus, let's verify that
# all the required package file values are present and, while at it, cache
@@ -292,6 +337,8 @@ package_file_paths=()
package_file_types=()
package_file_system_names=()
+arch_specific=
+
# The outer loop iterates over package file manifests while the inner loop
# iterates over manifest values in each such manifest.
#
@@ -325,6 +372,10 @@ while [[ "$more" ]]; do
package_file_paths+=("$path")
package_file_types+=("$type")
package_file_system_names+=("$system_name") # Note: system name can be empty.
+
+ if [[ "$path" == *"$cpu_dist"* ]]; then
+ arch_specific=true
+ fi
done
manifest_parser_finish
@@ -345,8 +396,18 @@ for c in $(sed 's/-/ /g' <<<"$package_config"); do
fi
done
+# Reflect the architecture in the sanitized configuration name.
+#
if [[ -z "$config" ]]; then
- config="default"
+ if [[ "$arch_specific" ]]; then
+ config="$cpu"
+ else
+ config="noarch"
+ fi
+else
+ if [[ "$arch_specific" && ("$config" != *"$cpu"*) ]]; then
+ config="$cpu-$config"
+ fi
fi
# Compose the package configuration symlink path.
@@ -393,7 +454,8 @@ fi
# Create parent (doesn't fail if directory exists).
#
-run mkdir -p "$(dirname "$config_dir")"
+config_parent_dir="$(dirname "$config_dir")"
+run mkdir -p "$config_parent_dir"
created=
@@ -459,10 +521,12 @@ done
trace "+ (cd $config_dir && exec sha256sum -b ${package_file_paths[@]} >.packages.sha256)"
(cd "$config_dir" && exec sha256sum -b "${package_file_paths[@]}" >".packages.sha256")
-# Create the new package configuration symlink.
+# Create the new package configuration "hidden" symlink. Construct its name by
+# prepending the configuration directory name with a dot.
#
-config_link_new="$config_dir.symlink"
-run ln -s $(basename "$config_dir") "$config_link_new"
+config_dir_name="$(basename "$config_dir")"
+config_link_new="$config_parent_dir/.$config_dir_name"
+run ln -s "$config_dir_name" "$config_link_new"
# Switch the package configuration symlink atomically. But first, cache the
# previous package configuration symlink target if the --keep-previous option