diff options
Diffstat (limited to 'brep/handler')
-rw-r--r-- | brep/handler/ci/ci-load.in | 62 | ||||
-rw-r--r-- | brep/handler/submit/submit.bash.in | 33 | ||||
-rw-r--r-- | brep/handler/upload/upload-bindist.in | 92 |
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 |