diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /security/nss/automation | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'security/nss/automation')
77 files changed, 7190 insertions, 0 deletions
diff --git a/security/nss/automation/abi-check/expected-report-libfreebl3.so.txt b/security/nss/automation/abi-check/expected-report-libfreebl3.so.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/security/nss/automation/abi-check/expected-report-libfreebl3.so.txt diff --git a/security/nss/automation/abi-check/expected-report-libfreeblpriv3.so.txt b/security/nss/automation/abi-check/expected-report-libfreeblpriv3.so.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/security/nss/automation/abi-check/expected-report-libfreeblpriv3.so.txt diff --git a/security/nss/automation/abi-check/expected-report-libnspr4.so.txt b/security/nss/automation/abi-check/expected-report-libnspr4.so.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/security/nss/automation/abi-check/expected-report-libnspr4.so.txt diff --git a/security/nss/automation/abi-check/expected-report-libnss3.so.txt b/security/nss/automation/abi-check/expected-report-libnss3.so.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/security/nss/automation/abi-check/expected-report-libnss3.so.txt diff --git a/security/nss/automation/abi-check/expected-report-libnssckbi.so.txt b/security/nss/automation/abi-check/expected-report-libnssckbi.so.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/security/nss/automation/abi-check/expected-report-libnssckbi.so.txt diff --git a/security/nss/automation/abi-check/expected-report-libnssdbm3.so.txt b/security/nss/automation/abi-check/expected-report-libnssdbm3.so.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/security/nss/automation/abi-check/expected-report-libnssdbm3.so.txt diff --git a/security/nss/automation/abi-check/expected-report-libnsssysinit.so.txt b/security/nss/automation/abi-check/expected-report-libnsssysinit.so.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/security/nss/automation/abi-check/expected-report-libnsssysinit.so.txt diff --git a/security/nss/automation/abi-check/expected-report-libnssutil3.so.txt b/security/nss/automation/abi-check/expected-report-libnssutil3.so.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/security/nss/automation/abi-check/expected-report-libnssutil3.so.txt diff --git a/security/nss/automation/abi-check/expected-report-libplc4.so.txt b/security/nss/automation/abi-check/expected-report-libplc4.so.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/security/nss/automation/abi-check/expected-report-libplc4.so.txt diff --git a/security/nss/automation/abi-check/expected-report-libplds4.so.txt b/security/nss/automation/abi-check/expected-report-libplds4.so.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/security/nss/automation/abi-check/expected-report-libplds4.so.txt diff --git a/security/nss/automation/abi-check/expected-report-libsmime3.so.txt b/security/nss/automation/abi-check/expected-report-libsmime3.so.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/security/nss/automation/abi-check/expected-report-libsmime3.so.txt diff --git a/security/nss/automation/abi-check/expected-report-libsoftokn3.so.txt b/security/nss/automation/abi-check/expected-report-libsoftokn3.so.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/security/nss/automation/abi-check/expected-report-libsoftokn3.so.txt diff --git a/security/nss/automation/abi-check/expected-report-libssl3.so.txt b/security/nss/automation/abi-check/expected-report-libssl3.so.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/security/nss/automation/abi-check/expected-report-libssl3.so.txt diff --git a/security/nss/automation/abi-check/previous-nss-release b/security/nss/automation/abi-check/previous-nss-release new file mode 100644 index 0000000000..c80b08e2e4 --- /dev/null +++ b/security/nss/automation/abi-check/previous-nss-release @@ -0,0 +1 @@ +NSS_3_86_BRANCH diff --git a/security/nss/automation/clang-format/Dockerfile b/security/nss/automation/clang-format/Dockerfile new file mode 100644 index 0000000000..9f4f12a636 --- /dev/null +++ b/security/nss/automation/clang-format/Dockerfile @@ -0,0 +1,42 @@ +# Minimal image with clang-format 3.9. +FROM ubuntu:18.04 +LABEL maintainer="Martin Thomson <martin.thomson@gmail.com>" + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + clang-format-10 \ + locales \ + python-dev \ + python-pip \ + python-setuptools \ + python-wheel \ + build-essential \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get autoremove -y && apt-get clean -y + +RUN pip install mercurial==6.1.1 + + +RUN update-alternatives --install /usr/bin/clang-format \ + clang-format $(which clang-format-10) 10 + +ENV SHELL /bin/bash +ENV USER worker +ENV LOGNAME $USER +ENV HOME /home/$USER +ENV HOSTNAME taskcluster-worker +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +ENV HOST localhost +ENV DOMSUF localdomain + +RUN locale-gen $LANG \ + && DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales + +RUN useradd -d $HOME -s $SHELL -m $USER +WORKDIR $HOME +USER $USER + +# Entrypoint - which only works if /home/worker/nss is mounted. +ENTRYPOINT ["/home/worker/nss/automation/clang-format/run_clang_format.sh"] diff --git a/security/nss/automation/clang-format/run_clang_format.sh b/security/nss/automation/clang-format/run_clang_format.sh new file mode 100755 index 0000000000..9f2b20db62 --- /dev/null +++ b/security/nss/automation/clang-format/run_clang_format.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +if [[ $(id -u) -eq 0 ]]; then + # Drop privileges by re-running this script. + # Note: this mangles arguments, better to avoid running scripts as root. + exec su worker -c "$0 $*" +fi + +set -e + +# Apply clang-format on the provided folder and verify that this doesn't change any file. +# If any file differs after formatting, the script eventually exits with 1. +# Any differences between formatted and unformatted files is printed to stdout to give a hint what's wrong. + +# Includes a default set of directories NOT to clang-format on. +blocklist=( + "./automation" \ + "./coreconf" \ + "./doc" \ + "./pkg" \ + "./tests" \ + "./lib/libpkix" \ + "./lib/zlib" \ + "./lib/sqlite" \ + "./gtests/google_test" \ + "./out" \ +) + +top=$(cd "$(dirname $0)/../.."; pwd -P) + +if [ $# -gt 0 ]; then + dirs=("$@") +else + cd "$top" + dirs=($(find . -maxdepth 2 -mindepth 1 -type d ! -path '*/.*' -print)) +fi + +format_folder() +{ + for block in "${blocklist[@]}"; do + if [[ "$1" == "$block"* ]]; then + echo "skip $1" + return 1 + fi + done + return 0 +} + +for dir in "${dirs[@]}"; do + if format_folder "$dir"; then + c="${dir//[^\/]}" + echo "formatting $dir ..." + depth=() + if [ "${#c}" == "1" ]; then + depth+=(-maxdepth 1) + fi + find "$dir" "${depth[@]}" -type f \( -name '*.[ch]' -o -name '*.cc' \) -exec clang-format -sort-includes=false -i {} \+ + fi +done + +TMPFILE=$(mktemp /tmp/$(basename $0).XXXXXX) +trap 'rm -f $TMPFILE' exit +if [[ -d "$top/.hg" ]]; then + hg diff --git "$top" | tee $TMPFILE +else + git -C "$top" diff | tee $TMPFILE +fi +[[ ! -s $TMPFILE ]] diff --git a/security/nss/automation/ossfuzz/build.sh b/security/nss/automation/ossfuzz/build.sh new file mode 100755 index 0000000000..e967ea8618 --- /dev/null +++ b/security/nss/automation/ossfuzz/build.sh @@ -0,0 +1,57 @@ +#!/bin/bash -eu +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +################################################################################ + +# List of targets disabled for oss-fuzz. +declare -A disabled=([pkcs8]=1) + +# List of targets we want to fuzz in TLS and non-TLS mode. +declare -A tls_targets=([tls-client]=1 [tls-server]=1 [dtls-client]=1 [dtls-server]=1) + +# Helper function that copies a fuzzer binary and its seed corpus. +copy_fuzzer() +{ + local fuzzer=$1 + local name=$2 + + # Copy the binary. + cp ../dist/Debug/bin/$fuzzer $OUT/$name + + # Zip and copy the corpus, if any. + if [ -d "$SRC/nss-corpus/$name" ]; then + zip $OUT/${name}_seed_corpus.zip $SRC/nss-corpus/$name/* + else + zip $OUT/${name}_seed_corpus.zip $SRC/nss-corpus/*/* + fi +} + +# Copy libFuzzer options +cp fuzz/options/*.options $OUT/ + +# Build the library (non-TLS fuzzing mode). +CXX="$CXX -stdlib=libc++" LDFLAGS="$CFLAGS" \ + ./build.sh -c -v --fuzz=oss --fuzz --disable-tests + +# Copy fuzzing targets. +for fuzzer in $(find ../dist/Debug/bin -name "nssfuzz-*" -printf "%f\n"); do + name=${fuzzer:8} + if [ -z "${disabled[$name]:-}" ]; then + [ -n "${tls_targets[$name]:-}" ] && name="${name}-no_fuzzer_mode" + copy_fuzzer $fuzzer $name + fi +done + +# Build the library again (TLS fuzzing mode). +CXX="$CXX -stdlib=libc++" LDFLAGS="$CFLAGS" \ + ./build.sh -c -v --fuzz=oss --fuzz=tls --disable-tests + +# Copy dual mode targets in TLS mode. +for name in "${!tls_targets[@]}"; do + if [ -z "${disabled[$name]:-}" ]; then + copy_fuzzer nssfuzz-$name $name + fi +done diff --git a/security/nss/automation/release/nspr-version.txt b/security/nss/automation/release/nspr-version.txt new file mode 100644 index 0000000000..9b2fe29d53 --- /dev/null +++ b/security/nss/automation/release/nspr-version.txt @@ -0,0 +1,10 @@ +4.35 + +# The first line of this file must contain the human readable NSPR +# version number, which is the minimum required version of NSPR +# that is supported by this version of NSS. +# +# This information is used by release automation, +# when creating an NSS source archive. +# +# All other lines in this file are ignored. diff --git a/security/nss/automation/release/nss-release-helper.py b/security/nss/automation/release/nss-release-helper.py new file mode 100755 index 0000000000..9e6ab9868b --- /dev/null +++ b/security/nss/automation/release/nss-release-helper.py @@ -0,0 +1,375 @@ +#!/usr/bin/python +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import os +import sys +import shutil +import re +import tempfile +from optparse import OptionParser +from subprocess import check_call +from subprocess import check_output + +nssutil_h = "lib/util/nssutil.h" +softkver_h = "lib/softoken/softkver.h" +nss_h = "lib/nss/nss.h" +nssckbi_h = "lib/ckfw/builtins/nssckbi.h" +abi_base_version_file = "automation/abi-check/previous-nss-release" + +abi_report_files = ['automation/abi-check/expected-report-libfreebl3.so.txt', + 'automation/abi-check/expected-report-libfreeblpriv3.so.txt', + 'automation/abi-check/expected-report-libnspr4.so.txt', + 'automation/abi-check/expected-report-libnss3.so.txt', + 'automation/abi-check/expected-report-libnssckbi.so.txt', + 'automation/abi-check/expected-report-libnssdbm3.so.txt', + 'automation/abi-check/expected-report-libnsssysinit.so.txt', + 'automation/abi-check/expected-report-libnssutil3.so.txt', + 'automation/abi-check/expected-report-libplc4.so.txt', + 'automation/abi-check/expected-report-libplds4.so.txt', + 'automation/abi-check/expected-report-libsmime3.so.txt', + 'automation/abi-check/expected-report-libsoftokn3.so.txt', + 'automation/abi-check/expected-report-libssl3.so.txt'] + + +def check_call_noisy(cmd, *args, **kwargs): + print("Executing command: {}".format(cmd)) + check_call(cmd, *args, **kwargs) + + +def exit_with_failure(what): + print("failure: {}".format(what)) + sys.exit(2) + + +def check_files_exist(): + if (not os.path.exists(nssutil_h) or not os.path.exists(softkver_h) + or not os.path.exists(nss_h) or not os.path.exists(nssckbi_h)): + exit_with_failure("cannot find expected header files, must run from inside NSS hg directory") + + +class Replacement(): + def __init__(self, regex="", repl=""): + self.regex = regex + self.repl = repl + self.matcher = re.compile(self.regex) + + def replace(self, line): + return self.matcher.sub(self.repl, line) + + +def inplace_replace(replacements=[], filename=""): + for r in replacements: + if not isinstance(r, Replacement): + raise TypeError("Expecting a list of Replacement objects") + + with tempfile.NamedTemporaryFile(mode="w", delete=False) as tmp_file: + with open(filename) as in_file: + for line in in_file: + for r in replacements: + line = r.replace(line) + tmp_file.write(line) + tmp_file.flush() + + shutil.copystat(filename, tmp_file.name) + shutil.move(tmp_file.name, filename) + + +def toggle_beta_status(is_beta): + check_files_exist() + if (is_beta): + print("adding Beta status to version numbers") + inplace_replace(filename=nssutil_h, replacements=[ + Replacement(regex=r'^(#define *NSSUTIL_VERSION *\"[0-9.]+)\" *$', + repl=r'\g<1> Beta"'), + Replacement(regex=r'^(#define *NSSUTIL_BETA *)PR_FALSE *$', + repl=r'\g<1>PR_TRUE')]) + inplace_replace(filename=softkver_h, replacements=[ + Replacement(regex=r'^(#define *SOFTOKEN_VERSION *\"[0-9.]+\" *SOFTOKEN_ECC_STRING) *$', + repl=r'\g<1> " Beta"'), + Replacement(regex=r'^(#define *SOFTOKEN_BETA *)PR_FALSE *$', + repl=r'\g<1>PR_TRUE')]) + inplace_replace(filename=nss_h, replacements=[ + Replacement(regex=r'^(#define *NSS_VERSION *\"[0-9.]+\" *_NSS_CUSTOMIZED) *$', + repl=r'\g<1> " Beta"'), + Replacement(regex=r'^(#define *NSS_BETA *)PR_FALSE *$', + repl=r'\g<1>PR_TRUE')]) + else: + print("removing Beta status from version numbers") + inplace_replace(filename=nssutil_h, replacements=[ + Replacement(regex=r'^(#define *NSSUTIL_VERSION *\"[0-9.]+) *Beta\" *$', + repl=r'\g<1>"'), + Replacement(regex=r'^(#define *NSSUTIL_BETA *)PR_TRUE *$', + repl=r'\g<1>PR_FALSE')]) + inplace_replace(filename=softkver_h, replacements=[ + Replacement(regex=r'^(#define *SOFTOKEN_VERSION *\"[0-9.]+\" *SOFTOKEN_ECC_STRING) *\" *Beta\" *$', + repl=r'\g<1>'), + Replacement(regex=r'^(#define *SOFTOKEN_BETA *)PR_TRUE *$', + repl=r'\g<1>PR_FALSE')]) + inplace_replace(filename=nss_h, replacements=[ + Replacement(regex=r'^(#define *NSS_VERSION *\"[0-9.]+\" *_NSS_CUSTOMIZED) *\" *Beta\" *$', + repl=r'\g<1>'), + Replacement(regex=r'^(#define *NSS_BETA *)PR_TRUE *$', + repl=r'\g<1>PR_FALSE')]) + + print("please run 'hg stat' and 'hg diff' to verify the files have been verified correctly") + + +def print_beta_versions(): + check_call_noisy(["egrep", "#define *NSSUTIL_VERSION|#define *NSSUTIL_BETA", nssutil_h]) + check_call_noisy(["egrep", "#define *SOFTOKEN_VERSION|#define *SOFTOKEN_BETA", softkver_h]) + check_call_noisy(["egrep", "#define *NSS_VERSION|#define *NSS_BETA", nss_h]) + + +def remove_beta_status(): + print("--- removing beta flags. Existing versions were:") + print_beta_versions() + toggle_beta_status(False) + print("--- finished modifications, new versions are:") + print_beta_versions() + + +def set_beta_status(): + print("--- adding beta flags. Existing versions were:") + print_beta_versions() + toggle_beta_status(True) + print("--- finished modifications, new versions are:") + print_beta_versions() + + +def print_library_versions(): + check_files_exist() + check_call_noisy(["egrep", "#define *NSSUTIL_VERSION|#define NSSUTIL_VMAJOR|#define *NSSUTIL_VMINOR|#define *NSSUTIL_VPATCH|#define *NSSUTIL_VBUILD|#define *NSSUTIL_BETA", nssutil_h]) + check_call_noisy(["egrep", "#define *SOFTOKEN_VERSION|#define SOFTOKEN_VMAJOR|#define *SOFTOKEN_VMINOR|#define *SOFTOKEN_VPATCH|#define *SOFTOKEN_VBUILD|#define *SOFTOKEN_BETA", softkver_h]) + check_call_noisy(["egrep", "#define *NSS_VERSION|#define NSS_VMAJOR|#define *NSS_VMINOR|#define *NSS_VPATCH|#define *NSS_VBUILD|#define *NSS_BETA", nss_h]) + + +def print_root_ca_version(): + check_files_exist() + check_call_noisy(["grep", "define *NSS_BUILTINS_LIBRARY_VERSION", nssckbi_h]) + + +def ensure_arguments_after_action(how_many, usage): + if (len(sys.argv) != (2 + how_many)): + exit_with_failure("incorrect number of arguments, expected parameters are:\n" + usage) + + +def set_major_versions(major): + for name, file in [["NSSUTIL_VMAJOR", nssutil_h], + ["SOFTOKEN_VMAJOR", softkver_h], + ["NSS_VMAJOR", nss_h]]: + inplace_replace(filename=file, replacements=[ + Replacement(regex=r'^(#define *{} ?).*$'.format(name), + repl=r'\g<1>{}'.format(major))]) + + +def set_minor_versions(minor): + for name, file in [["NSSUTIL_VMINOR", nssutil_h], + ["SOFTOKEN_VMINOR", softkver_h], + ["NSS_VMINOR", nss_h]]: + inplace_replace(filename=file, replacements=[ + Replacement(regex=r'^(#define *{} ?).*$'.format(name), + repl=r'\g<1>{}'.format(minor))]) + + +def set_patch_versions(patch): + for name, file in [["NSSUTIL_VPATCH", nssutil_h], + ["SOFTOKEN_VPATCH", softkver_h], + ["NSS_VPATCH", nss_h]]: + inplace_replace(filename=file, replacements=[ + Replacement(regex=r'^(#define *{} ?).*$'.format(name), + repl=r'\g<1>{}'.format(patch))]) + + +def set_build_versions(build): + for name, file in [["NSSUTIL_VBUILD", nssutil_h], + ["SOFTOKEN_VBUILD", softkver_h], + ["NSS_VBUILD", nss_h]]: + inplace_replace(filename=file, replacements=[ + Replacement(regex=r'^(#define *{} ?).*$'.format(name), + repl=r'\g<1>{}'.format(build))]) + + +def set_full_lib_versions(version): + for name, file in [["NSSUTIL_VERSION", nssutil_h], + ["SOFTOKEN_VERSION", softkver_h], + ["NSS_VERSION", nss_h]]: + inplace_replace(filename=file, replacements=[ + Replacement(regex=r'^(#define *{} *\")([0-9.]+)(.*)$'.format(name), + repl=r'\g<1>{}\g<3>'.format(version))]) + + +def set_root_ca_version(): + ensure_arguments_after_action(2, "major_version minor_version") + major = args[1].strip() + minor = args[2].strip() + version = major + '.' + minor + + inplace_replace(filename=nssckbi_h, replacements=[ + Replacement(regex=r'^(#define *NSS_BUILTINS_LIBRARY_VERSION *\").*$', + repl=r'\g<1>{}"'.format(version)), + Replacement(regex=r'^(#define *NSS_BUILTINS_LIBRARY_VERSION_MAJOR ?).*$', + repl=r'\g<1>{}'.format(major)), + Replacement(regex=r'^(#define *NSS_BUILTINS_LIBRARY_VERSION_MINOR ?).*$', + repl=r'\g<1>{}'.format(minor))]) + + +def set_all_lib_versions(version, major, minor, patch, build): + grep_major = check_output(['grep', 'define.*NSS_VMAJOR', nss_h]) + grep_minor = check_output(['grep', 'define.*NSS_VMINOR', nss_h]) + + old_major = int(grep_major.split()[2]) + old_minor = int(grep_minor.split()[2]) + + new_major = int(major) + new_minor = int(minor) + + if (old_major < new_major or (old_major == new_major and old_minor < new_minor)): + print("You're increasing the minor (or major) version:") + print("- erasing ABI comparison expectations") + new_branch = "NSS_" + str(old_major) + "_" + str(old_minor) + "_BRANCH" + print("- setting reference branch to the branch of the previous version: " + new_branch) + with open(abi_base_version_file, "w") as abi_base: + abi_base.write("%s\n" % new_branch) + for report_file in abi_report_files: + with open(report_file, "w") as report_file_handle: + report_file_handle.truncate() + + set_full_lib_versions(version) + set_major_versions(major) + set_minor_versions(minor) + set_patch_versions(patch) + set_build_versions(build) + + +def set_version_to_minor_release(): + ensure_arguments_after_action(2, "major_version minor_version") + major = args[1].strip() + minor = args[2].strip() + version = major + '.' + minor + patch = "0" + build = "0" + set_all_lib_versions(version, major, minor, patch, build) + + +def set_version_to_patch_release(): + ensure_arguments_after_action(3, "major_version minor_version patch_release") + major = args[1].strip() + minor = args[2].strip() + patch = args[3].strip() + version = major + '.' + minor + '.' + patch + build = "0" + set_all_lib_versions(version, major, minor, patch, build) + + +def set_release_candidate_number(): + ensure_arguments_after_action(1, "release_candidate_number") + build = args[1].strip() + set_build_versions(build) + + +def set_4_digit_release_number(): + ensure_arguments_after_action(4, "major_version minor_version patch_release 4th_digit_release_number") + major = args[1].strip() + minor = args[2].strip() + patch = args[3].strip() + build = args[4].strip() + version = major + '.' + minor + '.' + patch + '.' + build + set_all_lib_versions(version, major, minor, patch, build) + + +def create_nss_release_archive(): + ensure_arguments_after_action(3, "nss_release_version nss_hg_release_tag path_to_stage_directory") + nssrel = args[1].strip() # e.g. 3.19.3 + nssreltag = args[2].strip() # e.g. NSS_3_19_3_RTM + stagedir = args[3].strip() # e.g. ../stage + + with open('automation/release/nspr-version.txt') as nspr_version_file: + nsprrel = next(nspr_version_file).strip() + + nspr_tar = "nspr-" + nsprrel + ".tar.gz" + nsprtar_with_path = stagedir + "/v" + nsprrel + "/src/" + nspr_tar + if (not os.path.exists(nsprtar_with_path)): + exit_with_failure("cannot find nspr archive at expected location " + nsprtar_with_path) + + nss_stagedir = stagedir + "/" + nssreltag + "/src" + if (os.path.exists(nss_stagedir)): + exit_with_failure("nss stage directory already exists: " + nss_stagedir) + + nss_tar = "nss-" + nssrel + ".tar.gz" + + check_call_noisy(["mkdir", "-p", nss_stagedir]) + check_call_noisy(["hg", "archive", "-r", nssreltag, "--prefix=nss-" + nssrel + "/nss", + stagedir + "/" + nssreltag + "/src/" + nss_tar, "-X", ".hgtags"]) + check_call_noisy(["tar", "-xz", "-C", nss_stagedir, "-f", nsprtar_with_path]) + print("changing to directory " + nss_stagedir) + os.chdir(nss_stagedir) + check_call_noisy(["tar", "-xz", "-f", nss_tar]) + check_call_noisy(["mv", "-i", "nspr-" + nsprrel + "/nspr", "nss-" + nssrel + "/"]) + check_call_noisy(["rmdir", "nspr-" + nsprrel]) + + nss_nspr_tar = "nss-" + nssrel + "-with-nspr-" + nsprrel + ".tar.gz" + + check_call_noisy(["tar", "-cz", "--remove-files", "-f", nss_nspr_tar, "nss-" + nssrel]) + check_call("sha1sum " + nss_tar + " " + nss_nspr_tar + " > SHA1SUMS", shell=True) + check_call("sha256sum " + nss_tar + " " + nss_nspr_tar + " > SHA256SUMS", shell=True) + print("created directory " + nss_stagedir + " with files:") + check_call_noisy(["ls", "-l"]) + + +o = OptionParser(usage="client.py [options] " + " | ".join([ + "remove_beta", "set_beta", "print_library_versions", "print_root_ca_version", + "set_root_ca_version", "set_version_to_minor_release", + "set_version_to_patch_release", "set_release_candidate_number", + "set_4_digit_release_number", "create_nss_release_archive"])) + +try: + options, args = o.parse_args() + action = args[0] +except IndexError: + o.print_help() + sys.exit(2) + +if action in ('remove_beta'): + remove_beta_status() + +elif action in ('set_beta'): + set_beta_status() + +elif action in ('print_library_versions'): + print_library_versions() + +elif action in ('print_root_ca_version'): + print_root_ca_version() + +elif action in ('set_root_ca_version'): + set_root_ca_version() + +# x.y version number - 2 parameters +elif action in ('set_version_to_minor_release'): + set_version_to_minor_release() + +# x.y.z version number - 3 parameters +elif action in ('set_version_to_patch_release'): + set_version_to_patch_release() + +# change the release candidate number, usually increased by one, +# usually if previous release candiate had a bug +# 1 parameter +elif action in ('set_release_candidate_number'): + set_release_candidate_number() + +# use the build/release candiate number in the identifying version number +# 4 parameters +elif action in ('set_4_digit_release_number'): + set_4_digit_release_number() + +elif action in ('create_nss_release_archive'): + create_nss_release_archive() + +else: + o.print_help() + sys.exit(2) + +sys.exit(0) diff --git a/security/nss/automation/taskcluster/docker-aarch64/Dockerfile b/security/nss/automation/taskcluster/docker-aarch64/Dockerfile new file mode 100644 index 0000000000..aca173cd00 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-aarch64/Dockerfile @@ -0,0 +1,29 @@ +FROM franziskus/xenial:aarch64 +MAINTAINER Franziskus Kiefer <franziskuskiefer@gmail.com> + +RUN useradd -d /home/worker -s /bin/bash -m worker +WORKDIR /home/worker + +# Add build and test scripts. +ADD bin /home/worker/bin +RUN chmod +x /home/worker/bin/* + +# Install dependencies. +ADD setup.sh /tmp/setup.sh +RUN bash /tmp/setup.sh + +# Change user. +# USER worker # See bug 1347473. + +# Env variables. +ENV HOME /home/worker +ENV SHELL /bin/bash +ENV USER worker +ENV LOGNAME worker +ENV LANG en_US.UTF-8 +ENV LC_ALL en_US.UTF-8 +ENV HOST localhost +ENV DOMSUF localdomain + +# Set a default command for debugging. +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/docker-aarch64/bin/checkout.sh b/security/nss/automation/taskcluster/docker-aarch64/bin/checkout.sh new file mode 100755 index 0000000000..9167f6bda6 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-aarch64/bin/checkout.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -v -e -x + +if [ $(id -u) = 0 ]; then + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/docker-aarch64/setup.sh b/security/nss/automation/taskcluster/docker-aarch64/setup.sh new file mode 100755 index 0000000000..b76514ad5a --- /dev/null +++ b/security/nss/automation/taskcluster/docker-aarch64/setup.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +set -v -e -x + +export DEBIAN_FRONTEND=noninteractive + +apt-get -y update +apt-get -y install software-properties-common + +# Add more repos +add-apt-repository "deb http://ports.ubuntu.com/ xenial main restricted universe multiverse" +add-apt-repository "deb http://ports.ubuntu.com/ xenial-security main restricted universe multiverse" +add-apt-repository "deb http://ports.ubuntu.com/ xenial-updates main restricted universe multiverse" +add-apt-repository "deb http://ports.ubuntu.com/ xenial-backports main restricted universe multiverse" + +# Update. +apt-get -y update +apt-get -y dist-upgrade + +apt_packages=() +apt_packages+=('build-essential') +apt_packages+=('ca-certificates') +apt_packages+=('curl') +apt_packages+=('libxml2-utils') +apt_packages+=('zlib1g-dev') +apt_packages+=('ninja-build') +apt_packages+=('gyp') +apt_packages+=('mercurial') +apt_packages+=('locales') + +# Install packages. +apt-get install -y --no-install-recommends ${apt_packages[@]} + +locale-gen en_US.UTF-8 +dpkg-reconfigure locales + +# Cleanup. +rm -rf ~/.ccache ~/.cache +apt-get autoremove -y +apt-get clean +apt-get autoclean +rm $0 diff --git a/security/nss/automation/taskcluster/docker-arm/Dockerfile b/security/nss/automation/taskcluster/docker-arm/Dockerfile new file mode 100644 index 0000000000..5b8cfca208 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-arm/Dockerfile @@ -0,0 +1,26 @@ +FROM armv7/armhf-ubuntu:16.04 +MAINTAINER Franziskus Kiefer <franziskuskiefer@gmail.com> + +RUN useradd -d /home/worker -s /bin/bash -m worker +WORKDIR /home/worker + +# Add build and test scripts. +ADD bin /home/worker/bin +RUN chmod +x /home/worker/bin/* + +# Install dependencies. +ADD setup.sh /tmp/setup.sh +RUN bash /tmp/setup.sh + +# Env variables. +ENV HOME /home/worker +ENV SHELL /bin/bash +ENV USER worker +ENV LOGNAME worker +ENV LANG en_US.UTF-8 +ENV LC_ALL en_US.UTF-8 +ENV HOST localhost +ENV DOMSUF localdomain + +# Set a default command for debugging. +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/docker-arm/bin/checkout.sh b/security/nss/automation/taskcluster/docker-arm/bin/checkout.sh new file mode 100755 index 0000000000..4b891289dc --- /dev/null +++ b/security/nss/automation/taskcluster/docker-arm/bin/checkout.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -v -e -x + +if [ $(id -u) = 0 ]; then + # set up fake uname + if [ ! -f /bin/uname-real ]; then + mv /bin/uname /bin/uname-real + ln -s /home/worker/bin/uname.sh /bin/uname + fi + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/docker-arm/bin/uname.sh b/security/nss/automation/taskcluster/docker-arm/bin/uname.sh new file mode 100755 index 0000000000..61ad13c343 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-arm/bin/uname.sh @@ -0,0 +1,18 @@ +#!/bin/bash +args=`getopt rmvs $*` +set -- $args +for i +do + if [ "$i" == "-v" ]; then + /bin/uname-real -v + fi + if [ "$i" == "-r" ]; then + echo "4.4.16-v7+" + fi + if [ "$i" == "-m" ]; then + echo "armv7l" + fi + if [ "$i" == "-s" ]; then + echo "Linux" + fi +done
\ No newline at end of file diff --git a/security/nss/automation/taskcluster/docker-arm/setup.sh b/security/nss/automation/taskcluster/docker-arm/setup.sh new file mode 100755 index 0000000000..78c63925bc --- /dev/null +++ b/security/nss/automation/taskcluster/docker-arm/setup.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +set -v -e -x + +export DEBIAN_FRONTEND=noninteractive + +# Update. +apt-get -y update +apt-get -y dist-upgrade + +apt_packages=() +apt_packages+=('build-essential') +apt_packages+=('ca-certificates') +apt_packages+=('curl') +apt_packages+=('locales') +apt_packages+=('python-dev') +apt_packages+=('python-pip') +apt_packages+=('python-setuptools') +apt_packages+=('zlib1g-dev') + +# Install packages. +apt-get install -y --no-install-recommends ${apt_packages[@]} + +# Latest Mercurial. +pip install --upgrade pip +pip install Mercurial + +locale-gen en_US.UTF-8 +dpkg-reconfigure locales + +# Cleanup. +rm -rf ~/.ccache ~/.cache +apt-get autoremove -y +apt-get clean +apt-get autoclean +rm $0 diff --git a/security/nss/automation/taskcluster/docker-builds/Dockerfile b/security/nss/automation/taskcluster/docker-builds/Dockerfile new file mode 100644 index 0000000000..6ea2543764 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-builds/Dockerfile @@ -0,0 +1,75 @@ +# Dockerfile for building extra builds. This includes more tools than the +# default image, so it's a fair bit bigger. Only use this for builds where +# the smaller docker image is missing something. These builds will run on +# the leaner configuration. +FROM ubuntu:18.04 +LABEL maintainer="Martin Thomson <martin.thomson@gmail.com>" + +RUN dpkg --add-architecture i386 +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + clang-4.0 \ + clang-10 \ + clang \ + cmake \ + curl \ + g++-4.8-multilib \ + g++-5-multilib \ + g++-multilib \ + git \ + gyp \ + libelf-dev \ + libdw-dev \ + libssl-dev \ + libssl-dev:i386 \ + libxml2-utils \ + lib32z1-dev \ + linux-libc-dev:i386 \ + llvm-dev \ + locales \ + mercurial \ + ninja-build \ + pkg-config \ + valgrind \ + zlib1g-dev \ + clang-format-10 \ + sqlite3 \ + libabigail-dev \ + abigail-tools \ + software-properties-common \ + && add-apt-repository ppa:ubuntu-toolchain-r/test -y \ + && apt-get update \ + && apt-get install --no-install-recommends -y \ + gcc-11-multilib \ + g++-11-multilib \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get autoremove -y && apt-get clean -y + +RUN update-alternatives --install /usr/bin/clang-format \ + clang-format $(which clang-format-10) 10 + +ENV SHELL /bin/bash +ENV USER worker +ENV LOGNAME $USER +ENV HOME /home/$USER +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +ENV HOST localhost +ENV DOMSUF localdomain + +RUN locale-gen $LANG \ + && DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales + +RUN useradd -d $HOME -s $SHELL -m $USER +WORKDIR $HOME + +# Add build and test scripts. +ADD bin $HOME/bin +RUN chmod +x $HOME/bin/* + +USER $USER + +# Set a default command for debugging. +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/docker-builds/bin/checkout.sh b/security/nss/automation/taskcluster/docker-builds/bin/checkout.sh new file mode 100644 index 0000000000..9167f6bda6 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-builds/bin/checkout.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -v -e -x + +if [ $(id -u) = 0 ]; then + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/docker-clang-format/Dockerfile b/security/nss/automation/taskcluster/docker-clang-format/Dockerfile new file mode 100644 index 0000000000..8ef4bb0754 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-clang-format/Dockerfile @@ -0,0 +1,38 @@ +# Minimal image with clang-format 10 +FROM ubuntu:18.04 +LABEL maintainer="Martin Thomson <martin.thomson@gmail.com>" + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + clang-format-10 \ + locales \ + mercurial \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get autoremove -y && apt-get clean -y + +RUN update-alternatives --install /usr/bin/clang-format \ + clang-format $(which clang-format-10) 10 + +ENV SHELL /bin/bash +ENV USER worker +ENV LOGNAME $USER +ENV HOME /home/$USER +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +ENV HOST localhost +ENV DOMSUF localdomain + +RUN locale-gen $LANG \ + && DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales + +RUN useradd -d $HOME -s $SHELL -m $USER +WORKDIR $HOME + +ADD bin $HOME/bin +RUN chmod +x $HOME/bin/* + +USER $USER + +# Set a default command for debugging. +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/docker-clang-format/bin/checkout.sh b/security/nss/automation/taskcluster/docker-clang-format/bin/checkout.sh new file mode 100644 index 0000000000..9167f6bda6 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-clang-format/bin/checkout.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -v -e -x + +if [ $(id -u) = 0 ]; then + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/docker-decision/Dockerfile b/security/nss/automation/taskcluster/docker-decision/Dockerfile new file mode 100644 index 0000000000..8ce08a8f2b --- /dev/null +++ b/security/nss/automation/taskcluster/docker-decision/Dockerfile @@ -0,0 +1,38 @@ +# Minimal image for running the decision task. +FROM ubuntu:18.04 +LABEL maintainer="Martin Thomson <martin.thomson@gmail.com>" + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + locales \ + mercurial \ + nodejs \ + npm \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get autoremove -y && apt-get clean -y + +ENV SHELL /bin/bash +ENV USER worker +ENV LOGNAME $USER +ENV HOME /home/$USER +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +ENV HOST localhost +ENV DOMSUF localdomain + +RUN locale-gen $LANG \ + && DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales + +RUN useradd -d $HOME -s $SHELL -m $USER +WORKDIR $HOME + +# Add build and test scripts. +ADD bin $HOME/bin +RUN chmod +x $HOME/bin/* + +USER $USER + +# Set a default command for debugging. +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/docker-decision/bin/checkout.sh b/security/nss/automation/taskcluster/docker-decision/bin/checkout.sh new file mode 100644 index 0000000000..0cdd2ac405 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-decision/bin/checkout.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/docker-fuzz/Dockerfile b/security/nss/automation/taskcluster/docker-fuzz/Dockerfile new file mode 100644 index 0000000000..d7e7fa918d --- /dev/null +++ b/security/nss/automation/taskcluster/docker-fuzz/Dockerfile @@ -0,0 +1,61 @@ +# Dockerfile for running fuzzing tests. +# Used for ASAN. +# Note that when running this, you need to add `--cap-add SYS_PTRACE` to the +# docker invocation or ASAN won't work. +# On taskcluster for ASAN use `features: ["allowPtrace"]`. +# See https://github.com/google/sanitizers/issues/764#issuecomment-276700920 +FROM ubuntu:18.04 +LABEL maintainer="Martin Thomson <martin.thomson@gmail.com>" + +RUN dpkg --add-architecture i386 +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + clang \ + clang-tools \ + curl \ + g++-multilib \ + git \ + gyp \ + libssl-dev \ + libssl-dev:i386 \ + libxml2-utils \ + lib32z1-dev \ + linux-libc-dev:i386 \ + llvm-dev \ + locales \ + mercurial \ + ninja-build \ + pkg-config \ + python-pip \ + valgrind \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get autoremove -y && apt-get clean -y \ + && pip install requests + +ENV SHELL /bin/bash +ENV USER worker +ENV LOGNAME $USER +ENV HOME /home/$USER +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +ENV HOST localhost +ENV DOMSUF localdomain + +RUN locale-gen $LANG \ + && DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales + +RUN useradd -d $HOME -s $SHELL -m $USER +WORKDIR $HOME + +# Add build and test scripts. +ADD bin $HOME/bin +RUN chmod +x $HOME/bin/* + +# Change user. +USER $USER + +# Set a default command for debugging. +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/docker-fuzz/bin/checkout.sh b/security/nss/automation/taskcluster/docker-fuzz/bin/checkout.sh new file mode 100644 index 0000000000..9167f6bda6 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-fuzz/bin/checkout.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -v -e -x + +if [ $(id -u) = 0 ]; then + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/docker-fuzz32/Dockerfile b/security/nss/automation/taskcluster/docker-fuzz32/Dockerfile new file mode 100644 index 0000000000..e80b94d5f9 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-fuzz32/Dockerfile @@ -0,0 +1,75 @@ +# Dockerfile for running fuzzing tests on linux32. +# +# This is a temporary workaround for bugs in clang that make it incompatible +# with Ubuntu 18.04 (see bug 1488148). This image can be removed once a new +# release of LLVM includes the necessary fixes. + +FROM ubuntu:16.04 +LABEL maintainer="Martin Thomson <martin.thomson@gmail.com>" + +RUN dpkg --add-architecture i386 +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + apt-transport-https \ + apt-utils \ + build-essential \ + ca-certificates \ + curl \ + g++-multilib \ + git \ + gyp \ + libssl-dev \ + libssl-dev:i386 \ + libxml2-utils \ + lib32z1-dev \ + linux-libc-dev:i386 \ + locales \ + mercurial \ + ninja-build \ + pkg-config \ + software-properties-common \ + valgrind \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get autoremove -y && apt-get clean -y + +# Install clang and tools from the LLVM PPA. +RUN curl -sf https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - \ + && apt-add-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-6.0 main" \ + && apt-get update \ + && apt-get install -y --no-install-recommends \ + clang-6.0 \ + clang-tools-6.0 \ + llvm-6.0-dev \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get autoremove -y && apt-get clean -y + +# Alias all the clang commands. +RUN for i in $(dpkg -L clang-6.0 clang-tools-6.0 | grep '^/usr/bin/' | xargs -i basename {} -6.0); do \ + update-alternatives --install "/usr/bin/$i" "$i" "/usr/bin/${i}-6.0" 10; \ + done + +ENV SHELL /bin/bash +ENV USER worker +ENV LOGNAME $USER +ENV HOME /home/$USER +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +ENV HOST localhost +ENV DOMSUF localdomain + +RUN locale-gen $LANG \ + && DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales + +RUN useradd -d $HOME -s $SHELL -m $USER +WORKDIR $HOME + +# Add build and test scripts. +ADD bin $HOME/bin +RUN chmod +x $HOME/bin/* + +# Change user. +USER $USER + +# Set a default command for debugging. +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/docker-fuzz32/bin/checkout.sh b/security/nss/automation/taskcluster/docker-fuzz32/bin/checkout.sh new file mode 100644 index 0000000000..9167f6bda6 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-fuzz32/bin/checkout.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -v -e -x + +if [ $(id -u) = 0 ]; then + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/docker-gcc-4.4/Dockerfile b/security/nss/automation/taskcluster/docker-gcc-4.4/Dockerfile new file mode 100644 index 0000000000..866e8066c3 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-gcc-4.4/Dockerfile @@ -0,0 +1,41 @@ +FROM ubuntu:14.04 +LABEL maintainer="Martin Thomson <martin.thomson@gmail.com>" + +RUN dpkg --add-architecture i386 +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + g++-4.4 \ + gcc-4.4 \ + locales \ + make \ + patch \ + mercurial \ + sqlite3 \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get autoremove -y && apt-get clean -y + +ENV SHELL /bin/bash +ENV USER worker +ENV LOGNAME $USER +ENV HOME /home/$USER +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +ENV HOST localhost +ENV DOMSUF localdomain + +RUN locale-gen $LANG \ + && DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales + +RUN useradd -d $HOME -s $SHELL -m $USER +WORKDIR $HOME + +# Add build and test scripts. +ADD bin $HOME/bin +RUN chmod +x $HOME/bin/* + +USER $USER + +# Set a default command for debugging. +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/docker-gcc-4.4/bin/checkout.sh b/security/nss/automation/taskcluster/docker-gcc-4.4/bin/checkout.sh new file mode 100644 index 0000000000..9167f6bda6 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-gcc-4.4/bin/checkout.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -v -e -x + +if [ $(id -u) = 0 ]; then + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/docker-interop/Dockerfile b/security/nss/automation/taskcluster/docker-interop/Dockerfile new file mode 100644 index 0000000000..ff5f33ce86 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-interop/Dockerfile @@ -0,0 +1,57 @@ +# Dockerfile for running interop tests. +# This includes Rust, golang, and nodejs. +FROM ubuntu:20.04 +LABEL maintainer="Martin Thomson <martin.thomson@gmail.com>" + +RUN dpkg --add-architecture i386 +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive \ + apt-get install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + clang \ + cmake \ + curl \ + g++-multilib \ + git \ + golang \ + gyp \ + libxml2-utils \ + lib32z1-dev \ + linux-libc-dev:i386 \ + llvm-dev \ + locales \ + mercurial \ + ninja-build \ + npm \ + pkg-config \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get autoremove -y && apt-get clean -y + +ENV SHELL /bin/bash +ENV USER worker +ENV LOGNAME $USER +ENV HOME /home/$USER +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +ENV HOST localhost +ENV DOMSUF localdomain + +RUN locale-gen $LANG \ + && DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales + +RUN useradd -d $HOME -s $SHELL -m $USER +WORKDIR $HOME + +# Add build and test scripts. +ADD bin $HOME/bin +RUN chmod +x $HOME/bin/* + +USER $USER + +# Install Rust stable as $USER. +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y + +# Set a default command for debugging. +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/docker-interop/bin/checkout.sh b/security/nss/automation/taskcluster/docker-interop/bin/checkout.sh new file mode 100644 index 0000000000..9167f6bda6 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-interop/bin/checkout.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -v -e -x + +if [ $(id -u) = 0 ]; then + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/docker/Dockerfile b/security/nss/automation/taskcluster/docker/Dockerfile new file mode 100644 index 0000000000..859b5bd111 --- /dev/null +++ b/security/nss/automation/taskcluster/docker/Dockerfile @@ -0,0 +1,50 @@ +# Lean image for running the bulk of the NSS CI tests on taskcluster. +FROM ubuntu:18.04 +LABEL maintainer="Martin Thomson <martin.thomson@gmail.com>" + +RUN dpkg --add-architecture i386 +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + clang \ + curl \ + g++-multilib \ + git \ + gyp \ + libxml2-utils \ + lib32z1-dev \ + linux-libc-dev:i386 \ + llvm-dev \ + locales \ + mercurial \ + ninja-build \ + pkg-config \ + sqlite3 \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get autoremove -y && apt-get clean -y + +ENV SHELL /bin/bash +ENV USER worker +ENV LOGNAME $USER +ENV HOME /home/$USER +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +ENV HOST localhost +ENV DOMSUF localdomain + +RUN locale-gen $LANG \ + && DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales + +RUN useradd -d $HOME -s $SHELL -m $USER +WORKDIR $HOME + +# Add build and test scripts. +ADD bin $HOME/bin +RUN chmod +x $HOME/bin/* + +USER $USER + +# Set a default command for debugging. +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/docker/bin/checkout.sh b/security/nss/automation/taskcluster/docker/bin/checkout.sh new file mode 100644 index 0000000000..9167f6bda6 --- /dev/null +++ b/security/nss/automation/taskcluster/docker/bin/checkout.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -v -e -x + +if [ $(id -u) = 0 ]; then + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/graph/npm-shrinkwrap.json b/security/nss/automation/taskcluster/graph/npm-shrinkwrap.json new file mode 100644 index 0000000000..70718432bc --- /dev/null +++ b/security/nss/automation/taskcluster/graph/npm-shrinkwrap.json @@ -0,0 +1,2963 @@ +{ + "name": "decision-task", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", + "integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "anymatch": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz", + "integrity": "sha1-o+Uvo5FoyCX/V7AkgSbOWo/5VQc=", + "optional": true, + "requires": { + "arrify": "1.0.1", + "micromatch": "2.3.11" + } + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "requires": { + "sprintf-js": "1.0.3" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "optional": true, + "requires": { + "arr-flatten": "1.0.1" + } + }, + "arr-flatten": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.1.tgz", + "integrity": "sha1-5f/lTUXhnzLyFukeuZyM6JK7YEs=", + "optional": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "optional": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "optional": true + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" + }, + "async": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.1.1.tgz", + "integrity": "sha1-4RttEAQ/IlTvthohFj2EDM3bjSg=", + "requires": { + "lodash": "4.16.4" + } + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "optional": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" + }, + "aws4": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.5.0.tgz", + "integrity": "sha1-Cin/t5wxyecS7rCH6OemS0pW11U=" + }, + "b64": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/b64/-/b64-4.1.2.tgz", + "integrity": "sha512-+GUspBxlH3CJaxMUGUE1EBoWM6RKgWiYwUDal0qdf8m3ArnXNN1KzKVo5HOnE/FSq4HHyWf3TlHLsZI8PKQgrQ==", + "requires": { + "hoek": "6.1.3" + }, + "dependencies": { + "hoek": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz", + "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==" + } + } + }, + "babel-cli": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.16.0.tgz", + "integrity": "sha1-Tg0c9ARC73gzD3/viOs6ChsWvTc=", + "requires": { + "babel-core": "6.17.0", + "babel-polyfill": "6.16.0", + "babel-register": "6.16.3", + "babel-runtime": "6.11.6", + "bin-version-check": "2.1.0", + "chalk": "1.1.1", + "chokidar": "1.6.0", + "commander": "2.9.0", + "convert-source-map": "1.3.0", + "fs-readdir-recursive": "0.1.2", + "glob": "5.0.15", + "lodash": "4.16.4", + "log-symbols": "1.0.2", + "output-file-sync": "1.1.2", + "path-exists": "1.0.0", + "path-is-absolute": "1.0.1", + "request": "2.75.0", + "slash": "1.0.0", + "source-map": "0.5.6", + "v8flags": "2.0.11" + } + }, + "babel-code-frame": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.16.0.tgz", + "integrity": "sha1-+Q5g2ghikJ084JhzO105h8l8uN4=", + "requires": { + "chalk": "1.1.1", + "esutils": "2.0.2", + "js-tokens": "2.0.0" + } + }, + "babel-compile": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/babel-compile/-/babel-compile-2.0.0.tgz", + "integrity": "sha1-JwRg2Fzah1iqXGMWWzZaa8RMmXY=", + "requires": { + "babel-core": "6.17.0", + "commander": "2.9.0", + "fs-walk": "0.0.1", + "lodash": "4.16.4", + "mkdirp": "0.5.1", + "rimraf": "2.5.4" + } + }, + "babel-core": { + "version": "6.17.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.17.0.tgz", + "integrity": "sha1-bEV2RH30eeJB5YyAfkvH2k239CU=", + "requires": { + "babel-code-frame": "6.16.0", + "babel-generator": "6.17.0", + "babel-helpers": "6.16.0", + "babel-messages": "6.8.0", + "babel-register": "6.16.3", + "babel-runtime": "6.11.6", + "babel-template": "6.16.0", + "babel-traverse": "6.16.0", + "babel-types": "6.16.0", + "babylon": "6.11.6", + "convert-source-map": "1.3.0", + "debug": "2.2.0", + "json5": "0.4.0", + "lodash": "4.16.4", + "minimatch": "3.0.3", + "path-exists": "1.0.0", + "path-is-absolute": "1.0.1", + "private": "0.1.6", + "shebang-regex": "1.0.0", + "slash": "1.0.0", + "source-map": "0.5.6" + } + }, + "babel-generator": { + "version": "6.17.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.17.0.tgz", + "integrity": "sha1-uJTjgIvu94APJVBjW/4CS2ImzzM=", + "requires": { + "babel-messages": "6.8.0", + "babel-runtime": "6.11.6", + "babel-types": "6.16.0", + "detect-indent": "3.0.1", + "jsesc": "1.3.0", + "lodash": "4.16.4", + "source-map": "0.5.6" + } + }, + "babel-helper-call-delegate": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.8.0.tgz", + "integrity": "sha1-nSg+dIZ3m2sEgYZKEbNx6lwB+mQ=", + "requires": { + "babel-helper-hoist-variables": "6.8.0", + "babel-runtime": "6.11.6", + "babel-traverse": "6.16.0", + "babel-types": "6.16.0" + } + }, + "babel-helper-define-map": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.9.0.tgz", + "integrity": "sha1-Zin5sqfljhjoN5pX0eb7spaZAvs=", + "requires": { + "babel-helper-function-name": "6.8.0", + "babel-runtime": "6.11.6", + "babel-types": "6.16.0", + "lodash": "4.16.4" + } + }, + "babel-helper-function-name": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.8.0.tgz", + "integrity": "sha1-oDNroUUmoHXN9QL8UtP+hLEvejQ=", + "requires": { + "babel-helper-get-function-arity": "6.8.0", + "babel-runtime": "6.11.6", + "babel-template": "6.16.0", + "babel-traverse": "6.16.0", + "babel-types": "6.16.0" + } + }, + "babel-helper-get-function-arity": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.8.0.tgz", + "integrity": "sha1-iCdsJL0lHN9vYbb4n3RfSGztkq8=", + "requires": { + "babel-runtime": "6.11.6", + "babel-types": "6.16.0" + } + }, + "babel-helper-hoist-variables": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.8.0.tgz", + "integrity": "sha1-iwdm3AJuqepCO8KzTmZaTac3Oq8=", + "requires": { + "babel-runtime": "6.11.6", + "babel-types": "6.16.0" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.8.0.tgz", + "integrity": "sha1-QXVijpyJ/DYXSQTycHDynThWfwY=", + "requires": { + "babel-runtime": "6.11.6", + "babel-types": "6.16.0" + } + }, + "babel-helper-regex": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.9.0.tgz", + "integrity": "sha1-x0Jl/eGA/5oWc1/uBeY8rbngsFc=", + "requires": { + "babel-runtime": "6.11.6", + "babel-types": "6.16.0", + "lodash": "4.16.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.16.2", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.16.2.tgz", + "integrity": "sha1-JDFb3oMmxgAi3AU8zoTP441yS4I=", + "requires": { + "babel-helper-function-name": "6.8.0", + "babel-runtime": "6.11.6", + "babel-template": "6.16.0", + "babel-traverse": "6.16.0", + "babel-types": "6.16.0" + } + }, + "babel-helper-replace-supers": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.16.0.tgz", + "integrity": "sha1-Icl2I8x+QwhVdT8lJ0ASJiajnms=", + "requires": { + "babel-helper-optimise-call-expression": "6.8.0", + "babel-messages": "6.8.0", + "babel-runtime": "6.11.6", + "babel-template": "6.16.0", + "babel-traverse": "6.16.0", + "babel-types": "6.16.0" + } + }, + "babel-helpers": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.16.0.tgz", + "integrity": "sha1-EJXsENmSeUYFU+Z+s+7plz04Z+M=", + "requires": { + "babel-runtime": "6.11.6", + "babel-template": "6.16.0" + } + }, + "babel-messages": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.8.0.tgz", + "integrity": "sha1-v1BHNsqWfm1l7wrbWipflHyODrk=", + "requires": { + "babel-runtime": "6.11.6" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.8.0.tgz", + "integrity": "sha1-2/Akwy7Te/2o3uHnbaAjhqjSb+c=", + "requires": { + "babel-runtime": "6.11.6" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=" + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.16.0.tgz", + "integrity": "sha1-Gew2yxSGtZ+fRorfpCzhOQjKKZk=", + "requires": { + "babel-helper-remap-async-to-generator": "6.16.2", + "babel-plugin-syntax-async-functions": "6.13.0", + "babel-runtime": "6.11.6" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.8.0.tgz", + "integrity": "sha1-W2Ovwxgb3JqMTUgbWk8/fX/vPZ0=", + "requires": { + "babel-runtime": "6.11.6" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.8.0.tgz", + "integrity": "sha1-7ZXWKcS1pxriloK5mPcNmDPrNm0=", + "requires": { + "babel-runtime": "6.11.6" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.15.0.tgz", + "integrity": "sha1-W0Q8oUK+jR22qMKuQvUZWLZrcPY=", + "requires": { + "babel-runtime": "6.11.6", + "babel-template": "6.16.0", + "babel-traverse": "6.16.0", + "babel-types": "6.16.0", + "lodash": "4.16.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.14.0.tgz", + "integrity": "sha1-h9UUnukftHWSJAn5r1srpdHjkoc=", + "requires": { + "babel-helper-define-map": "6.9.0", + "babel-helper-function-name": "6.8.0", + "babel-helper-optimise-call-expression": "6.8.0", + "babel-helper-replace-supers": "6.16.0", + "babel-messages": "6.8.0", + "babel-runtime": "6.11.6", + "babel-template": "6.16.0", + "babel-traverse": "6.16.0", + "babel-types": "6.16.0" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.8.0.tgz", + "integrity": "sha1-9RAQ/WGzvXtrYKX9/TB7t6UnmHA=", + "requires": { + "babel-helper-define-map": "6.9.0", + "babel-runtime": "6.11.6", + "babel-template": "6.16.0" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.16.0.tgz", + "integrity": "sha1-BQ/ghm9dU7NgYu4QzfW/5k+Slic=", + "requires": { + "babel-runtime": "6.11.6" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.8.0.tgz", + "integrity": "sha1-/Y9/cXH8EIzBxwwxZLnxWoHCX30=", + "requires": { + "babel-runtime": "6.11.6", + "babel-types": "6.16.0" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.8.0.tgz", + "integrity": "sha1-gu2hObpCcN2hNcPsGx8oE/pi8jw=", + "requires": { + "babel-runtime": "6.11.6" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.9.0.tgz", + "integrity": "sha1-jBNbF9vQZOW7pW7FEbqu4vyoJxk=", + "requires": { + "babel-helper-function-name": "6.8.0", + "babel-runtime": "6.11.6", + "babel-types": "6.16.0" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.8.0.tgz", + "integrity": "sha1-UKouXHlY/CqyXXTsEX4MyY8EZGg=", + "requires": { + "babel-runtime": "6.11.6" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.8.0.tgz", + "integrity": "sha1-JdlUqgvwQDH8RtKo5iMLsau95KM=", + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "6.16.0", + "babel-runtime": "6.11.6", + "babel-template": "6.16.0" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.16.0.tgz", + "integrity": "sha1-CjS0R7yIrRpwmIttGZzKbQuWyJI=", + "requires": { + "babel-plugin-transform-strict-mode": "6.11.3", + "babel-runtime": "6.11.6", + "babel-template": "6.16.0", + "babel-types": "6.16.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.14.0.tgz", + "integrity": "sha1-xRm1xz4yOI5nnJse30Gy/CPcMwM=", + "requires": { + "babel-helper-hoist-variables": "6.8.0", + "babel-runtime": "6.11.6", + "babel-template": "6.16.0" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.12.0.tgz", + "integrity": "sha1-XXNVnrSSZnde0oHEC+iKQhvTcaM=", + "requires": { + "babel-plugin-transform-es2015-modules-amd": "6.8.0", + "babel-runtime": "6.11.6", + "babel-template": "6.16.0" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.8.0.tgz", + "integrity": "sha1-G4WHQKWkQAiHwj3P9vTVbupKJMU=", + "requires": { + "babel-helper-replace-supers": "6.16.0", + "babel-runtime": "6.11.6" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.17.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.17.0.tgz", + "integrity": "sha1-4G0wzviX9GrbRzRwe74Sig1CfVg=", + "requires": { + "babel-helper-call-delegate": "6.8.0", + "babel-helper-get-function-arity": "6.8.0", + "babel-runtime": "6.11.6", + "babel-template": "6.16.0", + "babel-traverse": "6.16.0", + "babel-types": "6.16.0" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.8.0.tgz", + "integrity": "sha1-8KTF/UcWMKzzM8LZnD1ne/CVIUk=", + "requires": { + "babel-runtime": "6.11.6", + "babel-types": "6.16.0" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.8.0.tgz", + "integrity": "sha1-Ahf3N+O4IfpaZp8YfG7VkgXwXpw=", + "requires": { + "babel-runtime": "6.11.6" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.8.0.tgz", + "integrity": "sha1-5z0wCkQKNdXGT1wqNE3CNuPfR74=", + "requires": { + "babel-helper-regex": "6.9.0", + "babel-runtime": "6.11.6", + "babel-types": "6.16.0" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.8.0.tgz", + "integrity": "sha1-huuHbQosY12k7ASLT33p38iX5ms=", + "requires": { + "babel-runtime": "6.11.6" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.8.0.tgz", + "integrity": "sha1-hMKesSGTckgJVaAg/vemXETzBTM=", + "requires": { + "babel-runtime": "6.11.6" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.11.0.tgz", + "integrity": "sha1-YpjOq6rYjVCj9POS2N6ZcmD27yw=", + "requires": { + "babel-helper-regex": "6.9.0", + "babel-runtime": "6.11.6", + "regexpu-core": "2.0.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.16.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.16.1.tgz", + "integrity": "sha1-p13msEihQVSq4UsBInVsW+05L1k=", + "requires": { + "babel-runtime": "6.11.6", + "babel-types": "6.16.0", + "private": "0.1.6" + } + }, + "babel-plugin-transform-runtime": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.15.0.tgz", + "integrity": "sha1-PXW02Umtga8VdXAnOEb7Wa6w1Xw=", + "requires": { + "babel-runtime": "6.11.6" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.11.3.tgz", + "integrity": "sha1-GDdBMlEmvH7Jz0wPwlfT58pa/UA=", + "requires": { + "babel-runtime": "6.11.6", + "babel-types": "6.16.0" + } + }, + "babel-polyfill": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.16.0.tgz", + "integrity": "sha1-LUUCHfh+JqN0ttTRqcZZZNF/JCI=", + "requires": { + "babel-runtime": "6.11.6", + "core-js": "2.4.1", + "regenerator-runtime": "0.9.5" + } + }, + "babel-preset-es2015": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.16.0.tgz", + "integrity": "sha1-Wazs0e++uvSPiUBIQPL+eMTSrVw=", + "requires": { + "babel-plugin-check-es2015-constants": "6.8.0", + "babel-plugin-transform-es2015-arrow-functions": "6.8.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.8.0", + "babel-plugin-transform-es2015-block-scoping": "6.15.0", + "babel-plugin-transform-es2015-classes": "6.14.0", + "babel-plugin-transform-es2015-computed-properties": "6.8.0", + "babel-plugin-transform-es2015-destructuring": "6.16.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.8.0", + "babel-plugin-transform-es2015-for-of": "6.8.0", + "babel-plugin-transform-es2015-function-name": "6.9.0", + "babel-plugin-transform-es2015-literals": "6.8.0", + "babel-plugin-transform-es2015-modules-amd": "6.8.0", + "babel-plugin-transform-es2015-modules-commonjs": "6.16.0", + "babel-plugin-transform-es2015-modules-systemjs": "6.14.0", + "babel-plugin-transform-es2015-modules-umd": "6.12.0", + "babel-plugin-transform-es2015-object-super": "6.8.0", + "babel-plugin-transform-es2015-parameters": "6.17.0", + "babel-plugin-transform-es2015-shorthand-properties": "6.8.0", + "babel-plugin-transform-es2015-spread": "6.8.0", + "babel-plugin-transform-es2015-sticky-regex": "6.8.0", + "babel-plugin-transform-es2015-template-literals": "6.8.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.8.0", + "babel-plugin-transform-es2015-unicode-regex": "6.11.0", + "babel-plugin-transform-regenerator": "6.16.1" + } + }, + "babel-preset-taskcluster": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-taskcluster/-/babel-preset-taskcluster-3.0.0.tgz", + "integrity": "sha1-QEfdaJJzFmGkjgRVHMBazTp3TFc=", + "requires": { + "babel-plugin-syntax-async-functions": "6.13.0", + "babel-plugin-transform-async-to-generator": "6.16.0", + "babel-plugin-transform-runtime": "6.15.0", + "babel-plugin-transform-strict-mode": "6.11.3", + "babel-preset-es2015": "6.16.0", + "babel-runtime": "6.11.6" + } + }, + "babel-register": { + "version": "6.16.3", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.16.3.tgz", + "integrity": "sha1-ewwMp7/euRiLpMJ+X8t1maSXxiQ=", + "requires": { + "babel-core": "6.17.0", + "babel-runtime": "6.11.6", + "core-js": "2.4.1", + "home-or-tmp": "1.0.0", + "lodash": "4.16.4", + "mkdirp": "0.5.1", + "path-exists": "1.0.0", + "source-map-support": "0.4.3" + } + }, + "babel-runtime": { + "version": "6.11.6", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.11.6.tgz", + "integrity": "sha1-bbcH/vLUnEm/o8tk79tDa1GLgiI=", + "requires": { + "core-js": "2.4.1", + "regenerator-runtime": "0.9.5" + } + }, + "babel-template": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.16.0.tgz", + "integrity": "sha1-4UndGp8Do1+BfdvE0EgZiOfryMo=", + "requires": { + "babel-runtime": "6.11.6", + "babel-traverse": "6.16.0", + "babel-types": "6.16.0", + "babylon": "6.11.6", + "lodash": "4.16.4" + } + }, + "babel-traverse": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.16.0.tgz", + "integrity": "sha1-+6ha4f1NEH3pzgAxScxX9TvvDE8=", + "requires": { + "babel-code-frame": "6.16.0", + "babel-messages": "6.8.0", + "babel-runtime": "6.11.6", + "babel-types": "6.16.0", + "babylon": "6.11.6", + "debug": "2.2.0", + "globals": "8.18.0", + "invariant": "2.2.1", + "lodash": "4.16.4" + } + }, + "babel-types": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.16.0.tgz", + "integrity": "sha1-ccyh2+Uzd2YiXFwZMHHo68vP/P4=", + "requires": { + "babel-runtime": "6.11.6", + "esutils": "2.0.2", + "lodash": "4.16.4", + "to-fast-properties": "1.0.2" + } + }, + "babylon": { + "version": "6.11.6", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.11.6.tgz", + "integrity": "sha1-VtxS5iSIKEHH/glSV/vLSlu2GuE=" + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + }, + "bcrypt-pbkdf": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz", + "integrity": "sha1-PKdrhSQccXC/fZcD57mqdGMAQNQ=", + "optional": true, + "requires": { + "tweetnacl": "0.14.3" + } + }, + "bin-version": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-1.0.4.tgz", + "integrity": "sha1-nrSY7m/Xb3q5p8FgQ2+JV5Q1144=", + "requires": { + "find-versions": "1.2.1" + } + }, + "bin-version-check": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-2.1.0.tgz", + "integrity": "sha1-5OXfKQuQaffRETJAMe/BP90RpbA=", + "requires": { + "bin-version": "1.0.4", + "minimist": "1.2.0", + "semver": "4.3.6", + "semver-truncate": "1.1.2" + } + }, + "binary-extensions": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.7.0.tgz", + "integrity": "sha1-bBYQ2xY6v7NO3+QvpCM0Oh4BGF0=", + "optional": true + }, + "bl": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", + "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=", + "requires": { + "readable-stream": "2.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + } + } + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "requires": { + "hoek": "2.16.3" + } + }, + "bounce": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bounce/-/bounce-1.2.3.tgz", + "integrity": "sha512-3G7B8CyBnip5EahCZJjnvQ1HLyArC6P5e+xcolo13BVI9ogFaDOsNMAE7FIWliHtIkYI8/nTRCvCY9tZa3Mu4g==", + "requires": { + "boom": "7.3.0", + "hoek": "6.1.3" + }, + "dependencies": { + "boom": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-7.3.0.tgz", + "integrity": "sha512-Swpoyi2t5+GhOEGw8rEsKvTxFLIDiiKoUc2gsoV6Lyr43LHBIzch3k2MvYUs8RTROrIkVJ3Al0TkaOGjnb+B6A==", + "requires": { + "hoek": "6.1.3" + } + }, + "hoek": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz", + "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==" + } + } + }, + "brace-expansion": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", + "integrity": "sha1-cZfX6qm4fmSDkOph/GbIRCdCDfk=", + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "optional": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "optional": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + } + }, + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=" + }, + "chalk": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.1.tgz", + "integrity": "sha1-UJr7ZwZudJn36zU1x3RFdyri0Bk=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "chokidar": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.6.0.tgz", + "integrity": "sha1-kMMq1IApAddxPeUy3ChOlqY60Fg=", + "optional": true, + "requires": { + "anymatch": "1.3.0", + "async-each": "1.0.1", + "fsevents": "1.2.7", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" + } + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "requires": { + "delayed-stream": "1.0.0" + } + }, + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "requires": { + "graceful-readlink": "1.0.1" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "convert-source-map": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.3.0.tgz", + "integrity": "sha1-6fPpxuJyjvwmdmlqcOs4L3MQamc=" + }, + "cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" + }, + "core-js": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", + "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "requires": { + "boom": "2.10.1" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "requires": { + "array-find-index": "1.0.2" + } + }, + "dashdash": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.0.tgz", + "integrity": "sha1-KeSGxUGL8PNWA0qZPVFoajPoQUE=", + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "detect-indent": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-3.0.1.tgz", + "integrity": "sha1-ncXl3bzu+DJXZLlFGwK8bVQIT3U=", + "requires": { + "get-stdin": "4.0.1", + "minimist": "1.2.0", + "repeating": "1.1.3" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "optional": true, + "requires": { + "jsbn": "0.1.0" + } + }, + "error-ex": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.0.tgz", + "integrity": "sha1-5ntD8+gsluo6WE/+4Ln8MyXYAtk=", + "requires": { + "is-arrayish": "0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "optional": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "optional": true, + "requires": { + "fill-range": "2.2.3" + } + }, + "extend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", + "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ=" + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "optional": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "extsprintf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=" + }, + "fast-safe-stringify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" + }, + "filename-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.0.tgz", + "integrity": "sha1-mW4+gEebmLmJfxWopYs9CE6SZ3U=", + "optional": true + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "optional": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.5", + "repeat-element": "1.1.2", + "repeat-string": "1.5.4" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "2.0.1" + } + } + } + }, + "find-versions": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-1.2.1.tgz", + "integrity": "sha1-y96fEuOFdaCvG+G5osXV/Y8Ya2I=", + "requires": { + "array-uniq": "1.0.3", + "get-stdin": "4.0.1", + "meow": "3.7.0", + "semver-regex": "1.0.0" + } + }, + "flatmap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/flatmap/-/flatmap-0.0.3.tgz", + "integrity": "sha1-Hxik2TgVLUlZZfnJWNkjqy3WabQ=" + }, + "for-in": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.6.tgz", + "integrity": "sha1-yfluib+tGKVFr17D7TUqHZ5bTcg=", + "optional": true + }, + "for-own": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.4.tgz", + "integrity": "sha1-AUm0GjkIjHUV9R6+HBOG1F+TUHI=", + "optional": true, + "requires": { + "for-in": "0.1.6" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.0.0.tgz", + "integrity": "sha1-bwrrrcxdoWwT4ezBETfYX5uIOyU=", + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.12" + } + }, + "formidable": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", + "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==" + }, + "fs-readdir-recursive": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz", + "integrity": "sha1-MVtPuMHKW4xH3v7zGdBz2tNWgFk=" + }, + "fs-walk": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/fs-walk/-/fs-walk-0.0.1.tgz", + "integrity": "sha1-9/yRw64e6tB8mYvF0N1B8tvr0zU=", + "requires": { + "async": "2.1.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", + "optional": true, + "requires": { + "nan": "2.12.1", + "node-pre-gyp": "0.10.3" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "needle": { + "version": "2.2.4", + "bundled": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.3", + "bundled": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.5", + "bundled": true, + "optional": true + }, + "npm-packlist": { + "version": "1.2.0", + "bundled": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "optional": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "optional": true + } + } + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=" + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "requires": { + "is-property": "1.0.2" + } + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + }, + "getpass": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz", + "integrity": "sha1-KD/9n8ElaECHUxHBtg6MQBhxEOY=", + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.3", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "optional": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "2.0.1" + } + }, + "globals": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-8.18.0.tgz", + "integrity": "sha1-k9SmK9ysOM+vr8R9awNHaMsP/LQ=" + }, + "graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha1-uqy6N9GdEfnRRtNXi8mZWMN4fik=" + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "requires": { + "chalk": "1.1.1", + "commander": "2.9.0", + "is-my-json-valid": "2.15.0", + "pinkie-promise": "2.0.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.0.0" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + }, + "home-or-tmp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-1.0.0.tgz", + "integrity": "sha1-S58eQIAMPlDGwn94FnavzOcfOYU=", + "requires": { + "os-tmpdir": "1.0.2", + "user-home": "1.1.1" + } + }, + "hosted-git-info": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.1.5.tgz", + "integrity": "sha1-C6gdkNouJas0ozLm7HeTbhWYEYs=" + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.3.1", + "sshpk": "1.10.1" + } + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "requires": { + "repeating": "2.0.1" + }, + "dependencies": { + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "requires": { + "is-finite": "1.0.2" + } + } + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "intersect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/intersect/-/intersect-1.0.1.tgz", + "integrity": "sha1-MyZQ4QhU2MCsWMGSvcJ6i/fnoww=" + }, + "invariant": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.1.tgz", + "integrity": "sha1-sJcBBUdmjH4zcCjr6Bbr42yKjVQ=", + "requires": { + "loose-envify": "1.2.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "optional": true, + "requires": { + "binary-extensions": "1.7.0" + } + }, + "is-buffer": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.4.tgz", + "integrity": "sha1-z8hszV3FpS+oBIkRHGkgxFfi2Ys=" + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-dotfile": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz", + "integrity": "sha1-LBMjg/ORmfjtwmjKAbmwB9IFzE0=", + "optional": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "optional": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "optional": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "1.0.0" + } + }, + "is-my-json-valid": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz", + "integrity": "sha1-k27do8o8IR/ZjzstPgjaQ/eykVs=", + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.0", + "xtend": "4.0.1" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "requires": { + "kind-of": "3.0.4" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "optional": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "optional": true, + "requires": { + "isarray": "1.0.0" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jodid25519": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", + "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=", + "optional": true, + "requires": { + "jsbn": "0.1.0" + } + }, + "js-tokens": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-2.0.0.tgz", + "integrity": "sha1-eZA/VWPud4zBFi5tzxoAJ8l/nLU=" + }, + "js-yaml": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz", + "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=", + "requires": { + "argparse": "1.0.9", + "esprima": "2.7.3" + } + }, + "jsbn": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz", + "integrity": "sha1-ZQmH2g3XT06/WhE3eiqi0nPpff0=", + "optional": true + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json5": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz", + "integrity": "sha1-BUNS5MTIDIbAkjh31EneF2pzLI0=" + }, + "jsonpointer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.0.tgz", + "integrity": "sha1-ZmHhYdL8RF8Z+YQwIxNDci4fy9U=" + }, + "jsprim": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz", + "integrity": "sha1-KnJW9wQSop7jZwqspiWZTE3P8lI=", + "requires": { + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + } + }, + "kind-of": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.0.4.tgz", + "integrity": "sha1-e47PGKThf4Jp1ztQHJ8jLJaIenQ=", + "requires": { + "is-buffer": "1.1.4" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "4.1.9", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "lodash": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.16.4.tgz", + "integrity": "sha1-Ac4wa5utExnypVKGdPiCl663ASc=" + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "requires": { + "chalk": "1.1.1" + } + }, + "loose-envify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.2.0.tgz", + "integrity": "sha1-aaZarT3lQs9O4PT+dOjjPHCcyw8=", + "requires": { + "js-tokens": "1.0.3" + }, + "dependencies": { + "js-tokens": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.3.tgz", + "integrity": "sha1-FOVutoyPGpLEPVn1AU7CncIPKuE=" + } + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.1" + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.3.5", + "object-assign": "4.1.0", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + } + }, + "merge": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", + "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "optional": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.0", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.0.4", + "normalize-path": "2.0.1", + "object.omit": "2.0.0", + "parse-glob": "3.0.4", + "regex-cache": "0.4.3" + } + }, + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + }, + "mime-db": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.24.0.tgz", + "integrity": "sha1-4tE/k58AFsbk6a0lqGUvEmxGfww=" + }, + "mime-types": { + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.12.tgz", + "integrity": "sha1-FSuiVndwIN1GY/VMLnvCY4HnFyk=", + "requires": { + "mime-db": "1.24.0" + } + }, + "minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "requires": { + "brace-expansion": "1.1.6" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + }, + "nan": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", + "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==", + "optional": true + }, + "node-uuid": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz", + "integrity": "sha1-baWhdmjEs91ZYjvaEc9/pMH2Cm8=" + }, + "normalize-package-data": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.5.tgz", + "integrity": "sha1-jZJPFClg4Xd+f/4XBUNjHMfLAt8=", + "requires": { + "hosted-git-info": "2.1.5", + "is-builtin-module": "1.0.0", + "semver": "4.3.6", + "validate-npm-package-license": "3.0.1" + } + }, + "normalize-path": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.0.1.tgz", + "integrity": "sha1-R4hqwWYnYNQmG32XnSQXCdPOP3o=", + "optional": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "object-assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=" + }, + "object.omit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.0.tgz", + "integrity": "sha1-hoWXMz1U5gZilAu0WGBd1q4S/pQ=", + "optional": true, + "requires": { + "for-own": "0.1.4", + "is-extendable": "0.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "output-file-sync": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", + "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", + "requires": { + "graceful-fs": "4.1.9", + "mkdirp": "0.5.1", + "object-assign": "4.1.0" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "optional": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.2", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "1.3.0" + } + }, + "path-exists": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz", + "integrity": "sha1-1aiZjrce83p0w06w2eum6HjuoIE=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "4.1.9", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + } + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "optional": true + }, + "private": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.6.tgz", + "integrity": "sha1-VcapdtD5uvuZJIUTUP5HubX7t8E=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "qs": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.1.tgz", + "integrity": "sha1-zgPF/wk1vB2daanxTL0Y5WjWdiU=" + }, + "randomatic": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.5.tgz", + "integrity": "sha1-Xp718tVzxnvSuBJK6QtRVuRXhAs=", + "optional": true, + "requires": { + "is-number": "2.1.0", + "kind-of": "3.0.4" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.3.5", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "readable-stream": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", + "optional": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "optional": true, + "requires": { + "graceful-fs": "4.1.9", + "minimatch": "3.0.3", + "readable-stream": "2.1.5", + "set-immediate-shim": "1.0.1" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "regenerate": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.1.tgz", + "integrity": "sha1-AwAgOl0v3PiRFtzoQnXQEfWQPzM=" + }, + "regenerator-runtime": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.9.5.tgz", + "integrity": "sha1-QD1tQKS9/5wzDdk5Lcuy2ai7ofw=" + }, + "regex-cache": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", + "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", + "optional": true, + "requires": { + "is-equal-shallow": "0.1.3", + "is-primitive": "2.0.0" + } + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "requires": { + "regenerate": "1.3.1", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "requires": { + "jsesc": "0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" + } + } + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" + }, + "repeat-string": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.5.4.tgz", + "integrity": "sha1-ZOwMkeD0tHX5DVtkNlHj5uW2wtU=", + "optional": true + }, + "repeating": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", + "integrity": "sha1-PUEUIYh3U3SU+X93+Xhfq4EPpKw=", + "requires": { + "is-finite": "1.0.2" + } + }, + "request": { + "version": "2.75.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.75.0.tgz", + "integrity": "sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM=", + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.5.0", + "bl": "1.1.2", + "caseless": "0.11.0", + "combined-stream": "1.0.5", + "extend": "3.0.0", + "forever-agent": "0.6.1", + "form-data": "2.0.0", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.12", + "node-uuid": "1.4.7", + "oauth-sign": "0.8.2", + "qs": "6.2.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.1", + "tunnel-agent": "0.4.3" + } + }, + "rimraf": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", + "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", + "requires": { + "glob": "7.1.1" + }, + "dependencies": { + "glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.3", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + }, + "semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=" + }, + "semver-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-1.0.0.tgz", + "integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk=" + }, + "semver-truncate": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz", + "integrity": "sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g=", + "requires": { + "semver": "5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + } + } + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "optional": true + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "signal-exit": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.1.tgz", + "integrity": "sha1-WkyISZK2OnrNm623iUw+6c/MrYE=" + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" + }, + "slugid": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/slugid/-/slugid-1.1.0.tgz", + "integrity": "sha1-4J8AiZwJ9acFjtw23UnwRv1QqCo=", + "requires": { + "uuid": "2.0.3" + } + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "requires": { + "hoek": "2.16.3" + } + }, + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" + }, + "source-map-support": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.3.tgz", + "integrity": "sha1-aTyDg9Q4mkVpSGmHwhl0TfxgFoU=", + "requires": { + "source-map": "0.5.6" + } + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=" + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.10.1.tgz", + "integrity": "sha1-MOGl0ykkSXShr2FREznVla9mOLA=", + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.0", + "dashdash": "1.14.0", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.6", + "jodid25519": "1.0.2", + "jsbn": "0.1.0", + "tweetnacl": "0.14.3" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "requires": { + "get-stdin": "4.0.1" + } + }, + "superagent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-5.1.0.tgz", + "integrity": "sha512-7V6JVx5N+eTL1MMqRBX0v0bG04UjrjAvvZJTF/VDH/SH2GjSLqlrcYepFlpTrXpm37aSY6h3GGVWGxXl/98TKA==", + "requires": { + "component-emitter": "1.3.0", + "cookiejar": "2.1.2", + "debug": "4.1.1", + "fast-safe-stringify": "2.0.7", + "form-data": "2.5.1", + "formidable": "1.2.1", + "methods": "1.1.2", + "mime": "2.4.4", + "qs": "6.9.0", + "readable-stream": "3.4.0", + "semver": "6.3.0" + }, + "dependencies": { + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "1.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "2.1.2" + } + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.8", + "mime-types": "2.1.12" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "qs": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.0.tgz", + "integrity": "sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA==" + }, + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "requires": { + "inherits": "2.0.3", + "string_decoder": "1.3.0", + "util-deprecate": "1.0.2" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "5.2.0" + } + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "taskcluster-client": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/taskcluster-client/-/taskcluster-client-22.0.0.tgz", + "integrity": "sha512-L9Z84WXWVLkCYlcxNl6TAXBqoERyB0iavNgsymQqu9TGMLh3Acl7J55PzthZr/o1F3sVfHwRgDnxM1CidaYbEQ==", + "requires": { + "debug": "4.1.1", + "hawk": "7.0.10", + "lodash": "4.17.15", + "slugid": "2.0.0", + "superagent": "5.1.0", + "taskcluster-lib-urls": "12.0.0" + }, + "dependencies": { + "boom": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-7.3.0.tgz", + "integrity": "sha512-Swpoyi2t5+GhOEGw8rEsKvTxFLIDiiKoUc2gsoV6Lyr43LHBIzch3k2MvYUs8RTROrIkVJ3Al0TkaOGjnb+B6A==", + "requires": { + "hoek": "6.1.3" + } + }, + "cryptiles": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-4.1.3.tgz", + "integrity": "sha512-gT9nyTMSUC1JnziQpPbxKGBbUg8VL7Zn2NB4E1cJYvuXdElHrwxrV9bmltZGDzet45zSDGyYceueke1TjynGzw==", + "requires": { + "boom": "7.3.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "2.1.2" + } + }, + "hawk": { + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-7.0.10.tgz", + "integrity": "sha512-3RWF4SXN9CdZ1VDAe6Pn3Rd0tC3Lw+GV+esX5oKCrXoScZK3Ri6dl5Wt986M/hlzU+GuapTGiB0rBhGeRIBQsw==", + "requires": { + "b64": "4.1.2", + "boom": "7.3.0", + "cryptiles": "4.1.3", + "hoek": "6.1.3", + "sntp": "3.0.2" + } + }, + "hoek": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz", + "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==" + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "slugid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slugid/-/slugid-2.0.0.tgz", + "integrity": "sha512-zTCivUfTk2GC6MU4Fjcz0iXwAjhe0NweMJqpfWcGrBbrm2dWtVAUupAonfsc7ysw4M0kZ934Nle5ljwM2dR+/g==", + "requires": { + "uuid": "3.3.3", + "uuid-parse": "1.1.0" + } + }, + "sntp": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-3.0.2.tgz", + "integrity": "sha512-MCAPpBPFjNp1fwDVCLSRuWuH9gONtb2R+lS1esC6Mp8lP6jy60FVUtP/Qr0jBvcWAVbhzx06y1b6ptXiy32dug==", + "requires": { + "boom": "7.3.0", + "bounce": "1.2.3", + "hoek": "6.1.3", + "teamwork": "3.2.0" + } + }, + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + } + } + }, + "taskcluster-lib-urls": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/taskcluster-lib-urls/-/taskcluster-lib-urls-12.0.0.tgz", + "integrity": "sha512-OrEFE0m3p/+mGsmIwjttLhSKg3io6MpJLhYtPNjVSZA9Ix8Y5tprN3vM6a3MjWt5asPF6AKZsfT43cgpGwJB0g==" + }, + "teamwork": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/teamwork/-/teamwork-3.2.0.tgz", + "integrity": "sha512-xAmJ8PIVjRZMXAHgUuOP8ITsv0SedyWAit2UWiNImXgg/F+BxrsG46ZegElNBM0Dwp+iMfbigg/Ll/M2oDRYww==" + }, + "to-fast-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.2.tgz", + "integrity": "sha1-8/XAw7pymafvmUJ+RGMyV63kMyA=" + }, + "tough-cookie": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz", + "integrity": "sha1-mcd9+7fYBCSeiimdTLD9gf7wg/0=" + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=" + }, + "tweetnacl": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.3.tgz", + "integrity": "sha1-PaOC9nDyXe1417PReSEZvKC3Ey0=", + "optional": true + }, + "user-home": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" + }, + "uuid-parse": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/uuid-parse/-/uuid-parse-1.1.0.tgz", + "integrity": "sha512-OdmXxA8rDsQ7YpNVbKSJkNzTw2I+S5WsbMDnCtIWSQaosNAcWtFuI/YK1TjzUI6nbkgiqEyh8gWngfcv8Asd9A==" + }, + "v8flags": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.0.11.tgz", + "integrity": "sha1-vKjzDw1tYGEswsAGQeaWLUKuaIE=", + "requires": { + "user-home": "1.1.1" + } + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "verror": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", + "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", + "requires": { + "extsprintf": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } +} diff --git a/security/nss/automation/taskcluster/graph/package.json b/security/nss/automation/taskcluster/graph/package.json new file mode 100644 index 0000000000..7bf52b9a5b --- /dev/null +++ b/security/nss/automation/taskcluster/graph/package.json @@ -0,0 +1,24 @@ +{ + "name": "decision-task", + "version": "0.0.1", + "private": true, + "author": "Tim Taubert <ttaubert@mozilla.com>", + "description": "Decision Task for NSS", + "scripts": { + "compile": "babel-compile -p taskcluster src:lib", + "install": "npm run compile" + }, + "dependencies": { + "babel-cli": "^6.14.0", + "babel-compile": "^2.0.0", + "babel-preset-taskcluster": "^3.0.0", + "babel-runtime": "^6.11.6", + "flatmap": "0.0.3", + "intersect": "^1.0.1", + "js-yaml": "^3.6.1", + "merge": "^1.2.0", + "minimist": "^1.2.0", + "slugid": "^1.1.0", + "taskcluster-client": "^22.0.0" + } +} diff --git a/security/nss/automation/taskcluster/graph/src/context_hash.js b/security/nss/automation/taskcluster/graph/src/context_hash.js new file mode 100644 index 0000000000..0699a0590e --- /dev/null +++ b/security/nss/automation/taskcluster/graph/src/context_hash.js @@ -0,0 +1,53 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import fs from "fs"; +import path from "path"; +import crypto from "crypto"; +import flatmap from "flatmap"; + +// Compute the SHA-256 digest. +function sha256(data) { + let hash = crypto.createHash("sha256"); + hash.update(data); + return hash.digest("hex"); +} + +// Recursively collect a list of all files of a given directory. +function collectFilesInDirectory(dir) { + return flatmap(fs.readdirSync(dir), entry => { + let entry_path = path.join(dir, entry); + + if (fs.lstatSync(entry_path).isDirectory()) { + return collectFilesInDirectory(entry_path); + } + + return [entry_path]; + }); +} + +// A list of hashes for each file in the given path. +function collectFileHashes(context_path) { + let root = path.join(__dirname, "../../../.."); + let dir = path.join(root, context_path); + let files = collectFilesInDirectory(dir).sort(); + + return files.map(file => { + return sha256(file + "|" + fs.readFileSync(file, "utf-8")); + }); +} + +// Compute a context hash for the given context path. +export default function (context_path) { + // Regenerate all images when the image_builder changes. + let hashes = collectFileHashes("automation/taskcluster/image_builder"); + + // Regenerate images when the image itself changes. + hashes = hashes.concat(collectFileHashes(context_path)); + + // Generate a new prefix every month to ensure the image stays buildable. + let now = new Date(); + let prefix = `${now.getUTCFullYear()}-${now.getUTCMonth() + 1}:`; + return sha256(prefix + hashes.join(",")); +} diff --git a/security/nss/automation/taskcluster/graph/src/extend.js b/security/nss/automation/taskcluster/graph/src/extend.js new file mode 100644 index 0000000000..a2e41a61d6 --- /dev/null +++ b/security/nss/automation/taskcluster/graph/src/extend.js @@ -0,0 +1,1229 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import merge from "./merge"; +import * as queue from "./queue"; + +const LINUX_IMAGE = { + name: "linux", + path: "automation/taskcluster/docker" +}; + +const LINUX_BUILDS_IMAGE = { + name: "linux-builds", + path: "automation/taskcluster/docker-builds" +}; + +const LINUX_INTEROP_IMAGE = { + name: "linux-interop", + path: "automation/taskcluster/docker-interop" +}; + +const CLANG_FORMAT_IMAGE = { + name: "clang-format", + path: "automation/taskcluster/docker-clang-format" +}; + +const LINUX_GCC44_IMAGE = { + name: "linux-gcc-4.4", + path: "automation/taskcluster/docker-gcc-4.4" +}; + +const FUZZ_IMAGE = { + name: "fuzz", + path: "automation/taskcluster/docker-fuzz" +}; + +// Bug 1488148 - temporary image for fuzzing 32-bit builds. +const FUZZ_IMAGE_32 = { + name: "fuzz32", + path: "automation/taskcluster/docker-fuzz32" +}; + +const WINDOWS_CHECKOUT_CMD = + "bash -c \"hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss || " + + "(sleep 2; hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss) || " + + "(sleep 5; hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss)\""; +const MAC_CHECKOUT_CMD = ["bash", "-c", + "hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss || " + + "(sleep 2; hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss) || " + + "(sleep 5; hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss)"]; + +/*****************************************************************************/ + +queue.filter(task => { + if (task.group == "Builds") { + // Remove extra builds on {A,UB}San and ARM. + if (task.collection == "asan" || task.platform == "aarch64") { + return false; + } + + // Make modular builds only on Linux make. + if (task.symbol == "modular" && task.collection != "make") { + return false; + } + } + + if (task.tests == "bogo" || task.tests == "interop" || task.tests == "tlsfuzzer") { + // No windows + if (task.platform == "windows2012-64" || + task.platform == "windows2012-32") { + return false; + } + + // No ARM; TODO: enable + if (task.platform == "aarch64") { + return false; + } + + // No mac + if (task.platform == "mac") { + return false; + } + } + + if (task.tests == "fips" && + (task.platform == "mac" || task.platform == "aarch64")) { + return false; + } + + // Only old make builds have -Ddisable_libpkix=0 and can run chain tests. + if (task.tests == "chains" && task.collection != "make") { + return false; + } + + // Don't run all additional hardware tests on ARM. + if (task.group == "Cipher" && task.platform == "aarch64" && task.env && + (task.env.NSS_DISABLE_PCLMUL == "1" || task.env.NSS_DISABLE_SSE4_1 == "1" + || task.env.NSS_DISABLE_AVX == "1" || task.env.NSS_DISABLE_AVX2 == "1")) { + return false; + } + + // Don't run ARM specific hardware tests on non-ARM. + // TODO: our server that runs task cluster doesn't support Intel SHA extensions. + if (task.group == "Cipher" && task.platform != "aarch64" && task.env && + (task.env.NSS_DISABLE_HW_SHA1 == "1" || task.env.NSS_DISABLE_HW_SHA2 == "1")) { + return false; + } + + // Don't run DBM builds on aarch64. + if (task.group == "DBM" && task.platform == "aarch64") { + return false; + } + + return true; +}); + +queue.map(task => { + if (task.collection == "asan") { + // CRMF and FIPS tests still leak, unfortunately. + if (task.tests == "crmf") { + task.env.ASAN_OPTIONS = "detect_leaks=0"; + } + } + + if (task.tests == "ssl") { + if (!task.env) { + task.env = {}; + } + + // Stress tests to not include other SSL tests + if (task.symbol == "stress") { + task.env.NSS_SSL_TESTS = "normal_normal"; + } else { + task.env.NSS_SSL_TESTS = "crl iopr policy normal_normal"; + } + + // FIPS runs + if (task.collection == "fips") { + task.env.NSS_SSL_TESTS += " fips_fips fips_normal normal_fips"; + } + + if (task.platform == "mac") { + task.maxRunTime = 7200; + } + } + + // Windows is slow. + if ((task.platform == "windows2012-32" || task.platform == "windows2012-64") && + task.tests == "chains") { + task.maxRunTime = 7200; + } + + if (task.platform == "mac" && task.tests == "tools") { + task.maxRunTime = 7200; + } + return task; +}); + +/*****************************************************************************/ + +export default async function main() { + await scheduleLinux("Linux 32 (opt)", { + platform: "linux32", + image: LINUX_IMAGE + }, "-t ia32 --opt"); + + await scheduleLinux("Linux 32 (debug)", { + platform: "linux32", + collection: "debug", + image: LINUX_IMAGE + }, "-t ia32"); + + await scheduleLinux("Linux 64 (opt)", { + platform: "linux64", + image: LINUX_IMAGE + }, "--opt"); + + await scheduleLinux("Linux 64 (debug)", { + platform: "linux64", + collection: "debug", + image: LINUX_IMAGE + }); + + await scheduleLinux("Linux 64 (debug, make)", { + env: {USE_64: "1"}, + platform: "linux64", + image: LINUX_IMAGE, + collection: "make", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh" + ], + }); + + await scheduleLinux("Linux 64 (opt, make)", { + env: {USE_64: "1", BUILD_OPT: "1"}, + platform: "linux64", + image: LINUX_IMAGE, + collection: "make", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh" + ], + }); + + await scheduleLinux("Linux 32 (debug, make)", { + platform: "linux32", + image: LINUX_IMAGE, + collection: "make", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh" + ], + }); + + await scheduleLinux("Linux 64 (ASan, debug)", { + env: { + UBSAN_OPTIONS: "print_stacktrace=1", + NSS_DISABLE_ARENA_FREE_LIST: "1", + NSS_DISABLE_UNLOAD: "1", + CC: "clang", + CCC: "clang++", + }, + platform: "linux64", + collection: "asan", + image: LINUX_IMAGE, + features: ["allowPtrace"], + }, "--ubsan --asan"); + + await scheduleLinux("Linux 64 (FIPS opt)", { + platform: "linux64", + collection: "fips", + image: LINUX_IMAGE, + }, "--enable-fips --opt"); + + await scheduleWindows("Windows 2012 64 (debug, make)", { + platform: "windows2012-64", + collection: "make", + env: {USE_64: "1"} + }, "build.sh"); + + await scheduleWindows("Windows 2012 32 (debug, make)", { + platform: "windows2012-32", + collection: "make" + }, "build.sh"); + + await scheduleWindows("Windows 2012 64 (opt)", { + platform: "windows2012-64", + }, "build_gyp.sh --opt"); + + await scheduleWindows("Windows 2012 64 (debug)", { + platform: "windows2012-64", + collection: "debug" + }, "build_gyp.sh"); + + await scheduleWindows("Windows 2012 64 Static (opt)", { + platform: "windows2012-64", + collection: "opt-static" + }, "build_gyp.sh --opt --static"); + + await scheduleWindows("Windows 2012 32 (opt)", { + platform: "windows2012-32", + }, "build_gyp.sh --opt -t ia32"); + + await scheduleWindows("Windows 2012 32 (debug)", { + platform: "windows2012-32", + collection: "debug" + }, "build_gyp.sh -t ia32"); + + await scheduleFuzzing(); + await scheduleFuzzing32(); + + await scheduleTools(); + + let aarch64_base = { + image: "franziskus/nss-aarch64-ci", + provisioner: "localprovisioner", + workerType: "nss-aarch64", + platform: "aarch64", + maxRunTime: 7200 + }; + + await scheduleLinux("Linux AArch64 (debug)", + merge(aarch64_base, { + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh" + ], + collection: "debug", + }) + ); + + await scheduleLinux("Linux AArch64 (opt)", + merge(aarch64_base, { + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh --opt" + ], + collection: "opt", + }) + ); + + await scheduleLinux("Linux AArch64 (debug, make)", + merge(aarch64_base, { + env: {USE_64: "1"}, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh" + ], + collection: "make", + }) + ); + + await scheduleMac("Mac (opt)", {collection: "opt"}, "--opt"); + await scheduleMac("Mac Static (opt)", {collection: "opt-static"}, "--opt --static -Ddisable_libpkix=1"); + await scheduleMac("Mac (debug)", {collection: "debug"}); + + // Must be executed after all other tasks are scheduled + queue.clearFilters(); + await scheduleCodeReview(); +} + + +async function scheduleMac(name, base, args = "") { + let mac_base = merge(base, { + env: { + PATH: "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin", + NSS_TASKCLUSTER_MAC: "1", + DOMSUF: "localdomain", + HOST: "localhost", + }, + provisioner: "localprovisioner", + workerType: "nss-macos-10-12", + platform: "mac" + }); + + // Build base definition. + let build_base_without_command_symbol = merge(mac_base, { + provisioner: "localprovisioner", + workerType: "nss-macos-10-12", + platform: "mac", + maxRunTime: 7200, + artifacts: [{ + expires: 24 * 7, + type: "directory", + path: "public" + }], + kind: "build", + }); + + let gyp_cmd = "nss/automation/taskcluster/scripts/build_gyp.sh "; + + if (!("collection" in base) || + (base.collection != "make" && + base.collection != "asan" && + base.collection != "fips" && + base.collection != "fuzz")) { + let nspr_gyp = gyp_cmd + "--nspr-only --nspr-test-build --nspr-test-run "; + let nspr_build = merge(build_base_without_command_symbol, { + command: [ + MAC_CHECKOUT_CMD, + ["bash", "-c", + nspr_gyp + args] + ], + symbol: "NSPR" + }); + // The task that tests NSPR. + let nspr_task_build = queue.scheduleTask(merge(nspr_build, {name})); + } + + let build_base = merge(build_base_without_command_symbol, { + command: [ + MAC_CHECKOUT_CMD, + ["bash", "-c", + gyp_cmd + args] + ], + symbol: "B" + }); + + // The task that builds NSPR+NSS. + let task_build = queue.scheduleTask(merge(build_base, {name})); + + // The task that generates certificates. + let task_cert = queue.scheduleTask(merge(build_base, { + name: "Certificates", + command: [ + MAC_CHECKOUT_CMD, + ["bash", "-c", + "nss/automation/taskcluster/scripts/gen_certs.sh"] + ], + parent: task_build, + symbol: "Certs" + })); + + // Schedule tests. + scheduleTests(task_build, task_cert, merge(mac_base, { + command: [ + MAC_CHECKOUT_CMD, + ["bash", "-c", + "nss/automation/taskcluster/scripts/run_tests.sh"] + ] + })); + + return queue.submit(); +} + +/*****************************************************************************/ + +async function scheduleLinux(name, overrides, args = "") { + let checkout_and_gyp = "bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh "; + let artifacts_and_kind = { + artifacts: { + public: { + expires: 24 * 7, + type: "directory", + path: "/home/worker/artifacts" + } + }, + kind: "build", + }; + + if (!("collection" in overrides) || + (overrides.collection != "make" && + overrides.collection != "asan" && + overrides.collection != "fips" && + overrides.collection != "fuzz")) { + let nspr_gyp = checkout_and_gyp + "--nspr-only --nspr-test-build --nspr-test-run "; + + let nspr_base = merge({ + command: [ + "/bin/bash", + "-c", + nspr_gyp + args + ], + }, overrides); + let nspr_without_symbol = merge(nspr_base, artifacts_and_kind); + let nspr_build = merge(nspr_without_symbol, { + symbol: "NSPR", + }); + // The task that tests NSPR. + let nspr_task_build = queue.scheduleTask(merge(nspr_build, {name})); + } + + // Construct a base definition. This takes |overrides| second because + // callers expect to be able to overwrite the |command| key. + let base = merge({ + command: [ + "/bin/bash", + "-c", + checkout_and_gyp + args + ], + }, overrides); + + let base_without_symbol = merge(base, artifacts_and_kind); + + // The base for building. + let build_base = merge(base_without_symbol, { + symbol: "B", + }); + + // The task that builds NSPR+NSS. + let task_build = queue.scheduleTask(merge(build_base, {name})); + + // Make builds run FIPS tests, which need an extra FIPS build. + if (base.collection == "make") { + let extra_build = queue.scheduleTask(merge(build_base, { + env: { NSS_FORCE_FIPS: "1" }, + group: "FIPS", + name: `${name} w/ NSS_FORCE_FIPS` + })); + + // The task that generates certificates. + let task_cert = queue.scheduleTask(merge(build_base, { + name: "Certificates", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/gen_certs.sh" + ], + parent: extra_build, + symbol: "Certs-F", + group: "FIPS", + })); + + // Schedule FIPS tests. + queue.scheduleTask(merge(base, { + parent: task_cert, + name: "FIPS", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/run_tests.sh" + ], + cycle: "standard", + kind: "test", + name: "FIPS tests", + symbol: "Tests-F", + tests: "fips", + group: "FIPS" + })); + } + + // The task that generates certificates. + let cert_base = merge(build_base, { + name: "Certificates", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/gen_certs.sh" + ], + parent: task_build, + symbol: "Certs" + }); + let task_cert = queue.scheduleTask(cert_base); + + // Schedule tests. + scheduleTests(task_build, task_cert, merge(base, { + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/run_tests.sh" + ] + })); + + // Extra builds. + let extra_base = merge(build_base, { + group: "Builds", + image: LINUX_BUILDS_IMAGE, + }); + queue.scheduleTask(merge(extra_base, { + name: `${name} w/ clang-4`, + env: { + CC: "clang-4.0", + CCC: "clang++-4.0", + }, + symbol: "clang-4" + })); + queue.scheduleTask(merge(extra_base, { + name: `${name} w/ clang-10`, + env: { + CC: "clang-10", + CCC: "clang++-10", + }, + symbol: "clang-10" + })); + queue.scheduleTask(merge(extra_base, { + name: `${name} w/ gcc-4.4`, + image: LINUX_GCC44_IMAGE, + env: { + USE_64: "1", + CC: "gcc-4.4", + CCC: "g++-4.4", + // gcc-4.6 introduced nullptr. + NSS_DISABLE_GTESTS: "1", + }, + // Use the old Makefile-based build system, GYP doesn't have a proper GCC + // version check for __int128 support. It's mainly meant to cover RHEL6. + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh", + ], + symbol: "gcc-4.4" + })); + + queue.scheduleTask(merge(extra_base, { + name: `${name} w/ gcc-4.8`, + env: { + CC: "gcc-4.8", + CCC: "g++-4.8", + // gcc-4.8 has incomplete c++11 support + NSS_DISABLE_GTESTS: "1", + }, + // Use -Ddisable-intelhw_sha=1, GYP doesn't have a proper GCC version + // check for Intel SHA support. + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh", + ], + symbol: "gcc-4.8" + })); + + queue.scheduleTask(merge(extra_base, { + name: `${name} w/ gcc-5`, + env: { + CC: "gcc-5", + CCC: "g++-5" + }, + symbol: "gcc-5" + })); + + queue.scheduleTask(merge(extra_base, { + name: `${name} w/ gcc-11`, + env: { + CC: "gcc-11", + CCC: "g++-11", + }, + symbol: "gcc-11" + })); + + queue.scheduleTask(merge(extra_base, { + name: `${name} w/ modular builds`, + image: LINUX_IMAGE, + env: {NSS_BUILD_MODULAR: "1"}, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh", + ], + symbol: "modular" + })); + + if (base.collection != "make") { + let task_build_dbm = queue.scheduleTask(merge(extra_base, { + name: `${name} w/ legacy-db`, + command: [ + "/bin/bash", + "-c", + checkout_and_gyp + "--enable-legacy-db" + ], + symbol: "B", + group: "DBM", + })); + + let task_cert_dbm = queue.scheduleTask(merge(cert_base, { + parent: task_build_dbm, + group: "DBM", + symbol: "Certs" + })); + } + + return queue.submit(); +} + +/*****************************************************************************/ + +function scheduleFuzzingRun(base, name, target, max_len, symbol = null, corpus = null) { + const MAX_FUZZ_TIME = 300; + + queue.scheduleTask(merge(base, { + name, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/fuzz.sh " + + `${target} nss/fuzz/corpus/${corpus || target} ` + + `-max_total_time=${MAX_FUZZ_TIME} ` + + `-max_len=${max_len}` + ], + symbol: symbol || name + })); +} + +async function scheduleFuzzing() { + let base = { + env: { + ASAN_OPTIONS: "allocator_may_return_null=1:detect_stack_use_after_return=1", + UBSAN_OPTIONS: "print_stacktrace=1", + NSS_DISABLE_ARENA_FREE_LIST: "1", + NSS_DISABLE_UNLOAD: "1", + CC: "clang", + CCC: "clang++" + }, + features: ["allowPtrace"], + platform: "linux64", + collection: "fuzz", + image: FUZZ_IMAGE + }; + + // Build base definition. + let build_base = merge(base, { + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && " + + "nss/automation/taskcluster/scripts/build_gyp.sh --fuzz" + ], + artifacts: { + public: { + expires: 24 * 7, + type: "directory", + path: "/home/worker/artifacts" + } + }, + kind: "build", + symbol: "B" + }); + + // The task that builds NSPR+NSS. + let task_build = queue.scheduleTask(merge(build_base, { + name: "Linux x64 (debug, fuzz)" + })); + + // The task that builds NSPR+NSS (TLS fuzzing mode). + let task_build_tls = queue.scheduleTask(merge(build_base, { + name: "Linux x64 (debug, TLS fuzz)", + symbol: "B", + group: "TLS", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && " + + "nss/automation/taskcluster/scripts/build_gyp.sh --fuzz=tls" + ], + })); + + // Schedule tests. + queue.scheduleTask(merge(base, { + parent: task_build_tls, + name: "Gtests", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/run_tests.sh" + ], + env: {GTESTFILTER: "*Fuzz*"}, + tests: "ssl_gtests gtests", + cycle: "standard", + symbol: "Gtest", + kind: "test" + })); + + // Schedule fuzzing runs. + let run_base = merge(base, {parent: task_build, kind: "test"}); + scheduleFuzzingRun(run_base, "CertDN", "certDN", 4096); + scheduleFuzzingRun(run_base, "QuickDER", "quickder", 10000); + + // Schedule MPI fuzzing runs. + let mpi_base = merge(run_base, {group: "MPI"}); + let mpi_names = ["add", "addmod", "div", "mod", "mulmod", "sqr", + "sqrmod", "sub", "submod"]; + for (let name of mpi_names) { + scheduleFuzzingRun(mpi_base, `MPI (${name})`, `mpi-${name}`, 4096, name); + } + scheduleFuzzingRun(mpi_base, `MPI (invmod)`, `mpi-invmod`, 256, "invmod"); + scheduleFuzzingRun(mpi_base, `MPI (expmod)`, `mpi-expmod`, 2048, "expmod"); + + // Schedule TLS fuzzing runs (non-fuzzing mode). + let tls_base = merge(run_base, {group: "TLS"}); + scheduleFuzzingRun(tls_base, "TLS Client", "tls-client", 20000, "client-nfm", + "tls-client-no_fuzzer_mode"); + scheduleFuzzingRun(tls_base, "TLS Server", "tls-server", 20000, "server-nfm", + "tls-server-no_fuzzer_mode"); + scheduleFuzzingRun(tls_base, "DTLS Client", "dtls-client", 20000, + "dtls-client-nfm", "dtls-client-no_fuzzer_mode"); + scheduleFuzzingRun(tls_base, "DTLS Server", "dtls-server", 20000, + "dtls-server-nfm", "dtls-server-no_fuzzer_mode"); + + // Schedule TLS fuzzing runs (fuzzing mode). + let tls_fm_base = merge(tls_base, {parent: task_build_tls}); + scheduleFuzzingRun(tls_fm_base, "TLS Client", "tls-client", 20000, "client"); + scheduleFuzzingRun(tls_fm_base, "TLS Server", "tls-server", 20000, "server"); + scheduleFuzzingRun(tls_fm_base, "DTLS Client", "dtls-client", 20000, "dtls-client"); + scheduleFuzzingRun(tls_fm_base, "DTLS Server", "dtls-server", 20000, "dtls-server"); + + return queue.submit(); +} + +async function scheduleFuzzing32() { + let base = { + env: { + ASAN_OPTIONS: "allocator_may_return_null=1:detect_stack_use_after_return=1", + UBSAN_OPTIONS: "print_stacktrace=1", + NSS_DISABLE_ARENA_FREE_LIST: "1", + NSS_DISABLE_UNLOAD: "1", + CC: "clang", + CCC: "clang++" + }, + features: ["allowPtrace"], + platform: "linux32", + collection: "fuzz", + image: FUZZ_IMAGE_32 + }; + + // Build base definition. + let build_base = merge(base, { + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && " + + "nss/automation/taskcluster/scripts/build_gyp.sh --fuzz -t ia32" + ], + artifacts: { + public: { + expires: 24 * 7, + type: "directory", + path: "/home/worker/artifacts" + } + }, + kind: "build", + symbol: "B" + }); + + // The task that builds NSPR+NSS. + let task_build = queue.scheduleTask(merge(build_base, { + name: "Linux 32 (debug, fuzz)" + })); + + // The task that builds NSPR+NSS (TLS fuzzing mode). + let task_build_tls = queue.scheduleTask(merge(build_base, { + name: "Linux 32 (debug, TLS fuzz)", + symbol: "B", + group: "TLS", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && " + + "nss/automation/taskcluster/scripts/build_gyp.sh --fuzz=tls -t ia32" + ], + })); + + // Schedule tests. + queue.scheduleTask(merge(base, { + parent: task_build_tls, + name: "Gtests", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/run_tests.sh" + ], + env: {GTESTFILTER: "*Fuzz*"}, + tests: "ssl_gtests gtests", + cycle: "standard", + symbol: "Gtest", + kind: "test" + })); + + // Schedule fuzzing runs. + let run_base = merge(base, {parent: task_build, kind: "test"}); + scheduleFuzzingRun(run_base, "CertDN", "certDN", 4096); + scheduleFuzzingRun(run_base, "QuickDER", "quickder", 10000); + + // Schedule MPI fuzzing runs. + let mpi_base = merge(run_base, {group: "MPI"}); + let mpi_names = ["add", "addmod", "div", "expmod", "mod", "mulmod", "sqr", + "sqrmod", "sub", "submod"]; + for (let name of mpi_names) { + scheduleFuzzingRun(mpi_base, `MPI (${name})`, `mpi-${name}`, 4096, name); + } + scheduleFuzzingRun(mpi_base, `MPI (invmod)`, `mpi-invmod`, 256, "invmod"); + + // Schedule TLS fuzzing runs (non-fuzzing mode). + let tls_base = merge(run_base, {group: "TLS"}); + scheduleFuzzingRun(tls_base, "TLS Client", "tls-client", 20000, "client-nfm", + "tls-client-no_fuzzer_mode"); + scheduleFuzzingRun(tls_base, "TLS Server", "tls-server", 20000, "server-nfm", + "tls-server-no_fuzzer_mode"); + scheduleFuzzingRun(tls_base, "DTLS Client", "dtls-client", 20000, + "dtls-client-nfm", "dtls-client-no_fuzzer_mode"); + scheduleFuzzingRun(tls_base, "DTLS Server", "dtls-server", 20000, + "dtls-server-nfm", "dtls-server-no_fuzzer_mode"); + + // Schedule TLS fuzzing runs (fuzzing mode). + let tls_fm_base = merge(tls_base, {parent: task_build_tls}); + scheduleFuzzingRun(tls_fm_base, "TLS Client", "tls-client", 20000, "client"); + scheduleFuzzingRun(tls_fm_base, "TLS Server", "tls-server", 20000, "server"); + scheduleFuzzingRun(tls_fm_base, "DTLS Client", "dtls-client", 20000, "dtls-client"); + scheduleFuzzingRun(tls_fm_base, "DTLS Server", "dtls-server", 20000, "dtls-server"); + + return queue.submit(); +} + +/*****************************************************************************/ + +async function scheduleWindows(name, base, build_script) { + base = merge(base, { + workerType: "win2012r2", + env: { + PATH: "c:\\mozilla-build\\bin;c:\\mozilla-build\\python;" + + "c:\\mozilla-build\\msys\\local\\bin;c:\\mozilla-build\\7zip;" + + "c:\\mozilla-build\\info-zip;c:\\mozilla-build\\python\\Scripts;" + + "c:\\mozilla-build\\yasm;c:\\mozilla-build\\msys\\bin;" + + "c:\\Windows\\system32;c:\\mozilla-build\\upx391w;" + + "c:\\mozilla-build\\moztools-x64\\bin;c:\\mozilla-build\\wget", + DOMSUF: "localdomain", + HOST: "localhost", + }, + features: ["taskclusterProxy"], + scopes: ["project:releng:services/tooltool/api/download/internal"], + }); + + let artifacts_and_kind = { + artifacts: [{ + expires: 24 * 7, + type: "directory", + path: "public\\build" + }], + kind: "build", + }; + + let build_without_command_symbol = merge(base, artifacts_and_kind); + + // Build base definition. + let build_base = merge(build_without_command_symbol, { + command: [ + WINDOWS_CHECKOUT_CMD, + `bash -c 'nss/automation/taskcluster/windows/${build_script}'` + ], + symbol: "B" + }); + + if (!("collection" in base) || + (base.collection != "make" && + base.collection != "asan" && + base.collection != "fips" && + base.collection != "fuzz")) { + let nspr_gyp = + `bash -c 'nss/automation/taskcluster/windows/${build_script} --nspr-only --nspr-test-build --nspr-test-run'`; + let nspr_build = merge(build_without_command_symbol, { + command: [ + WINDOWS_CHECKOUT_CMD, + nspr_gyp + ], + symbol: "NSPR" + }); + // The task that tests NSPR. + let task_build = queue.scheduleTask(merge(nspr_build, {name})); + } + + // Make builds run FIPS tests, which need an extra FIPS build. + if (base.collection == "make") { + let extra_build = queue.scheduleTask(merge(build_base, { + env: { NSS_FORCE_FIPS: "1" }, + group: "FIPS", + name: `${name} w/ NSS_FORCE_FIPS` + })); + + // The task that generates certificates. + let task_cert = queue.scheduleTask(merge(build_base, { + name: "Certificates", + command: [ + WINDOWS_CHECKOUT_CMD, + "bash -c nss/automation/taskcluster/windows/gen_certs.sh" + ], + parent: extra_build, + symbol: "Certs-F", + group: "FIPS", + })); + + // Schedule FIPS tests. + queue.scheduleTask(merge(base, { + parent: task_cert, + name: "FIPS", + command: [ + WINDOWS_CHECKOUT_CMD, + "bash -c nss/automation/taskcluster/windows/run_tests.sh" + ], + cycle: "standard", + kind: "test", + name: "FIPS tests", + symbol: "Tests-F", + tests: "fips", + group: "FIPS" + })); + } + + // The task that builds NSPR+NSS. + let task_build = queue.scheduleTask(merge(build_base, {name})); + + // The task that generates certificates. + let task_cert = queue.scheduleTask(merge(build_base, { + name: "Certificates", + command: [ + WINDOWS_CHECKOUT_CMD, + "bash -c nss/automation/taskcluster/windows/gen_certs.sh" + ], + parent: task_build, + symbol: "Certs" + })); + + // Schedule tests. + scheduleTests(task_build, task_cert, merge(base, { + command: [ + WINDOWS_CHECKOUT_CMD, + "bash -c nss/automation/taskcluster/windows/run_tests.sh" + ] + })); + + return queue.submit(); +} + +/*****************************************************************************/ + +function scheduleTests(task_build, task_cert, test_base) { + test_base = merge(test_base, {kind: "test"}); + let no_cert_base = merge(test_base, {parent: task_build}); + let cert_base = merge(test_base, {parent: task_cert}); + let cert_base_long = merge(cert_base, {maxRunTime: 7200}); + + // Schedule tests that do NOT need certificates. This is defined as + // the test itself not needing certs AND not running under the upgradedb + // cycle (which itself needs certs). If cycle is not defined, default is all. + queue.scheduleTask(merge(no_cert_base, { + name: "Gtests", symbol: "Gtest", tests: "ssl_gtests gtests", cycle: "standard" + })); + queue.scheduleTask(merge(no_cert_base, { + name: "Bogo tests", + symbol: "Bogo", + tests: "bogo", + cycle: "standard", + image: LINUX_INTEROP_IMAGE, + })); + queue.scheduleTask(merge(no_cert_base, { + name: "Interop tests", + symbol: "Interop", + tests: "interop", + cycle: "standard", + image: LINUX_INTEROP_IMAGE, + })); + queue.scheduleTask(merge(no_cert_base, { + name: "tlsfuzzer tests", symbol: "tlsfuzzer", tests: "tlsfuzzer", cycle: "standard" + })); + queue.scheduleTask(merge(no_cert_base, { + name: "MPI tests", symbol: "MPI", tests: "mpi", cycle: "standard" + })); + queue.scheduleTask(merge(cert_base, { + name: "Chains tests", symbol: "Chains", tests: "chains" + })); + queue.scheduleTask(merge(cert_base_long, { + name: "Cipher tests", symbol: "Default", tests: "cipher", group: "Cipher" + })); + queue.scheduleTask(merge(cert_base_long, { + name: "Cipher tests", symbol: "NoAES", tests: "cipher", + env: {NSS_DISABLE_HW_AES: "1"}, group: "Cipher" + })); + queue.scheduleTask(merge(cert_base_long, { + name: "Cipher tests", symbol: "NoSHA", tests: "cipher", + env: { + NSS_DISABLE_HW_SHA1: "1", + NSS_DISABLE_HW_SHA2: "1" + }, group: "Cipher" + })); + queue.scheduleTask(merge(cert_base_long, { + name: "Cipher tests", symbol: "NoPCLMUL", tests: "cipher", + env: {NSS_DISABLE_PCLMUL: "1"}, group: "Cipher" + })); + queue.scheduleTask(merge(cert_base_long, { + name: "Cipher tests", symbol: "NoAVX", tests: "cipher", + env: {NSS_DISABLE_AVX: "1"}, group: "Cipher" + })); + queue.scheduleTask(merge(cert_base_long, { + name: "Cipher tests", symbol: "NoAVX2", tests: "cipher", + env: {NSS_DISABLE_AVX2: "1"}, group: "Cipher" + })); + queue.scheduleTask(merge(cert_base_long, { + name: "Cipher tests", symbol: "NoSSSE3|NEON", tests: "cipher", + env: { + NSS_DISABLE_ARM_NEON: "1", + NSS_DISABLE_SSSE3: "1" + }, group: "Cipher" + })); + queue.scheduleTask(merge(cert_base_long, { + name: "Cipher tests", symbol: "NoSSE4.1", tests: "cipher", + env: {NSS_DISABLE_SSE4_1: "1"}, group: "Cipher" + })); + queue.scheduleTask(merge(cert_base, { + name: "EC tests", symbol: "EC", tests: "ec" + })); + queue.scheduleTask(merge(cert_base, { + name: "Lowhash tests", symbol: "Lowhash", tests: "lowhash" + })); + queue.scheduleTask(merge(cert_base, { + name: "SDR tests", symbol: "SDR", tests: "sdr" + })); + queue.scheduleTask(merge(cert_base, { + name: "Policy tests", symbol: "Policy", tests: "policy" + })); + + // Schedule tests that need certificates. + queue.scheduleTask(merge(cert_base, { + name: "CRMF tests", symbol: "CRMF", tests: "crmf" + })); + queue.scheduleTask(merge(cert_base, { + name: "DB tests", symbol: "DB", tests: "dbtests" + })); + queue.scheduleTask(merge(cert_base, { + name: "Merge tests", symbol: "Merge", tests: "merge" + })); + queue.scheduleTask(merge(cert_base, { + name: "S/MIME tests", symbol: "SMIME", tests: "smime" + })); + queue.scheduleTask(merge(cert_base, { + name: "Tools tests", symbol: "Tools", tests: "tools" + })); + + // SSL tests, need certificates too. + let ssl_base = merge(cert_base, {tests: "ssl", group: "SSL"}); + queue.scheduleTask(merge(ssl_base, { + name: "SSL tests (standard)", symbol: "standard", cycle: "standard" + })); + queue.scheduleTask(merge(ssl_base, { + name: "SSL tests (pkix)", symbol: "pkix", cycle: "pkix" + })); + queue.scheduleTask(merge(ssl_base, { + name: "SSL tests (stress)", symbol: "stress", cycle: "sharedb", + env: {NSS_SSL_RUN: "stress"} + })); +} + +/*****************************************************************************/ + +async function scheduleTools() { + let base = { + platform: "nss-tools", + kind: "test" + }; + + // ABI check task + queue.scheduleTask(merge(base, { + symbol: "abi", + name: "abi", + image: LINUX_BUILDS_IMAGE, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/check_abi.sh" + ], + })); + + queue.scheduleTask(merge(base, { + symbol: "clang-format", + name: "clang-format", + image: CLANG_FORMAT_IMAGE, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/clang-format/run_clang_format.sh" + ] + })); + + queue.scheduleTask(merge(base, { + symbol: "scan-build", + name: "scan-build", + image: FUZZ_IMAGE, + env: { + USE_64: "1", + CC: "clang", + CCC: "clang++", + }, + artifacts: { + public: { + expires: 24 * 7, + type: "directory", + path: "/home/worker/artifacts" + } + }, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/run_scan_build.sh" + ] + })); + + queue.scheduleTask(merge(base, { + symbol: "hacl", + name: "hacl", + image: LINUX_BUILDS_IMAGE, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/run_hacl.sh" + ] + })); + + queue.scheduleTask(merge(base, { + symbol: "Coverage", + name: "Coverage", + image: FUZZ_IMAGE, + type: "other", + features: ["allowPtrace"], + artifacts: { + public: { + expires: 24 * 7, + type: "directory", + path: "/home/worker/artifacts" + } + }, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/gen_coverage_report.sh" + ] + })); + + return queue.submit(); +} + +async function scheduleCodeReview() { + let tasks = queue.taggedTasks("code-review"); + if(! tasks) { + console.debug("No code review tasks, skipping ending task"); + return + } + + // From https://hg.mozilla.org/mozilla-central/file/tip/taskcluster/ci/code-review/kind.yml + queue.scheduleTask({ + platform: "nss-tools", + name: "code-review-issues", + description: "List all issues found in static analysis and linting tasks", + + // No logic on that task + image: LINUX_IMAGE, + command: ["/bin/true"], + + // This task must run after all analyzer tasks are completed + parents: tasks, + + // This option permits to run the task + // regardless of the analyzers tasks exit status + // as we are interested in the task failures + requires: "all-resolved", + + // Publish code review trigger on pulse + routes: ["project.relman.codereview.v1.try_ending"], + + kind: "code-review", + symbol: "E" + }); + + return queue.submit(); +}; diff --git a/security/nss/automation/taskcluster/graph/src/image_builder.js b/security/nss/automation/taskcluster/graph/src/image_builder.js new file mode 100644 index 0000000000..7bf632d29d --- /dev/null +++ b/security/nss/automation/taskcluster/graph/src/image_builder.js @@ -0,0 +1,61 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as queue from "./queue"; +import context_hash from "./context_hash"; +import taskcluster from "taskcluster-client"; + +async function taskHasImageArtifact(taskId) { + let queue = new taskcluster.Queue(taskcluster.fromEnvVars()); + let {artifacts} = await queue.listLatestArtifacts(taskId); + return artifacts.some(artifact => artifact.name == "public/image.tar.zst"); +} + +async function findTaskWithImageArtifact(ns) { + let index = new taskcluster.Index(taskcluster.fromEnvVars()); + let {taskId} = await index.findTask(ns); + let has_image = await taskHasImageArtifact(taskId); + return has_image ? taskId : null; +} + +export async function findTask({name, path}) { + let hash = await context_hash(path); + let ns = `docker.images.v1.${process.env.TC_PROJECT}.${name}.hash.${hash}`; + return findTaskWithImageArtifact(ns).catch(() => null); +} + +export async function buildTask({name, path}) { + let hash = await context_hash(path); + let ns = `docker.images.v1.${process.env.TC_PROJECT}.${name}.hash.${hash}`; + + return { + name: `Image Builder (${name})`, + image: "nssdev/image_builder:0.1.5", + routes: ["index." + ns], + env: { + NSS_HEAD_REPOSITORY: process.env.NSS_HEAD_REPOSITORY, + NSS_HEAD_REVISION: process.env.NSS_HEAD_REVISION, + PROJECT: process.env.TC_PROJECT, + CONTEXT_PATH: path, + HASH: hash + }, + artifacts: { + "public/image.tar.zst": { + type: "file", + expires: 24 * 90, + path: "/artifacts/image.tar.zst" + } + }, + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build_image.sh" + ], + platform: "nss-decision", + features: ["dind"], + maxRunTime: 7200, + kind: "build", + symbol: "I" + }; +} diff --git a/security/nss/automation/taskcluster/graph/src/index.js b/security/nss/automation/taskcluster/graph/src/index.js new file mode 100644 index 0000000000..78f4af8e48 --- /dev/null +++ b/security/nss/automation/taskcluster/graph/src/index.js @@ -0,0 +1,22 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as try_syntax from "./try_syntax"; +import * as queue from "./queue"; +import extend from "./extend"; + +const main = async () => { + // Init try syntax filter. + if (process.env.TC_PROJECT == "nss-try") { + await try_syntax.initFilter(); + } + + // Extend the task graph. + await extend(); +}; + +main().catch(err => { + console.error(err); + process.exit(1); +}); diff --git a/security/nss/automation/taskcluster/graph/src/merge.js b/security/nss/automation/taskcluster/graph/src/merge.js new file mode 100644 index 0000000000..17043dd8e4 --- /dev/null +++ b/security/nss/automation/taskcluster/graph/src/merge.js @@ -0,0 +1,10 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import {recursive as merge} from "merge"; + +// We always want to clone. +export default function (...args) { + return merge(true, ...args); +} diff --git a/security/nss/automation/taskcluster/graph/src/queue.js b/security/nss/automation/taskcluster/graph/src/queue.js new file mode 100644 index 0000000000..1baa604174 --- /dev/null +++ b/security/nss/automation/taskcluster/graph/src/queue.js @@ -0,0 +1,304 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import {clone} from "merge"; +import merge from "./merge"; +import slugid from "slugid"; +import taskcluster from "taskcluster-client"; +import * as image_builder from "./image_builder"; + +let maps = []; +let filters = []; + +let tasks = new Map(); +let tags = new Map(); +let image_tasks = new Map(); +let parameters = {}; + +let queue = new taskcluster.Queue({ + rootUrl: process.env.TASKCLUSTER_PROXY_URL, +}); + +function fromNow(hours) { + let d = new Date(); + d.setHours(d.getHours() + (hours|0)); + return d.toJSON(); +} + +function parseRoutes(routes) { + let rv = [ + `tc-treeherder.v2.${process.env.TC_PROJECT}.${process.env.NSS_HEAD_REVISION}.${process.env.NSS_PUSHLOG_ID}`, + ...routes + ]; + + // Notify about failures (except on try). + // Turned off, too noisy. + /*if (process.env.TC_PROJECT != "nss-try") { + rv.push(`notify.email.${process.env.TC_OWNER}.on-failed`, + `notify.email.${process.env.TC_OWNER}.on-exception`); + }*/ + + return rv; +} + +function parseFeatures(list) { + return list.reduce((map, feature) => { + map[feature] = true; + return map; + }, {}); +} + +function parseArtifacts(artifacts) { + let copy = clone(artifacts); + Object.keys(copy).forEach(key => { + copy[key].expires = fromNow(copy[key].expires); + }); + return copy; +} + +function parseCollection(name) { + let collection = {}; + collection[name] = true; + return collection; +} + +function parseTreeherder(def) { + let treeherder = { + build: { + platform: def.platform + }, + machine: { + platform: def.platform + }, + symbol: def.symbol, + jobKind: def.kind + }; + + if (def.group) { + treeherder.groupSymbol = def.group; + } + + if (def.collection) { + treeherder.collection = parseCollection(def.collection); + } + + if (def.tier) { + treeherder.tier = def.tier; + } + + return treeherder; +} + +function convertTask(def) { + let scopes = []; + let dependencies = []; + + let env = merge({ + NSS_HEAD_REPOSITORY: process.env.NSS_HEAD_REPOSITORY, + NSS_HEAD_REVISION: process.env.NSS_HEAD_REVISION, + NSS_MAX_MP_PBE_ITERATION_COUNT: "100", + }, def.env || {}); + + if (def.parent) { + dependencies.push(def.parent); + env.TC_PARENT_TASK_ID = def.parent; + } + if (def.parents) { + dependencies = dependencies.concat(def.parents); + } + + if (def.tests) { + env.NSS_TESTS = def.tests; + } + + if (def.cycle) { + env.NSS_CYCLES = def.cycle; + } + if (def.kind === "build") { + // Disable leak checking during builds (bug 1579290). + if (env.ASAN_OPTIONS) { + env.ASAN_OPTIONS += ":detect_leaks=0"; + } else { + env.ASAN_OPTIONS = "detect_leaks=0"; + } + } + + let payload = { + env, + command: def.command, + maxRunTime: def.maxRunTime || 3600 + }; + + if (def.image) { + payload.image = def.image; + } + + if (def.artifacts) { + payload.artifacts = parseArtifacts(def.artifacts); + } + + if (def.features) { + payload.features = parseFeatures(def.features); + + if (payload.features.allowPtrace) { + scopes.push("docker-worker:feature:allowPtrace"); + } + } + + if (def.scopes) { + // Need to add existing scopes in the task definition + scopes.push.apply(scopes, def.scopes) + } + + let extra = Object.assign({ + treeherder: parseTreeherder(def) + }, parameters); + + return { + provisionerId: def.provisioner || `nss-${process.env.MOZ_SCM_LEVEL}`, + workerType: def.workerType || "linux-gcp", + schedulerId: process.env.TC_SCHEDULER_ID, + taskGroupId: process.env.TASK_ID, + + scopes, + created: fromNow(0), + deadline: fromNow(24), + + dependencies, + requires: def.requires || "all-completed", + routes: parseRoutes(def.routes || []), + + metadata: { + name: def.name, + description: def.name, + owner: process.env.TC_OWNER, + source: process.env.TC_SOURCE + }, + + payload, + extra, + }; +} + +export function map(fun) { + maps.push(fun); +} + +export function filter(fun) { + filters.push(fun); +} + +export function addParameters(params) { + parameters = Object.assign(parameters, params); +} + +export function clearFilters(fun) { + filters = []; +} + +export function taggedTasks(tag) { + return tags[tag]; +} + +export function scheduleTask(def) { + let taskId = slugid.v4(); + tasks.set(taskId, merge({}, def)); + return taskId; +} + +export async function submit() { + let promises = new Map(); + + for (let [taskId, task] of tasks) { + // Allow filtering tasks before we schedule them. + if (!filters.every(filter => filter(task))) { + continue; + } + + // Allow changing tasks before we schedule them. + maps.forEach(map => { task = map(merge({}, task)) }); + + let log_id = `${task.name} @ ${task.platform}[${task.collection || "opt"}]`; + if (task.group) { + log_id = `${task.group}::${log_id}`; + } + console.log(`+ Submitting ${log_id}.`); + + // Index that task for each tag specified + if(task.tags) { + task.tags.map(tag => { + if(!tags[tag]) { + tags[tag] = []; + } + tags[tag].push(taskId); + }); + } + + let parent = task.parent; + + // Convert the task definition. + task = await convertTask(task); + + // Convert the docker image definition. + let image_def = task.payload.image; + if (image_def && image_def.hasOwnProperty("path")) { + let key = `${image_def.name}:${image_def.path}`; + let data = {}; + + // Check the cache first. + if (image_tasks.has(key)) { + data = image_tasks.get(key); + } else { + data.taskId = await image_builder.findTask(image_def); + data.isPending = !data.taskId; + + // No task found. + if (data.isPending) { + let image_task = await image_builder.buildTask(image_def); + + // Schedule a new image builder task immediately. + data.taskId = slugid.v4(); + + try { + await queue.createTask(data.taskId, convertTask(image_task)); + } catch (e) { + console.error("! FAIL: Scheduling image builder task failed."); + continue; /* Skip this task on failure. */ + } + } + + // Store in cache. + image_tasks.set(key, data); + } + + if (data.isPending) { + task.dependencies.push(data.taskId); + } + + task.payload.image = { + path: "public/image.tar.zst", + taskId: data.taskId, + type: "task-image" + }; + } + + // Wait for the parent task to be created before scheduling dependants. + let predecessor = parent ? promises.get(parent) : Promise.resolve(); + + promises.set(taskId, predecessor.then(() => { + // Schedule the task. + return queue.createTask(taskId, task).catch(err => { + console.error(`! FAIL: Scheduling ${log_id} failed.`, err); + }); + })); + } + + // Wait for all requests to finish. + if (promises.length) { + await Promise.all([...promises.values()]); + console.log("=== Total:", promises.length, "tasks. ==="); + } + + tasks.clear(); +} diff --git a/security/nss/automation/taskcluster/graph/src/try_syntax.js b/security/nss/automation/taskcluster/graph/src/try_syntax.js new file mode 100644 index 0000000000..4629ff4b26 --- /dev/null +++ b/security/nss/automation/taskcluster/graph/src/try_syntax.js @@ -0,0 +1,201 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as queue from "./queue"; +import path from 'path' +import fs from 'fs' +import intersect from "intersect"; +import parse_args from "minimist"; +import util from "util"; +import child_process from 'child_process'; + +let execFile = util.promisify(child_process.execFile); + +function parseOptions(opts) { + opts = parse_args(opts.split(/\s+/), { + default: {build: "do", platform: "all", unittests: "none", tools: "none"}, + alias: {b: "build", p: "platform", u: "unittests", t: "tools", e: "extra-builds"}, + string: ["build", "platform", "unittests", "tools", "extra-builds"] + }); + + // Parse build types (d=debug, o=opt). + let builds = intersect(opts.build.split(""), ["d", "o"]); + + // If the given value is nonsense default to debug and opt builds. + if (builds.length == 0) { + builds = ["d", "o"]; + } + + // Parse platforms. + let allPlatforms = ["linux", "linux64", "linux64-asan", "linux64-fips", + "win", "win64", "win-make", "win64-make", + "linux64-make", "linux-make", "linux-fuzz", + "linux64-fuzz", "aarch64", "aarch64-make", "mac"]; + let platforms = intersect(opts.platform.split(/\s*,\s*/), allPlatforms); + + // If the given value is nonsense or "none" default to all platforms. + if (platforms.length == 0 && opts.platform != "none") { + platforms = allPlatforms; + } + + // Parse unit tests. + let aliases = {"gtests": "gtest"}; + let allUnitTests = ["bogo", "crmf", "chains", "cipher", "db", "ec", "fips", + "gtest", "interop", "lowhash", "merge", "sdr", "smime", "tools", + "ssl", "mpi", "scert", "spki", "policy", "tlsfuzzer"]; + let unittests = intersect(opts.unittests.split(/\s*,\s*/).map(t => { + return aliases[t] || t; + }), allUnitTests); + + // If the given value is "all" run all tests. + // If it's nonsense then don't run any tests. + if (opts.unittests == "all") { + unittests = allUnitTests; + } else if (unittests.length == 0) { + unittests = []; + } + + // Parse tools. + let allTools = ["clang-format", "scan-build", "hacl", "saw", "abi", "coverage"]; + let tools = intersect(opts.tools.split(/\s*,\s*/), allTools); + + // If the given value is "all" run all tools. + // If it's nonsense then don't run any tools. + if (opts.tools == "all") { + tools = allTools; + } else if (tools.length == 0) { + tools = []; + } + + return { + builds: builds, + platforms: platforms, + unittests: unittests, + extra: (opts.e == "all"), + tools: tools + }; +} + +function filter(opts) { + return function (task) { + // Filter tools. We can immediately return here as those + // are not affected by platform or build type selectors. + if (task.platform == "nss-tools") { + return opts.tools.some(tool => { + return task.symbol.toLowerCase().startsWith(tool) || + (task.group && task.group.toLowerCase().startsWith(tool)); + }); + } + + // Filter unit tests. + if (task.tests) { + let found = opts.unittests.some(test => { + if (task.group && task.group.toLowerCase() == "ssl" && test == "ssl") { + return true; + } + if (task.group && task.group.toLowerCase() == "cipher" && test == "cipher") { + return true; + } + return task.symbol.toLowerCase().startsWith(test); + }); + + if (!found) { + return false; + } + } + + // Filter extra builds. + if (task.group == "Builds" && !opts.extra) { + return false; + } + + let coll = name => name == (task.collection || "opt"); + + // Filter by platform. + let found = opts.platforms.some(platform => { + let aliases = { + "aarch64-make": "aarch64", + "linux": "linux32", + "linux-fuzz": "linux32", + "linux64-asan": "linux64", + "linux64-fips": "linux64", + "linux64-fuzz": "linux64", + "linux64-make": "linux64", + "linux-make": "linux32", + "win64-make": "windows2012-64", + "win-make": "windows2012-32", + "win64": "windows2012-64", + "win": "windows2012-32" + }; + + // Check the platform name. + let keep = (task.platform == (aliases[platform] || platform)); + + // Additional checks. + if (platform == "linux64-asan") { + keep &= coll("asan"); + } else if (platform == "linux64-fips") { + keep &= coll("fips"); + } else if (platform == "linux64-make" || platform == "linux-make" || + platform == "win64-make" || platform == "win-make" || + platform == "aarch64-make") { + keep &= coll("make"); + } else if (platform == "linux64-fuzz" || platform == "linux-fuzz") { + keep &= coll("fuzz"); + } else { + keep &= coll("opt") || coll("debug"); + } + + return keep; + }); + + if (!found) { + return false; + } + + // Finally, filter by build type. + let isDebug = coll("debug") || coll("asan") || coll("make") || + coll("fuzz"); + return (isDebug && opts.builds.includes("d")) || + (!isDebug && opts.builds.includes("o")); + } +} + +async function getCommitComment() { + const res = await execFile('hg', ['log', '-r', '.', '-T', '{desc}']); + return res.stdout; +}; + +export async function initFilter() { + let comment = await getCommitComment(); + + // Load try_task_config.json + // Add parameters to queue for created tasks + let config_path = path.normalize(path.join(__dirname, '../../../../try_task_config.json')) + if (fs.existsSync(config_path)) { + var payload = JSON.parse(fs.readFileSync(config_path)); + if (payload['version'] == 2) { + queue.addParameters(payload['parameters']); + } + } + + // Check for try syntax in changeset comment. + let match = comment.match(/\btry:\s*(.*)\s*$/m); + + // Add try syntax filter. + if (match) { + let match1 = match[1]; + queue.filter(filter(parseOptions(match1))); + + if (match1.includes("--nspr-patch")) { + queue.map(task => { + if (!task.env) { + task.env = {}; + } + task.env.ALLOW_NSPR_PATCH = "1"; + return task; + }); + } + } +} diff --git a/security/nss/automation/taskcluster/image_builder/Dockerfile b/security/nss/automation/taskcluster/image_builder/Dockerfile new file mode 100644 index 0000000000..f8b4edcc53 --- /dev/null +++ b/security/nss/automation/taskcluster/image_builder/Dockerfile @@ -0,0 +1,23 @@ +FROM ubuntu:16.04 +MAINTAINER Tim Taubert <ttaubert@mozilla.com> + +WORKDIR /home/worker + +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update && apt-get install -y apt-transport-https apt-utils +RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9 && \ + sh -c "echo deb https://get.docker.io/ubuntu docker main \ + > /etc/apt/sources.list.d/docker.list" +RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 41BD8711B1F0EC2B0D85B91CF59CE3A8323293EE && \ + sh -c "echo deb http://ppa.launchpad.net/mercurial-ppa/releases/ubuntu xenial main \ + > /etc/apt/sources.list.d/mercurial.list" +RUN apt-get update && apt-get install -y \ + lxc-docker-1.6.1 \ + mercurial + +ADD bin /home/worker/bin +RUN chmod +x /home/worker/bin/* + +# Set a default command useful for debugging +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/image_builder/VERSION b/security/nss/automation/taskcluster/image_builder/VERSION new file mode 100644 index 0000000000..9faa1b7a73 --- /dev/null +++ b/security/nss/automation/taskcluster/image_builder/VERSION @@ -0,0 +1 @@ +0.1.5 diff --git a/security/nss/automation/taskcluster/image_builder/bin/checkout.sh b/security/nss/automation/taskcluster/image_builder/bin/checkout.sh new file mode 100644 index 0000000000..0cdd2ac405 --- /dev/null +++ b/security/nss/automation/taskcluster/image_builder/bin/checkout.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/scripts/build.sh b/security/nss/automation/taskcluster/scripts/build.sh new file mode 100755 index 0000000000..42ac822f28 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/build.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +source $(dirname "$0")/tools.sh + +if [ -n "$NSS_BUILD_MODULAR" ]; then + $(dirname "$0")/build_nspr.sh || exit $? + $(dirname "$0")/build_util.sh || exit $? + $(dirname "$0")/build_softoken.sh || exit $? + $(dirname "$0")/build_nss.sh || exit $? + exit +fi + +# Clone NSPR if needed. +hg_clone https://hg.mozilla.org/projects/nspr ./nspr default + +if [[ -f nss/nspr.patch && "$ALLOW_NSPR_PATCH" == "1" ]]; then + pushd nspr + cat ../nss/nspr.patch | patch -p1 + popd +fi + +# Build. +make -C nss nss_build_all + +# Package. +mkdir artifacts +tar cvfjh artifacts/dist.tar.bz2 dist diff --git a/security/nss/automation/taskcluster/scripts/build_gyp.sh b/security/nss/automation/taskcluster/scripts/build_gyp.sh new file mode 100755 index 0000000000..2cb0deb016 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/build_gyp.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +source $(dirname "$0")/tools.sh + +# Clone NSPR if needed. +hg_clone https://hg.mozilla.org/projects/nspr ./nspr default + +if [[ -f nss/nspr.patch && "$ALLOW_NSPR_PATCH" == "1" ]]; then + pushd nspr + cat ../nss/nspr.patch | patch -p1 + popd +fi + +# Build. +nss/build.sh -g -v --enable-libpkix -Denable_draft_hpke=1 "$@" + +# Package. +if [[ $(uname) = "Darwin" ]]; then + mkdir -p public + tar cvfjh public/dist.tar.bz2 dist +else + mkdir artifacts + tar cvfjh artifacts/dist.tar.bz2 dist +fi diff --git a/security/nss/automation/taskcluster/scripts/build_image.sh b/security/nss/automation/taskcluster/scripts/build_image.sh new file mode 100755 index 0000000000..3a469cf224 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/build_image.sh @@ -0,0 +1,27 @@ +#!/bin/bash -vex + +set -x -e -v + +# Prefix errors with taskcluster error prefix so that they are parsed by Treeherder +raise_error() { + echo + echo "[taskcluster-image-build:error] $1" + exit 1 +} + +# Ensure that the PROJECT is specified so the image can be indexed +test -n "$PROJECT" || raise_error "Project must be provided." +test -n "$HASH" || raise_error "Context Hash must be provided." + +CONTEXT_PATH="/home/worker/nss/$CONTEXT_PATH" + +test -d "$CONTEXT_PATH" || raise_error "Context Path $CONTEXT_PATH does not exist." +test -f "$CONTEXT_PATH/Dockerfile" || raise_error "Dockerfile must be present in $CONTEXT_PATH." + +apt-get update +apt-get -y install zstd + +docker build -t "$PROJECT:$HASH" "$CONTEXT_PATH" + +mkdir /artifacts +docker save "$PROJECT:$HASH" | zstd > /artifacts/image.tar.zst diff --git a/security/nss/automation/taskcluster/scripts/build_nspr.sh b/security/nss/automation/taskcluster/scripts/build_nspr.sh new file mode 100755 index 0000000000..b104e430a4 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/build_nspr.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +set -v -e -x + +source $(dirname $0)/tools.sh + +# Clone NSPR if needed. +hg_clone https://hg.mozilla.org/projects/nspr nspr default + +if [[ -f nss/nspr.patch && "$ALLOW_NSPR_PATCH" == "1" ]]; then + pushd nspr + cat ../nss/nspr.patch | patch -p1 + popd +fi + +# Build. +rm -rf dist +make -C nss build_nspr + +# Package. +test -d artifacts || mkdir artifacts +rm -rf dist-nspr +mv dist dist-nspr +tar cvfjh artifacts/dist-nspr.tar.bz2 dist-nspr diff --git a/security/nss/automation/taskcluster/scripts/build_nss.sh b/security/nss/automation/taskcluster/scripts/build_nss.sh new file mode 100755 index 0000000000..b909bc30ed --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/build_nss.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +set -v -e -x + +source $(dirname $0)/tools.sh +source $(dirname $0)/split.sh + +test -d dist-softoken || { echo "run build_softoken.sh first" 1>&2; exit 1; } + +rm -rf nss-nss +split_nss nss nss-nss + +# Build. +export NSS_BUILD_WITHOUT_SOFTOKEN=1 +export NSS_USE_SYSTEM_FREEBL=1 + +platform=`make -s -C nss platform` + +export NSPR_LIB_DIR="$PWD/dist-nspr/$platform/lib" +export NSSUTIL_LIB_DIR="$PWD/dist-util/$platform/lib" +export FREEBL_LIB_DIR="$PWD/dist-softoken/$platform/lib" +export SOFTOKEN_LIB_DIR="$PWD/dist-softoken/$platform/lib" +export FREEBL_LIBS=-lfreebl + +export NSS_NO_PKCS11_BYPASS=1 +export FREEBL_NO_DEPEND=1 + +export LIBRARY_PATH="$PWD/dist-nspr/$platform/lib:$PWD/dist-util/$platform/lib:$PWD/dist-softoken/$platform/lib" +export LD_LIBRARY_PATH="$LIBRARY_PATH:$LD_LIBRARY_PATH" +export INCLUDES="-I$PWD/dist-nspr/$platform/include -I$PWD/dist-util/public/nss -I$PWD/dist-softoken/public/nss" + +rm -rf dist +make -C nss-nss nss_build_all + +# Package. +test -d artifacts || mkdir artifacts +rm -rf dist-nss +mv dist dist-nss +tar cvfjh artifacts/dist-nss.tar.bz2 dist-nss diff --git a/security/nss/automation/taskcluster/scripts/build_softoken.sh b/security/nss/automation/taskcluster/scripts/build_softoken.sh new file mode 100755 index 0000000000..5f60456022 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/build_softoken.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +set -v -e -x + +source $(dirname $0)/tools.sh +source $(dirname $0)/split.sh + +test -d dist-util || { echo "run build_util.sh first" 1>&2; exit 1; } + +rm -rf nss-softoken +split_softoken nss nss-softoken + +# Build. +platform=`make -s -C nss platform` +export LIBRARY_PATH="$PWD/dist-nspr/$platform/lib:$PWD/dist-util/$platform/lib" +export LD_LIBRARY_PATH="$LIBRARY_PATH:$LD_LIBRARY_PATH" +export INCLUDES="-I$PWD/dist-nspr/$platform/include -I$PWD/dist-util/public/nss" +export NSS_BUILD_SOFTOKEN_ONLY=1 + +rm -rf dist +make -C nss-softoken nss_build_all + +for i in blapi alghmac cmac; do + mv "dist/private/nss/${i}.h" dist/public/nss +done + +# Package. +test -d artifacts || mkdir artifacts +rm -rf dist-softoken +mv dist dist-softoken +tar cvfjh artifacts/dist-softoken.tar.bz2 dist-softoken diff --git a/security/nss/automation/taskcluster/scripts/build_util.sh b/security/nss/automation/taskcluster/scripts/build_util.sh new file mode 100755 index 0000000000..0d2ecc5e87 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/build_util.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -v -e -x + +source $(dirname $0)/tools.sh +source $(dirname $0)/split.sh + +rm -rf nss-util +split_util nss nss-util + +# Build. +platform=`make -s -C nss platform` +export LIBRARY_PATH="$PWD/dist-nspr/$platform/lib" +export LD_LIBRARY_PATH="$LIBRARY_PATH:$LD_LIBRARY_PATH" +export INCLUDES="-I$PWD/dist-nspr/$platform/include" +export NSS_BUILD_UTIL_ONLY=1 + +rm -rf dist +make -C nss-util nss_build_all + +# Package. +test -d artifacts || mkdir artifacts +rm -rf dist-util +mv dist dist-util +tar cvfjh artifacts/dist-util.tar.bz2 dist-util diff --git a/security/nss/automation/taskcluster/scripts/check_abi.sh b/security/nss/automation/taskcluster/scripts/check_abi.sh new file mode 100755 index 0000000000..0bd8d9693b --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/check_abi.sh @@ -0,0 +1,180 @@ +#! /bin/bash + +set_env() +{ + cd /home/worker + HGDIR=/home/worker + OUTPUTDIR=$(pwd)$(echo "/output") + DATE=$(date "+TB [%Y-%m-%d %H:%M:%S]") + + if [ ! -d "${OUTPUTDIR}" ]; then + echo "Creating output dir" + mkdir "${OUTPUTDIR}" + fi + + if [ ! -d "nspr" ]; then + for i in 0 2 5; do + sleep $i + hg clone -r "default" "https://hg.mozilla.org/projects/nspr" "${HGDIR}/nspr" && break + rm -rf nspr + done + fi + + if [[ -f nss/nspr.patch && "$ALLOW_NSPR_PATCH" == "1" ]]; then + pushd nspr + cat ../nss/nspr.patch | patch -p1 + popd + fi + + cd nss + ./build.sh -v -c + cd .. +} + +check_abi() +{ + set_env + set +e #reverses set -e from build.sh to allow possible hg clone failures + if [[ "$1" != --nobuild ]]; then # Start nobuild block + + echo "######## NSS ABI CHECK ########" + echo "######## creating temporary HG clones ########" + + rm -rf ${HGDIR}/baseline + mkdir ${HGDIR}/baseline + BASE_NSS=`cat ${HGDIR}/nss/automation/abi-check/previous-nss-release` #Reads the version number of the last release from the respective file + NSS_CLONE_RESULT=0 + for i in 0 2 5; do + sleep $i + hg clone -u "${BASE_NSS}" "https://hg.mozilla.org/projects/nss" "${HGDIR}/baseline/nss" + if [ $? -eq 0 ]; then + NSS_CLONE_RESULT=0 + break + fi + rm -rf "${HGDIR}/baseline/nss" + NSS_CLONE_RESULT=1 + done + if [ ${NSS_CLONE_RESULT} -ne 0 ]; then + echo "invalid tag in automation/abi-check/previous-nss-release" + return 1 + fi + + BASE_NSPR=NSPR_$(head -1 ${HGDIR}/baseline/nss/automation/release/nspr-version.txt | cut -d . -f 1-2 | tr . _)_BRANCH + hg clone -u "${BASE_NSPR}" "https://hg.mozilla.org/projects/nspr" "${HGDIR}/baseline/nspr" + NSPR_CLONE_RESULT=$? + + if [ ${NSPR_CLONE_RESULT} -ne 0 ]; then + rm -rf "${HGDIR}/baseline/nspr" + for i in 0 2 5; do + sleep $i + hg clone -u "default" "https://hg.mozilla.org/projects/nspr" "${HGDIR}/baseline/nspr" && break + rm -rf "${HGDIR}/baseline/nspr" + done + echo "Nonexisting tag ${BASE_NSPR} derived from ${BASE_NSS} automation/release/nspr-version.txt" + echo "Using default branch instead." + fi + + echo "######## building baseline NSPR/NSS ########" + echo "${HGDIR}/baseline/nss/build.sh" + cd ${HGDIR}/baseline/nss + ./build.sh -v -c + cd ${HGDIR} + else # Else nobuild block + echo "######## using existing baseline NSPR/NSS build ########" + fi # End nobuild block + + set +e #reverses set -e from build.sh to allow abidiff failures + + echo "######## Starting abidiff procedure ########" + abi_diff +} + +#Slightly modified from build.sh in this directory +abi_diff() +{ + ABI_PROBLEM_FOUND=0 + ABI_REPORT=${OUTPUTDIR}/abi-diff.txt + rm -f ${ABI_REPORT} + PREVDIST=${HGDIR}/baseline/dist + NEWDIST=${HGDIR}/dist + # libnssdbm3.so isn't built by default anymore, skip it. + ALL_SOs="libfreebl3.so libfreeblpriv3.so libnspr4.so libnss3.so libnssckbi.so libnsssysinit.so libnssutil3.so libplc4.so libplds4.so libsmime3.so libsoftokn3.so libssl3.so" + for SO in ${ALL_SOs}; do + if [ ! -f ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt ]; then + touch ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt + fi + abidiff --hd1 $PREVDIST/public/ --hd2 $NEWDIST/public \ + $PREVDIST/*/lib/$SO $NEWDIST/*/lib/$SO \ + > ${HGDIR}/nss/automation/abi-check/new-report-temp$SO.txt + RET=$? + cat ${HGDIR}/nss/automation/abi-check/new-report-temp$SO.txt \ + | grep -v "^Functions changes summary:" \ + | grep -v "^Variables changes summary:" \ + | sed -e 's/__anonymous_enum__[0-9]*/__anonymous_enum__/g' \ + > ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt + rm -f ${HGDIR}/nss/automation/abi-check/new-report-temp$SO.txt + + ABIDIFF_ERROR=$((($RET & 0x01) != 0)) + ABIDIFF_USAGE_ERROR=$((($RET & 0x02) != 0)) + ABIDIFF_ABI_CHANGE=$((($RET & 0x04) != 0)) + ABIDIFF_ABI_INCOMPATIBLE_CHANGE=$((($RET & 0x08) != 0)) + ABIDIFF_UNKNOWN_BIT_SET=$((($RET & 0xf0) != 0)) + + # If abidiff reports an error, or a usage error, or if it sets a result + # bit value this script doesn't know yet about, we'll report failure. + # For ABI changes, we don't yet report an error. We'll compare the + # result report with our allowlist. This allows us to silence changes + # that we're already aware of and have been declared acceptable. + + REPORT_RET_AS_FAILURE=0 + if [ $ABIDIFF_ERROR -ne 0 ]; then + echo "abidiff reported ABIDIFF_ERROR." + REPORT_RET_AS_FAILURE=1 + fi + if [ $ABIDIFF_USAGE_ERROR -ne 0 ]; then + echo "abidiff reported ABIDIFF_USAGE_ERROR." + REPORT_RET_AS_FAILURE=1 + fi + if [ $ABIDIFF_UNKNOWN_BIT_SET -ne 0 ]; then + echo "abidiff reported ABIDIFF_UNKNOWN_BIT_SET." + REPORT_RET_AS_FAILURE=1 + fi + + if [ $ABIDIFF_ABI_CHANGE -ne 0 ]; then + echo "Ignoring abidiff result ABI_CHANGE, instead we'll check for non-allowlisted differences." + fi + if [ $ABIDIFF_ABI_INCOMPATIBLE_CHANGE -ne 0 ]; then + echo "Ignoring abidiff result ABIDIFF_ABI_INCOMPATIBLE_CHANGE, instead we'll check for non-allowlisted differences." + fi + + if [ $REPORT_RET_AS_FAILURE -ne 0 ]; then + ABI_PROBLEM_FOUND=1 + echo "abidiff {$PREVDIST , $NEWDIST} for $SO FAILED with result $RET, or failed writing to ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt" + fi + if [ ! -f ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt ]; then + ABI_PROBLEM_FOUND=1 + echo "FAILED to access report file: ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt" + fi + + diff -wB -u ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt \ + ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt >> ${ABI_REPORT} + if [ ! -f ${ABI_REPORT} ]; then + ABI_PROBLEM_FOUND=1 + echo "FAILED to compare exepcted and new report: ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt" + fi + done + + if [ -s ${ABI_REPORT} ]; then + echo "FAILED: there are new unexpected ABI changes" + cat ${ABI_REPORT} + return 1 + elif [ $ABI_PROBLEM_FOUND -ne 0 ]; then + echo "FAILED: failure executing the ABI checks" + cat ${ABI_REPORT} + return 1 + fi + + return 0 +} + +check_abi $1 diff --git a/security/nss/automation/taskcluster/scripts/extend_task_graph.sh b/security/nss/automation/taskcluster/scripts/extend_task_graph.sh new file mode 100755 index 0000000000..ade84cd602 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/extend_task_graph.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +source $(dirname "$0")/tools.sh + +mkdir -p /home/worker/artifacts + +# Install Node.JS dependencies. +cd nss/automation/taskcluster/graph/ && npm install + +# Extend the task graph. +node lib/index.js diff --git a/security/nss/automation/taskcluster/scripts/fuzz.sh b/security/nss/automation/taskcluster/scripts/fuzz.sh new file mode 100755 index 0000000000..75851ff5b9 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/fuzz.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +source $(dirname "$0")/tools.sh + +type="$1" +shift + +# Fetch artifact if needed. +fetch_dist + +# Clone corpus. +./nss/fuzz/config/clone_corpus.sh + +# Ensure we have a corpus. +if [ ! -d "nss/fuzz/corpus/$type" ]; then + mkdir -p nss/fuzz/corpus/$type + + set +x + + # Create a corpus out of what we have. + for f in $(find nss/fuzz/corpus -type f); do + cp $f "nss/fuzz/corpus/$type" + done + + set -x +fi + +# Fetch objdir name. +objdir=$(cat dist/latest) + +# Run nssfuzz. +dist/$objdir/bin/nssfuzz-"$type" "$@" diff --git a/security/nss/automation/taskcluster/scripts/gen_certs.sh b/security/nss/automation/taskcluster/scripts/gen_certs.sh new file mode 100755 index 0000000000..c03db7e9c2 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/gen_certs.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +source $(dirname "$0")/tools.sh + +# Fetch artifact if needed. +fetch_dist + +# Generate certificates. +NSS_TESTS=cert NSS_CYCLES="standard pkix sharedb" $(dirname $0)/run_tests.sh + +# Reset test counter so that test runs pick up our certificates. +echo 1 > tests_results/security/localhost + +# Package. +if [[ $(uname) = "Darwin" ]]; then + mkdir -p public + tar cvfjh public/dist.tar.bz2 dist tests_results +else + mkdir artifacts + tar cvfjh artifacts/dist.tar.bz2 dist tests_results +fi diff --git a/security/nss/automation/taskcluster/scripts/gen_coverage_report.sh b/security/nss/automation/taskcluster/scripts/gen_coverage_report.sh new file mode 100755 index 0000000000..dc7d77d6c1 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/gen_coverage_report.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +source $(dirname "$0")/tools.sh + +# Clone NSPR. +hg_clone https://hg.mozilla.org/projects/nspr ./nspr default + +if [[ -f nss/nspr.patch && "$ALLOW_NSPR_PATCH" == "1" ]]; then + pushd nspr + cat ../nss/nspr.patch | patch -p1 + popd +fi + +out=/home/worker/artifacts +mkdir -p $out + +# Generate coverage report. +cd nss && ./mach coverage --outdir=$out ssl_gtests diff --git a/security/nss/automation/taskcluster/scripts/run_hacl.sh b/security/nss/automation/taskcluster/scripts/run_hacl.sh new file mode 100755 index 0000000000..7b82c911bf --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/run_hacl.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +if [[ $(id -u) -eq 0 ]]; then + # Drop privileges by re-running this script. + # Note: this mangles arguments, better to avoid running scripts as root. + exec su worker -c "$0 $*" +fi + +set -e -x -v + +# The docker image this is running in has NSS sources. +# Get the HACL* source, containing a snapshot of the C code, extracted on the +# HACL CI. +# When bug 1593647 is resolved, extract the code on CI again. +git clone -q "https://github.com/project-everest/hacl-star" ~/hacl-star +git -C ~/hacl-star checkout -q c95ab70fcb2bc21025d8845281bc4bc8987ca683 + +# Format the C snapshot. +cd ~/hacl-star/dist/mozilla +cp ~/nss/.clang-format . +find . -type f -name '*.[ch]' -exec clang-format -i {} \+ +cd ~/hacl-star/dist/kremlin +cp ~/nss/.clang-format . +find . -type f -name '*.[ch]' -exec clang-format -i {} \+ + +# These diff commands will return 1 if there are differences and stop the script. +files=($(find ~/nss/lib/freebl/verified/ -type f -name '*.[ch]')) +for f in "${files[@]}"; do + file_name=$(basename "$f") + hacl_file=($(find ~/hacl-star/dist/mozilla/ ~/hacl-star/dist/kremlin/ -type f -name $file_name)) + diff $hacl_file $f +done diff --git a/security/nss/automation/taskcluster/scripts/run_scan_build.sh b/security/nss/automation/taskcluster/scripts/run_scan_build.sh new file mode 100755 index 0000000000..0e4fcbdf0d --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/run_scan_build.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +source $(dirname "$0")/tools.sh + +# Clone NSPR if needed. +if [ ! -d "nspr" ]; then + hg_clone https://hg.mozilla.org/projects/nspr ./nspr default + + if [[ -f nss/nspr.patch && "$ALLOW_NSPR_PATCH" == "1" ]]; then + pushd nspr + cat ../nss/nspr.patch | patch -p1 + popd + fi +fi + +# Build. +cd nss +make nss_build_all + +# What we want to scan. +# key: directory to scan +# value: number of errors expected in that directory +declare -A scan=( \ + [lib/base]=0 \ + [lib/certdb]=0 \ + [lib/certhigh]=0 \ + [lib/ckfw]=0 \ + [lib/crmf]=0 \ + [lib/cryptohi]=0 \ + [lib/dev]=0 \ + [lib/freebl]=0 \ + [lib/nss]=0 \ + [lib/ssl]=0 \ + [lib/util]=0 \ + ) + +# remove .OBJ directories to force a rebuild of just the select few +for i in "${!scan[@]}"; do + find "$i" -name "*.OBJ" -exec rm -rf {} \+ +done + +# run scan-build (only building affected directories) +scan-build-5.0 -o /home/worker/artifacts --use-cc=$CC --use-c++=$CCC make nss_build_all && cd .. + +# print errors we found +set +v +x +STATUS=0 +for i in "${!scan[@]}"; do + n=$(grep -Rn "$i" /home/worker/artifacts/*/report-*.html | wc -l) + if [ $n -ne ${scan[$i]} ]; then + STATUS=1 + echo "$(date '+%T') WARNING - TEST-UNEXPECTED-FAIL: $i contains $n scan-build errors" + elif [ $n -ne 0 ]; then + echo "$(date '+%T') WARNING - TEST-EXPECTED-FAIL: $i contains $n scan-build errors" + fi +done +exit $STATUS diff --git a/security/nss/automation/taskcluster/scripts/run_tests.sh b/security/nss/automation/taskcluster/scripts/run_tests.sh new file mode 100755 index 0000000000..b8e26761a9 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/run_tests.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +source $(dirname "$0")/tools.sh + +# Fetch artifact if needed. +fetch_dist + +# Run tests. +cd nss/tests && ./all.sh diff --git a/security/nss/automation/taskcluster/scripts/split.sh b/security/nss/automation/taskcluster/scripts/split.sh new file mode 100644 index 0000000000..d4ed4cc007 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/split.sh @@ -0,0 +1,147 @@ +copy_top() +{ + srcdir_="$1" + dstdir_="$2" + files=`find "$srcdir_" -maxdepth 1 -mindepth 1 -type f` + for f in $files; do + cp -p "$f" "$dstdir_" + done +} + +split_util() { + nssdir="$1" + dstdir="$2" + + # Prepare a source tree only containing files to build nss-util: + # + # nss/dbm full directory + # nss/coreconf full directory + # nss top files only + # nss/lib top files only + # nss/lib/util full directory + + # Copy everything. + cp -R $nssdir $dstdir + + # Remove subdirectories that we don't want. + rm -rf $dstdir/cmd + rm -rf $dstdir/lib + rm -rf $dstdir/automation + rm -rf $dstdir/doc + + # Start with an empty cmd lib directories to be filled selectively. + mkdir $dstdir/cmd + cp $nssdir/cmd/Makefile $dstdir/cmd + cp $nssdir/cmd/manifest.mn $dstdir/cmd + cp $nssdir/cmd/platlibs.mk $dstdir/cmd + cp $nssdir/cmd/platrules.mk $dstdir/cmd + + # Copy some files at the top and the util subdirectory recursively. + mkdir $dstdir/lib + cp $nssdir/lib/Makefile $dstdir/lib + cp -R $nssdir/lib/util $dstdir/lib/util +} + +split_softoken() { + nssdir="$1" + dstdir="$2" + + # Prepare a source tree only containing files to build nss-softoken: + # + # nss/dbm full directory + # nss/coreconf full directory + # nss top files only + # nss/lib top files only + # nss/lib/freebl full directory + # nss/lib/softoken full directory + # nss/lib/softoken/dbm full directory + + # Copy everything. + cp -R $nssdir $dstdir + + # Skip gtests when building. + sed '/^DIRS = /s/ cpputil gtests$//' $nssdir/manifest.mn > $dstdir/manifest.mn-t && mv $dstdir/manifest.mn-t $dstdir/manifest.mn + + # Remove subdirectories that we don't want. + rm -rf $dstdir/cmd + rm -rf $dstdir/tests + rm -rf $dstdir/lib + rm -rf $dstdir/pkg + rm -rf $dstdir/automation + rm -rf $dstdir/gtests + rm -rf $dstdir/cpputil + rm -rf $dstdir/doc + + # Start with an empty lib directory and copy only what we need. + mkdir $dstdir/lib + copy_top $nssdir/lib $dstdir/lib + cp -R $nssdir/lib/dbm $dstdir/lib/dbm + cp -R $nssdir/lib/freebl $dstdir/lib/freebl + cp -R $nssdir/lib/softoken $dstdir/lib/softoken + cp -R $nssdir/lib/sqlite $dstdir/lib/sqlite + + mkdir $dstdir/cmd + copy_top $nssdir/cmd $dstdir/cmd + cp -R $nssdir/cmd/bltest $dstdir/cmd/bltest + cp -R $nssdir/cmd/ecperf $dstdir/cmd/ecperf + cp -R $nssdir/cmd/fbectest $dstdir/cmd/fbectest + cp -R $nssdir/cmd/fipstest $dstdir/cmd/fipstest + cp -R $nssdir/cmd/lib $dstdir/cmd/lib + cp -R $nssdir/cmd/lowhashtest $dstdir/cmd/lowhashtest + cp -R $nssdir/cmd/shlibsign $dstdir/cmd/shlibsign + + mkdir $dstdir/tests + copy_top $nssdir/tests $dstdir/tests + + cp -R $nssdir/tests/cipher $dstdir/tests/cipher + cp -R $nssdir/tests/common $dstdir/tests/common + cp -R $nssdir/tests/ec $dstdir/tests/ec + cp -R $nssdir/tests/lowhash $dstdir/tests/lowhash + + cp $nssdir/lib/util/verref.h $dstdir/lib/freebl + cp $nssdir/lib/util/verref.h $dstdir/lib/softoken + cp $nssdir/lib/util/verref.h $dstdir/lib/softoken/legacydb +} + +split_nss() { + nssdir="$1" + dstdir="$2" + + # Prepare a source tree only containing files to build nss: + # + # nss/dbm full directory + # nss/coreconf full directory + # nss top files only + # nss/lib top files only + # nss/lib/freebl full directory + # nss/lib/softoken full directory + # nss/lib/softoken/dbm full directory + + # Copy everything. + cp -R $nssdir $dstdir + + # Remove subdirectories that we don't want. + rm -rf $dstdir/lib/freebl + rm -rf $dstdir/lib/softoken + rm -rf $dstdir/lib/util + rm -rf $dstdir/cmd/bltest + rm -rf $dstdir/cmd/fipstest + rm -rf $dstdir/cmd/rsaperf_low + + # Copy these headers until the upstream bug is accepted + # Upstream https://bugzilla.mozilla.org/show_bug.cgi?id=820207 + cp $nssdir/lib/softoken/lowkeyi.h $dstdir/cmd/rsaperf + cp $nssdir/lib/softoken/lowkeyti.h $dstdir/cmd/rsaperf + + # Copy verref.h which will be needed later during the build phase. + cp $nssdir/lib/util/verref.h $dstdir/lib/ckfw/builtins/verref.h + cp $nssdir/lib/util/verref.h $dstdir/lib/nss/verref.h + cp $nssdir/lib/util/verref.h $dstdir/lib/smime/verref.h + cp $nssdir/lib/util/verref.h $dstdir/lib/ssl/verref.h + cp $nssdir/lib/util/templates.c $dstdir/lib/nss/templates.c + + # FIXME: Skip util_gtest because it links with libnssutil.a. Note + # that we can't use libnssutil3.so instead, because util_gtest + # depends on internal symbols not exported from the shared library. + sed '/ util_gtest \\/d' $dstdir/gtests/manifest.mn > $dstdir/gtests/manifest.mn-t && mv $dstdir/gtests/manifest.mn-t $dstdir/gtests/manifest.mn +} diff --git a/security/nss/automation/taskcluster/scripts/tools.sh b/security/nss/automation/taskcluster/scripts/tools.sh new file mode 100644 index 0000000000..81563f5066 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/tools.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Assert that we're not running as root. +if [[ $(id -u) -eq 0 ]]; then + # This exec is still needed until aarch64 images are updated (Bug 1488325). + # Remove when images are updated. Until then, assert that things are good. + [[ $(uname -m) == aarch64 ]] + exec su worker -c "$0 $*" +fi + +export PATH="${PATH}:/home/worker/.cargo/bin/:/usr/lib/go-1.6/bin" + +# Usage: hg_clone repo dir [revision=@] +hg_clone() { + repo=$1 + dir=$2 + rev=${3:-@} + if [ -d "$dir" ]; then + hg pull -R "$dir" -ur "$rev" "$repo" && return + rm -rf "$dir" + fi + for i in 0 2 5; do + sleep $i + hg clone -r "$rev" "$repo" "$dir" && return + rm -rf "$dir" + done + exit 1 +} + +fetch_dist() { + if [ "$TASKCLUSTER_ROOT_URL" = "https://taskcluster.net" ] || [ -z "$TASKCLUSTER_ROOT_URL" ]; then + url=https://queue.taskcluster.net/v1/task/$TC_PARENT_TASK_ID/artifacts/public/dist.tar.bz2 + else + url=$TASKCLUSTER_ROOT_URL/api/queue/v1/task/$TC_PARENT_TASK_ID/artifacts/public/dist.tar.bz2 + fi + if [ ! -d "dist" ]; then + for i in 0 2 5; do + sleep $i + curl --retry 3 -Lo dist.tar.bz2 $url && tar xvjf dist.tar.bz2 && return + rm -fr dist.tar.bz2 dist + done + exit 1 + fi +} diff --git a/security/nss/automation/taskcluster/windows/build.sh b/security/nss/automation/taskcluster/windows/build.sh new file mode 100644 index 0000000000..f878a3d0d7 --- /dev/null +++ b/security/nss/automation/taskcluster/windows/build.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -v -e -x + +if [[ "$USE_64" == 1 ]]; then + m=x64 +else + m=x86 +fi +source "$(dirname "$0")/setup.sh" + +# Clone NSPR. +hg_clone https://hg.mozilla.org/projects/nspr nspr default + +if [[ -f nss/nspr.patch && "$ALLOW_NSPR_PATCH" == "1" ]]; then + pushd nspr + cat ../nss/nspr.patch | patch -p1 + popd +fi + +# Build. +make -C nss nss_build_all + +# Package. +7z a public/build/dist.7z dist diff --git a/security/nss/automation/taskcluster/windows/build_gyp.sh b/security/nss/automation/taskcluster/windows/build_gyp.sh new file mode 100644 index 0000000000..d7072ebbf2 --- /dev/null +++ b/security/nss/automation/taskcluster/windows/build_gyp.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Parse for the -t option. +m=x64 +for i in "$@"; do + case "$i" in + -t|--target) m= ;; + --target=*) m="${i#*=}" ;; + *) [[ -z "$m" ]] && m="$i" ;; + esac +done +[[ "$m" == "ia32" ]] && m=x86 +source "$(dirname "$0")/setup.sh" + +# Install GYP. +pushd gyp +python -m virtualenv test-env +test-env/Scripts/python setup.py install +test-env/Scripts/python -m pip install --upgrade pip +test-env/Scripts/pip install --upgrade 'setuptools<45.0.0' +# Fool GYP. +touch "${VSPATH}/VC/vcvarsall.bat" +export GYP_MSVS_OVERRIDE_PATH="${VSPATH}" +export GYP_MSVS_VERSION=2015 +popd + +export PATH="${PATH}:${PWD}/ninja/bin:${PWD}/gyp/test-env/Scripts" + +# Clone NSPR. +hg_clone https://hg.mozilla.org/projects/nspr nspr default + +if [[ -f nss/nspr.patch && "$ALLOW_NSPR_PATCH" == "1" ]]; then + pushd nspr + cat ../nss/nspr.patch | patch -p1 + popd +fi + +# Build with gyp. +./nss/build.sh -g -v --enable-libpkix -Denable_draft_hpke=1 "$@" + +# Package. +7z a public/build/dist.7z dist diff --git a/security/nss/automation/taskcluster/windows/gen_certs.sh b/security/nss/automation/taskcluster/windows/gen_certs.sh new file mode 100644 index 0000000000..594112b98f --- /dev/null +++ b/security/nss/automation/taskcluster/windows/gen_certs.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Set up the toolchain. +source $(dirname $0)/setup.sh + +# Fetch artifact. +if [ "$TASKCLUSTER_ROOT_URL" = "https://taskcluster.net" ] || [ -z "$TASKCLUSTER_ROOT_URL" ]; then + url=https://queue.taskcluster.net/v1/task/$TC_PARENT_TASK_ID/artifacts/public/build/dist.7z +else + url=$TASKCLUSTER_ROOT_URL/api/queue/v1/task/$TC_PARENT_TASK_ID/artifacts/public/build/dist.7z +fi + +wget -t 3 --retry-connrefused -w 5 --random-wait $url -O dist.7z +7z x dist.7z + +# Generate certificates. +NSS_TESTS=cert NSS_CYCLES="standard pkix sharedb" nss/tests/all.sh + +# Reset test counter so that test runs pick up our certificates. +echo 1 > tests_results/security/localhost + +# Package. +7z a public/build/dist.7z dist tests_results diff --git a/security/nss/automation/taskcluster/windows/releng.manifest b/security/nss/automation/taskcluster/windows/releng.manifest new file mode 100644 index 0000000000..d571c544d6 --- /dev/null +++ b/security/nss/automation/taskcluster/windows/releng.manifest @@ -0,0 +1,26 @@ +[ + { + "version": "Visual Studio 2017 15.4.2 / SDK 10.0.15063.0", + "size": 303146863, + "digest": "18700889e6b5e81613b9cf57ce4e0d46a6ee45bb4c5c33bae2604a5275326128775b8a032a1eb178c5db973746d565340c4e36d98375789e1d5bd836ab16ba58", + "algorithm": "sha512", + "filename": "vs2017_15.4.2.zip", + "unpack": true + }, + { + "version": "Ninja 1.7.1", + "size": 184821, + "digest": "e4f9a1ae624a2630e75264ba37d396d9c7407d6e6aea3763056210ba6e1387908bd31cf4037a6a3661a418e86c4d2761e0c333e6a3bd0d66549d2b0d72d3f43b", + "algorithm": "sha512", + "filename": "ninja171.zip", + "unpack": true + }, + { + "size": 13063963, + "visibility": "public", + "digest": "47a19f8f863eab3414abab2b9e9bd901ab896c799b3d9254b456b2f59374b085b99de805e21069a0819f01eecb3f43f7e2395a8c644c04bcbfa5711261cca29d", + "algorithm": "sha512", + "filename": "gyp-2017-05-23.zip", + "unpack": true + } +] diff --git a/security/nss/automation/taskcluster/windows/run_tests.sh b/security/nss/automation/taskcluster/windows/run_tests.sh new file mode 100644 index 0000000000..2392559d98 --- /dev/null +++ b/security/nss/automation/taskcluster/windows/run_tests.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Set up the toolchain. +source $(dirname $0)/setup.sh + +# Fetch artifact. +if [ "$TASKCLUSTER_ROOT_URL" = "https://taskcluster.net" ] || [ -z "$TASKCLUSTER_ROOT_URL" ]; then + url=https://queue.taskcluster.net/v1/task/$TC_PARENT_TASK_ID/artifacts/public/build/dist.7z +else + url=$TASKCLUSTER_ROOT_URL/api/queue/v1/task/$TC_PARENT_TASK_ID/artifacts/public/build/dist.7z +fi + +wget -t 3 --retry-connrefused -w 5 --random-wait $url -O dist.7z +7z x dist.7z + +# Run tests. +cd nss/tests && ./all.sh diff --git a/security/nss/automation/taskcluster/windows/setup.sh b/security/nss/automation/taskcluster/windows/setup.sh new file mode 100644 index 0000000000..d5bed3b817 --- /dev/null +++ b/security/nss/automation/taskcluster/windows/setup.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Usage: hg_clone repo dir [revision=@] +hg_clone() { + repo=$1 + dir=$2 + rev=${3:-@} + for i in 0 2 5; do + sleep $i + hg clone -r "$rev" "$repo" "$dir" && return + rm -rf "$dir" + done + exit 1 +} + +hg_clone https://hg.mozilla.org/build/tools tools b8d7c263dfc3 +tools/scripts/tooltool/tooltool_wrapper.sh \ + $(dirname $0)/releng.manifest http://taskcluster/tooltool.mozilla-releng.net/ \ + non-existant-file.sh /c/mozilla-build/python/python.exe \ + /c/builds/tooltool.py \ + -c /c/builds/tooltool_cache + +# This needs $m to be set. +[[ -n "$m" ]] + +# Setup MSVC paths. +export VSPATH="${PWD}/vs2017_15.4.2" +UCRTVersion="10.0.15063.0" + +export WINDOWSSDKDIR="${VSPATH}/SDK" +export VS90COMNTOOLS="${VSPATH}/VC" +export WIN32_REDIST_DIR="${VSPATH}/VC/redist/${m}/Microsoft.VC141.CRT" +export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/${m}" + +if [ "$m" == "x86" ]; then + PATH="${PATH}:${VSPATH}/VC/bin/Hostx64/x86" + PATH="${PATH}:${VSPATH}/VC/bin/Hostx64/x64" +fi +PATH="${PATH}:${VSPATH}/VC/bin/Host${m}/${m}" +PATH="${PATH}:${WIN32_REDIST_DIR}" +PATH="${PATH}:${WIN_UCRT_REDIST_DIR}" +PATH="${PATH}:${VSPATH}/SDK/bin/${UCRTVersion}/x64" +export PATH + +LIB="${LIB}:${VSPATH}/VC/lib/${m}" +LIB="${LIB}:${VSPATH}/SDK/lib/${UCRTVersion}/ucrt/${m}" +LIB="${LIB}:${VSPATH}/SDK/lib/${UCRTVersion}/um/${m}" +export LIB + +INCLUDE="${INCLUDE}:${VSPATH}/VC/include" +INCLUDE="${INCLUDE}:${VSPATH}/SDK/Include/${UCRTVersion}/ucrt" +INCLUDE="${INCLUDE}:${VSPATH}/SDK/Include/${UCRTVersion}/shared" +INCLUDE="${INCLUDE}:${VSPATH}/SDK/Include/${UCRTVersion}/um" +export INCLUDE |