diff options
Diffstat (limited to 'security/nss/automation')
39 files changed, 4139 insertions, 0 deletions
diff --git a/security/nss/automation/buildbot-slave/bbenv-example.sh b/security/nss/automation/buildbot-slave/bbenv-example.sh new file mode 100644 index 000000000..c76e5d6ab --- /dev/null +++ b/security/nss/automation/buildbot-slave/bbenv-example.sh @@ -0,0 +1,67 @@ +#! /bin/bash + +# Each buildbot-slave requires a bbenv.sh file that defines +# machine specific variables. This is an example file. + + +HOST=$(hostname | cut -d. -f1) +export HOST + +# if your machine's IP isn't registered in DNS, +# you must set appropriate environment variables +# that can be resolved locally. +# For example, if localhost.localdomain works on your system, set: +#HOST=localhost +#DOMSUF=localdomain +#export DOMSUF + +ARCH=$(uname -s) + +ulimit -c unlimited 2> /dev/null + +export NSPR_LOG_MODULES="pkix:1" + +#export JAVA_HOME_32= +#export JAVA_HOME_64= + +#enable if you have PKITS data +#export PKITS_DATA=$HOME/pkits/data/ + +NSS_BUILD_TARGET="clean nss_build_all" +JSS_BUILD_TARGET="clean all" + +MAKE=gmake +AWK=awk +PATCH=patch + +if [ "${ARCH}" = "SunOS" ]; then + AWK=nawk + PATCH=gpatch + ARCH=SunOS/$(uname -p) +fi + +if [ "${ARCH}" = "Linux" -a -f /etc/system-release ]; then + VERSION=`sed -e 's; release ;;' -e 's; (.*)$;;' -e 's;Red Hat Enterprise Linux Server;RHEL;' -e 's;Red Hat Enterprise Linux Workstation;RHEL;' /etc/system-release` + ARCH=Linux/${VERSION} + echo ${ARCH} +fi + +PROCESSOR=$(uname -p) +if [ "${PROCESSOR}" = "ppc64" ]; then + ARCH="${ARCH}/ppc64" +fi +if [ "${PROCESSOR}" = "powerpc" ]; then + ARCH="${ARCH}/ppc" +fi + +PORT_64_DBG=8543 +PORT_64_OPT=8544 +PORT_32_DBG=8545 +PORT_32_OPT=8546 + +if [ "${NSS_TESTS}" = "memleak" ]; then + PORT_64_DBG=8547 + PORT_64_OPT=8548 + PORT_32_DBG=8549 + PORT_32_OPT=8550 +fi diff --git a/security/nss/automation/buildbot-slave/build.sh b/security/nss/automation/buildbot-slave/build.sh new file mode 100755 index 000000000..0917cec6b --- /dev/null +++ b/security/nss/automation/buildbot-slave/build.sh @@ -0,0 +1,380 @@ +#! /bin/bash + +# Ensure a failure of the first command inside a pipe +# won't be hidden by commands later in the pipe. +# (e.g. as in ./dosomething | grep) + +set -o pipefail + +proc_args() +{ + while [ -n "$1" ]; do + OPT=$(echo $1 | cut -d= -f1) + VAL=$(echo $1 | cut -d= -f2) + + case $OPT in + "--build-nss") + BUILD_NSS=1 + ;; + "--test-nss") + TEST_NSS=1 + ;; + "--build-jss") + BUILD_JSS=1 + ;; + "--test-jss") + TEST_JSS=1 + ;; + "--memtest") + NSS_TESTS="memleak" + export NSS_TESTS + ;; + "--nojsssign") + NO_JSS_SIGN=1 + ;; + *) + echo "Usage: $0 ..." + echo " --memtest - run the memory leak tests" + echo " --nojsssign - try to sign jss" + echo " --build-nss" + echo " --build-jss" + echo " --test-nss" + echo " --test-jss" + exit 1 + ;; + esac + + shift + done +} + +set_env() +{ + TOPDIR=$(pwd) + HGDIR=$(pwd)$(echo "/hg") + OUTPUTDIR=$(pwd)$(echo "/output") + LOG_ALL="${OUTPUTDIR}/all.log" + LOG_TMP="${OUTPUTDIR}/tmp.log" + + echo "hello" |grep --line-buffered hello >/dev/null 2>&1 + [ $? -eq 0 ] && GREP_BUFFER="--line-buffered" +} + +print_log() +{ + DATE=$(date "+TB [%Y-%m-%d %H:%M:%S]") + echo "${DATE} $*" + echo "${DATE} $*" >> ${LOG_ALL} +} + +print_result() +{ + TESTNAME=$1 + RET=$2 + EXP=$3 + + if [ ${RET} -eq ${EXP} ]; then + print_log "${TESTNAME} PASSED" + else + print_log "${TESTNAME} FAILED" + fi +} + +print_env() +{ + print_log "######## Environment variables ########" + + uname -a | tee -a ${LOG_ALL} + if [ -e "/etc/redhat-release" ]; then + cat "/etc/redhat-release" | tee -a ${LOG_ALL} + fi + # don't print the MAIL command, it might contain a password + env | grep -v "^MAIL=" | tee -a ${LOG_ALL} +} + +set_cycle() +{ + BITS=$1 + OPT=$2 + + if [ "${BITS}" = "64" ]; then + USE_64=1 + JAVA_HOME=${JAVA_HOME_64} + PORT_DBG=${PORT_64_DBG} + PORT_OPT=${PORT_64_OPT} + else + USE_64= + JAVA_HOME=${JAVA_HOME_32} + PORT_DBG=${PORT_32_DBG} + PORT_OPT=${PORT_32_OPT} + fi + export USE_64 + export JAVA_HOME + + BUILD_OPT= + if [ "${OPT}" = "OPT" ]; then + BUILD_OPT=1 + XPCLASS=xpclass.jar + PORT=${PORT_OPT} + else + BUILD_OPT= + XPCLASS=xpclass_dbg.jar + PORT=${PORT_DBG} + fi + export BUILD_OPT + + PORT_JSS_SERVER=$(expr ${PORT} + 20) + PORT_JSSE_SERVER=$(expr ${PORT} + 40) + + export PORT + export PORT_JSS_SERVER + export PORT_JSSE_SERVER +} + +build_nss() +{ + print_log "######## NSS - build - ${BITS} bits - ${OPT} ########" + + print_log "$ cd ${HGDIR}/nss" + cd ${HGDIR}/nss + + print_log "$ ${MAKE} ${NSS_BUILD_TARGET}" + #${MAKE} ${NSS_BUILD_TARGET} 2>&1 | tee -a ${LOG_ALL} | grep ${GREP_BUFFER} "^${MAKE}" + ${MAKE} ${NSS_BUILD_TARGET} 2>&1 | tee -a ${LOG_ALL} + RET=$? + print_result "NSS - build - ${BITS} bits - ${OPT}" ${RET} 0 + + if [ ${RET} -eq 0 ]; then + return 0 + else + tail -100 ${LOG_ALL} + return ${RET} + fi +} + +build_jss() +{ + print_log "######## JSS - build - ${BITS} bits - ${OPT} ########" + + print_log "$ cd ${HGDIR}/jss" + cd ${HGDIR}/jss + + print_log "$ ${MAKE} ${JSS_BUILD_TARGET}" + #${MAKE} ${JSS_BUILD_TARGET} 2>&1 | tee -a ${LOG_ALL} | grep ${GREP_BUFFER} "^${MAKE}" + ${MAKE} ${JSS_BUILD_TARGET} 2>&1 | tee -a ${LOG_ALL} + RET=$? + print_result "JSS build - ${BITS} bits - ${OPT}" ${RET} 0 + [ ${RET} -eq 0 ] || return ${RET} + + print_log "$ cd ${HGDIR}/dist" + cd ${HGDIR}/dist + + if [ -z "${NO_JSS_SIGN}" ]; then + print_log "cat ${TOPDIR}/keystore.pw | ${JAVA_HOME}/bin/jarsigner -keystore ${TOPDIR}/keystore -internalsf ${XPCLASS} jssdsa" + cat ${TOPDIR}/keystore.pw | ${JAVA_HOME}/bin/jarsigner -keystore ${TOPDIR}/keystore -internalsf ${XPCLASS} jssdsa >> ${LOG_ALL} 2>&1 + RET=$? + print_result "JSS - sign JAR files - ${BITS} bits - ${OPT}" ${RET} 0 + [ ${RET} -eq 0 ] || return ${RET} + fi + print_log "${JAVA_HOME}/bin/jarsigner -verify -certs ${XPCLASS}" + ${JAVA_HOME}/bin/jarsigner -verify -certs ${XPCLASS} >> ${LOG_ALL} 2>&1 + RET=$? + print_result "JSS - verify JAR files - ${BITS} bits - ${OPT}" ${RET} 0 + [ ${RET} -eq 0 ] || return ${RET} + + return 0 +} + +test_nss() +{ + print_log "######## NSS - tests - ${BITS} bits - ${OPT} ########" + + if [ "${OS_TARGET}" = "Android" ]; then + print_log "$ cd ${HGDIR}/nss/tests/remote" + cd ${HGDIR}/nss/tests/remote + print_log "$ make test_android" + make test_android 2>&1 | tee ${LOG_TMP} | grep ${GREP_BUFFER} ": #" + OUTPUTFILE=${HGDIR}/tests_results/security/*.1/output.log + else + print_log "$ cd ${HGDIR}/nss/tests" + cd ${HGDIR}/nss/tests + print_log "$ ./all.sh" + ./all.sh 2>&1 | tee ${LOG_TMP} | egrep ${GREP_BUFFER} ": #|^\[.{10}\] " + OUTPUTFILE=${LOG_TMP} + fi + + cat ${LOG_TMP} >> ${LOG_ALL} + tail -n2 ${HGDIR}/tests_results/security/*.1/results.html | grep END_OF_TEST >> ${LOG_ALL} + RET=$? + + print_log "######## details of detected failures (if any) ########" + grep -B50 FAILED ${OUTPUTFILE} + [ $? -eq 1 ] || RET=1 + + print_result "NSS - tests - ${BITS} bits - ${OPT}" ${RET} 0 + return ${RET} +} + +test_jss() +{ + print_log "######## JSS - tests - ${BITS} bits - ${OPT} ########" + + print_log "$ cd ${HGDIR}/jss" + cd ${HGDIR}/jss + + print_log "$ ${MAKE} platform" + PLATFORM=$(${MAKE} platform) + print_log "PLATFORM=${PLATFORM}" + + print_log "$ cd ${HGDIR}/jss/org/mozilla/jss/tests" + cd ${HGDIR}/jss/org/mozilla/jss/tests + + print_log "$ perl all.pl dist ${HGDIR}/dist/${PLATFORM}" + perl all.pl dist ${HGDIR}/dist/${PLATFORM} 2>&1 | tee ${LOG_TMP} + cat ${LOG_TMP} >> ${LOG_ALL} + + tail -n2 ${LOG_TMP} | grep JSSTEST_RATE > /dev/null + RET=$? + + grep FAIL ${LOG_TMP} + [ $? -eq 1 ] || RET=1 + + print_result "JSS - tests - ${BITS} bits - ${OPT}" ${RET} 0 + return ${RET} +} + +build_and_test() +{ + if [ -n "${BUILD_NSS}" ]; then + build_nss + [ $? -eq 0 ] || return 1 + fi + + if [ -n "${TEST_NSS}" ]; then + test_nss + [ $? -eq 0 ] || return 1 + fi + + if [ -n "${BUILD_JSS}" ]; then + build_jss + [ $? -eq 0 ] || return 1 + fi + + if [ -n "${TEST_JSS}" ]; then + test_jss + [ $? -eq 0 ] || return 1 + fi + + return 0 +} + +run_cycle() +{ + print_env + build_and_test + RET=$? + + grep ^TinderboxPrint ${LOG_ALL} + + return ${RET} +} + +prepare() +{ + rm -rf ${OUTPUTDIR}.oldest >/dev/null 2>&1 + mv ${OUTPUTDIR}.older ${OUTPUTDIR}.oldest >/dev/null 2>&1 + mv ${OUTPUTDIR}.old ${OUTPUTDIR}.older >/dev/null 2>&1 + mv ${OUTPUTDIR}.last ${OUTPUTDIR}.old >/dev/null 2>&1 + mv ${OUTPUTDIR} ${OUTPUTDIR}.last >/dev/null 2>&1 + mkdir -p ${OUTPUTDIR} + + # Remove temporary test files from previous jobs, that weren't cleaned up + # by move_results(), e.g. caused by unexpected interruptions. + rm -rf ${HGDIR}/tests_results/ + + cd ${HGDIR}/nss + + if [ -n "${FEWER_STRESS_ITERATIONS}" ]; then + sed -i 's/-c_1000_/-c_500_/g' tests/ssl/sslstress.txt + fi + + return 0 +} + +move_results() +{ + cd ${HGDIR} + if [ -n "${TEST_NSS}" ]; then + mv -f tests_results ${OUTPUTDIR} + fi + tar -c -z --dereference -f ${OUTPUTDIR}/dist.tgz dist + rm -rf dist +} + +run_all() +{ + set_cycle ${BITS} ${OPT} + prepare + run_cycle + RESULT=$? + print_log "### result of run_cycle is ${RESULT}" + move_results + return ${RESULT} +} + +main() +{ + VALID=0 + RET=1 + + for BITS in 32 64; do + echo ${RUN_BITS} | grep ${BITS} > /dev/null + [ $? -eq 0 ] || continue + for OPT in DBG OPT; do + echo ${RUN_OPT} | grep ${OPT} > /dev/null + [ $? -eq 0 ] || continue + + VALID=1 + set_env + run_all + RET=$? + print_log "### result of run_all is ${RET}" + done + done + + if [ ${VALID} -ne 1 ]; then + echo "Need to set valid bits/opt values." + return 1 + fi + + return ${RET} +} + +#function killallsub() +#{ +# FINAL_RET=$? +# for proc in `jobs -p` +# do +# kill -9 $proc +# done +# return ${FINAL_RET} +#} +#trap killallsub EXIT + +#IS_RUNNING_FILE="./build-is-running" + +#if [ -a $IS_RUNNING_FILE ]; then +# echo "exiting, because old job is still running" +# exit 1 +#fi + +#touch $IS_RUNNING_FILE + +echo "tinderbox args: $0 $@" +. ${ENVVARS} +proc_args "$@" +main + +#RET=$? +#rm $IS_RUNNING_FILE +#exit ${RET} diff --git a/security/nss/automation/buildbot-slave/reboot.bat b/security/nss/automation/buildbot-slave/reboot.bat new file mode 100644 index 000000000..c6a5c7b43 --- /dev/null +++ b/security/nss/automation/buildbot-slave/reboot.bat @@ -0,0 +1,6 @@ +IF EXIST ..\buildbot-is-building ( + del ..\buildbot-is-building + shutdown /r /t 0 + + timeout /t 120 +) diff --git a/security/nss/automation/buildbot-slave/startbuild.bat b/security/nss/automation/buildbot-slave/startbuild.bat new file mode 100644 index 000000000..ba06834f1 --- /dev/null +++ b/security/nss/automation/buildbot-slave/startbuild.bat @@ -0,0 +1,14 @@ +echo running > ..\buildbot-is-building + +echo running: "%MOZILLABUILD%\msys\bin\bash" -c "hg/nss/automation/buildbot-slave/build.sh %*" +"%MOZILLABUILD%\msys\bin\bash" -c "hg/nss/automation/buildbot-slave/build.sh %*" + +if %errorlevel% neq 0 ( + set EXITCODE=1 +) else ( + set EXITCODE=0 +) + +del ..\buildbot-is-building + +exit /b %EXITCODE% diff --git a/security/nss/automation/release/nspr-version.txt b/security/nss/automation/release/nspr-version.txt new file mode 100644 index 000000000..9e0c933dc --- /dev/null +++ b/security/nss/automation/release/nspr-version.txt @@ -0,0 +1,10 @@ +4.13.1 + +# 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 100644 index 000000000..d168febde --- /dev/null +++ b/security/nss/automation/release/nss-release-helper.py @@ -0,0 +1,252 @@ +#!/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 datetime +import shutil +import glob +from optparse import OptionParser +from subprocess import check_call + +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" + +def check_call_noisy(cmd, *args, **kwargs): + print "Executing command:", cmd + check_call(cmd, *args, **kwargs) + +o = OptionParser(usage="client.py [options] 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) + +def exit_with_failure(what): + print "failure: ", 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") + +def sed_inplace(sed_expression, filename): + backup_file = filename + '.tmp' + check_call_noisy(["sed", "-i.tmp", sed_expression, filename]) + os.remove(backup_file) + +def toggle_beta_status(is_beta): + check_files_exist() + if (is_beta): + print "adding Beta status to version numbers" + sed_inplace('s/^\(#define *NSSUTIL_VERSION *\"[0-9.]\+\)\" *$/\\1 Beta\"/', nssutil_h) + sed_inplace('s/^\(#define *NSSUTIL_BETA *\)PR_FALSE *$/\\1PR_TRUE/', nssutil_h) + sed_inplace('s/^\(#define *SOFTOKEN_VERSION *\"[0-9.]\+\" *SOFTOKEN_ECC_STRING\) *$/\\1 \" Beta"/', softkver_h) + sed_inplace('s/^\(#define *SOFTOKEN_BETA *\)PR_FALSE *$/\\1PR_TRUE/', softkver_h) + sed_inplace('s/^\(#define *NSS_VERSION *\"[0-9.]\+\" *_NSS_CUSTOMIZED\) *$/\\1 \" Beta"/', nss_h) + sed_inplace('s/^\(#define *NSS_BETA *\)PR_FALSE *$/\\1PR_TRUE/', nss_h) + else: + print "removing Beta status from version numbers" + sed_inplace('s/^\(#define *NSSUTIL_VERSION *\"[0-9.]\+\) *Beta\" *$/\\1\"/', nssutil_h) + sed_inplace('s/^\(#define *NSSUTIL_BETA *\)PR_TRUE *$/\\1PR_FALSE/', nssutil_h) + sed_inplace('s/^\(#define *SOFTOKEN_VERSION *\"[0-9.]\+\" *SOFTOKEN_ECC_STRING\) *\" *Beta\" *$/\\1/', softkver_h) + sed_inplace('s/^\(#define *SOFTOKEN_BETA *\)PR_TRUE *$/\\1PR_FALSE/', softkver_h) + sed_inplace('s/^\(#define *NSS_VERSION *\"[0-9.]\+\" *_NSS_CUSTOMIZED\) *\" *Beta\" *$/\\1/', nss_h) + sed_inplace('s/^\(#define *NSS_BETA *\)PR_TRUE *$/\\1PR_FALSE/', nss_h) + 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): + sed_inplace('s/^\(#define *NSSUTIL_VMAJOR *\).*$/\\1' + major + '/', nssutil_h) + sed_inplace('s/^\(#define *SOFTOKEN_VMAJOR *\).*$/\\1' + major + '/', softkver_h) + sed_inplace('s/^\(#define *NSS_VMAJOR *\).*$/\\1' + major + '/', nss_h) + +def set_minor_versions(minor): + sed_inplace('s/^\(#define *NSSUTIL_VMINOR *\).*$/\\1' + minor + '/', nssutil_h) + sed_inplace('s/^\(#define *SOFTOKEN_VMINOR *\).*$/\\1' + minor + '/', softkver_h) + sed_inplace('s/^\(#define *NSS_VMINOR *\).*$/\\1' + minor + '/', nss_h) + +def set_patch_versions(patch): + sed_inplace('s/^\(#define *NSSUTIL_VPATCH *\).*$/\\1' + patch + '/', nssutil_h) + sed_inplace('s/^\(#define *SOFTOKEN_VPATCH *\).*$/\\1' + patch + '/', softkver_h) + sed_inplace('s/^\(#define *NSS_VPATCH *\).*$/\\1' + patch + '/', nss_h) + +def set_build_versions(build): + sed_inplace('s/^\(#define *NSSUTIL_VBUILD *\).*$/\\1' + build + '/', nssutil_h) + sed_inplace('s/^\(#define *SOFTOKEN_VBUILD *\).*$/\\1' + build + '/', softkver_h) + sed_inplace('s/^\(#define *NSS_VBUILD *\).*$/\\1' + build + '/', nss_h) + +def set_full_lib_versions(version): + sed_inplace('s/^\(#define *NSSUTIL_VERSION *\"\)\([0-9.]\+\)\(.*\)$/\\1' + version + '\\3/', nssutil_h) + sed_inplace('s/^\(#define *SOFTOKEN_VERSION *\"\)\([0-9.]\+\)\(.*\)$/\\1' + version + '\\3/', softkver_h) + sed_inplace('s/^\(#define *NSS_VERSION *\"\)\([0-9.]\+\)\(.*\)$/\\1' + version + '\\3/', nss_h) + +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 + sed_inplace('s/^\(#define *NSS_BUILTINS_LIBRARY_VERSION *\"\).*$/\\1' + version + '/', nssckbi_h) + sed_inplace('s/^\(#define *NSS_BUILTINS_LIBRARY_VERSION_MAJOR *\).*$/\\1' + major + '/', nssckbi_h) + sed_inplace('s/^\(#define *NSS_BUILTINS_LIBRARY_VERSION_MINOR *\).*$/\\1' + minor + '/', nssckbi_h) + +def set_all_lib_versions(version, major, minor, patch, build): + 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"]) + +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-arm/Dockerfile b/security/nss/automation/taskcluster/docker-arm/Dockerfile new file mode 100644 index 000000000..9a7e50201 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-arm/Dockerfile @@ -0,0 +1,27 @@ +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 HOSTNAME taskcluster-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 000000000..4b891289d --- /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 000000000..61ad13c34 --- /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 000000000..42d66a454 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-arm/setup.sh @@ -0,0 +1,35 @@ +#!/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+=('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-decision/Dockerfile b/security/nss/automation/taskcluster/docker-decision/Dockerfile new file mode 100644 index 000000000..35777c0b7 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-decision/Dockerfile @@ -0,0 +1,27 @@ +FROM ubuntu:16.04 +MAINTAINER Tim Taubert <ttaubert@mozilla.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 HOSTNAME taskcluster-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-decision/bin/checkout.sh b/security/nss/automation/taskcluster/docker-decision/bin/checkout.sh new file mode 100644 index 000000000..9167f6bda --- /dev/null +++ b/security/nss/automation/taskcluster/docker-decision/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/setup.sh b/security/nss/automation/taskcluster/docker-decision/setup.sh new file mode 100644 index 000000000..e5a6d2019 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-decision/setup.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Update packages. +export DEBIAN_FRONTEND=noninteractive +apt-get -y update && apt-get -y upgrade + +# Need those to install newer packages below. +apt-get install -y --no-install-recommends apt-utils curl ca-certificates + +# Latest Mercurial. +apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 41BD8711B1F0EC2B0D85B91CF59CE3A8323293EE +echo "deb http://ppa.launchpad.net/mercurial-ppa/releases/ubuntu xenial main" > /etc/apt/sources.list.d/mercurial.list + +# Install packages. +apt-get -y update && apt-get install -y --no-install-recommends mercurial + +# Latest Node.JS. +curl -sL https://deb.nodesource.com/setup_6.x | bash - +apt-get install -y --no-install-recommends nodejs + +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/Dockerfile b/security/nss/automation/taskcluster/docker/Dockerfile new file mode 100644 index 000000000..35777c0b7 --- /dev/null +++ b/security/nss/automation/taskcluster/docker/Dockerfile @@ -0,0 +1,27 @@ +FROM ubuntu:16.04 +MAINTAINER Tim Taubert <ttaubert@mozilla.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 HOSTNAME taskcluster-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/bin/checkout.sh b/security/nss/automation/taskcluster/docker/bin/checkout.sh new file mode 100644 index 000000000..9167f6bda --- /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/docker/setup.sh b/security/nss/automation/taskcluster/docker/setup.sh new file mode 100644 index 000000000..4969f4aa0 --- /dev/null +++ b/security/nss/automation/taskcluster/docker/setup.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Update packages. +export DEBIAN_FRONTEND=noninteractive +apt-get -y update && apt-get -y upgrade + +# Need this to add keys for PPAs below. +apt-get install -y --no-install-recommends apt-utils + +apt_packages=() +apt_packages+=('build-essential') +apt_packages+=('ca-certificates') +apt_packages+=('curl') +apt_packages+=('npm') +apt_packages+=('git') +apt_packages+=('golang-1.6') +apt_packages+=('ninja-build') +apt_packages+=('pkg-config') +apt_packages+=('zlib1g-dev') + +# 32-bit builds +apt_packages+=('lib32z1-dev') +apt_packages+=('gcc-multilib') +apt_packages+=('g++-multilib') + +# ct-verif and sanitizers +apt_packages+=('valgrind') + +# Latest Mercurial. +apt_packages+=('mercurial') +apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 41BD8711B1F0EC2B0D85B91CF59CE3A8323293EE +echo "deb http://ppa.launchpad.net/mercurial-ppa/releases/ubuntu xenial main" > /etc/apt/sources.list.d/mercurial.list + +# gcc 4.8 and 6 +apt_packages+=('g++-6') +apt_packages+=('g++-4.8') +apt_packages+=('g++-6-multilib') +apt_packages+=('g++-4.8-multilib') +apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 60C317803A41BA51845E371A1E9377A2BA9EF27F +echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu xenial main" > /etc/apt/sources.list.d/toolchain.list + +# Install packages. +apt-get -y update +apt-get install -y --no-install-recommends ${apt_packages[@]} + +# 32-bit builds +ln -s /usr/include/x86_64-linux-gnu/zconf.h /usr/include + +# Install clang-3.9 into /usr/local/. +curl -L http://llvm.org/releases/3.9.0/clang+llvm-3.9.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz | tar xJv -C /usr/local --strip-components=1 + +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/graph/npm-shrinkwrap.json b/security/nss/automation/taskcluster/graph/npm-shrinkwrap.json new file mode 100644 index 000000000..b805bb8ed --- /dev/null +++ b/security/nss/automation/taskcluster/graph/npm-shrinkwrap.json @@ -0,0 +1,1643 @@ +{ + "name": "decision-task", + "version": "0.0.1", + "dependencies": { + "amqplib": { + "version": "0.4.2", + "from": "amqplib@>=0.4.1 <0.5.0", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.4.2.tgz", + "dependencies": { + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "readable-stream": { + "version": "1.1.14", + "from": "readable-stream@>=1.0.0 <2.0.0 >=1.1.9", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz" + } + } + }, + "ansi-regex": { + "version": "2.0.0", + "from": "ansi-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" + }, + "ansi-styles": { + "version": "2.2.1", + "from": "ansi-styles@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" + }, + "anymatch": { + "version": "1.3.0", + "from": "anymatch@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz" + }, + "argparse": { + "version": "1.0.9", + "from": "argparse@>=1.0.7 <2.0.0", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz" + }, + "arr-diff": { + "version": "2.0.0", + "from": "arr-diff@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz" + }, + "arr-flatten": { + "version": "1.0.1", + "from": "arr-flatten@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.1.tgz" + }, + "array-find-index": { + "version": "1.0.2", + "from": "array-find-index@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz" + }, + "array-uniq": { + "version": "1.0.3", + "from": "array-uniq@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" + }, + "array-unique": { + "version": "0.2.1", + "from": "array-unique@>=0.2.1 <0.3.0", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz" + }, + "arrify": { + "version": "1.0.1", + "from": "arrify@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + }, + "asap": { + "version": "1.0.0", + "from": "asap@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz" + }, + "asn1": { + "version": "0.2.3", + "from": "asn1@>=0.2.3 <0.3.0", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz" + }, + "assert-plus": { + "version": "0.2.0", + "from": "assert-plus@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz" + }, + "async": { + "version": "2.1.1", + "from": "async@*", + "resolved": "https://registry.npmjs.org/async/-/async-2.1.1.tgz" + }, + "async-each": { + "version": "1.0.1", + "from": "async-each@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz" + }, + "asynckit": { + "version": "0.4.0", + "from": "asynckit@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + }, + "aws-sign2": { + "version": "0.6.0", + "from": "aws-sign2@>=0.6.0 <0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz" + }, + "aws4": { + "version": "1.5.0", + "from": "aws4@>=1.2.1 <2.0.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.5.0.tgz" + }, + "babel-cli": { + "version": "6.16.0", + "from": "babel-cli@>=6.14.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.16.0.tgz" + }, + "babel-code-frame": { + "version": "6.16.0", + "from": "babel-code-frame@>=6.16.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.16.0.tgz" + }, + "babel-compile": { + "version": "2.0.0", + "from": "babel-compile@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/babel-compile/-/babel-compile-2.0.0.tgz" + }, + "babel-core": { + "version": "6.17.0", + "from": "babel-core@>=6.16.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.17.0.tgz" + }, + "babel-generator": { + "version": "6.17.0", + "from": "babel-generator@>=6.17.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.17.0.tgz" + }, + "babel-helper-call-delegate": { + "version": "6.8.0", + "from": "babel-helper-call-delegate@>=6.8.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.8.0.tgz" + }, + "babel-helper-define-map": { + "version": "6.9.0", + "from": "babel-helper-define-map@>=6.9.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.9.0.tgz" + }, + "babel-helper-function-name": { + "version": "6.8.0", + "from": "babel-helper-function-name@>=6.8.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.8.0.tgz" + }, + "babel-helper-get-function-arity": { + "version": "6.8.0", + "from": "babel-helper-get-function-arity@>=6.8.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.8.0.tgz" + }, + "babel-helper-hoist-variables": { + "version": "6.8.0", + "from": "babel-helper-hoist-variables@>=6.8.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.8.0.tgz" + }, + "babel-helper-optimise-call-expression": { + "version": "6.8.0", + "from": "babel-helper-optimise-call-expression@>=6.8.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.8.0.tgz" + }, + "babel-helper-regex": { + "version": "6.9.0", + "from": "babel-helper-regex@>=6.8.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.9.0.tgz" + }, + "babel-helper-remap-async-to-generator": { + "version": "6.16.2", + "from": "babel-helper-remap-async-to-generator@>=6.16.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.16.2.tgz" + }, + "babel-helper-replace-supers": { + "version": "6.16.0", + "from": "babel-helper-replace-supers@>=6.14.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.16.0.tgz" + }, + "babel-helpers": { + "version": "6.16.0", + "from": "babel-helpers@>=6.16.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.16.0.tgz" + }, + "babel-messages": { + "version": "6.8.0", + "from": "babel-messages@>=6.8.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.8.0.tgz" + }, + "babel-plugin-check-es2015-constants": { + "version": "6.8.0", + "from": "babel-plugin-check-es2015-constants@>=6.3.13 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.8.0.tgz" + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "from": "babel-plugin-syntax-async-functions@>=6.8.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz" + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.16.0", + "from": "babel-plugin-transform-async-to-generator@>=6.8.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.16.0.tgz" + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.8.0", + "from": "babel-plugin-transform-es2015-arrow-functions@>=6.3.13 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.8.0.tgz" + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.8.0", + "from": "babel-plugin-transform-es2015-block-scoped-functions@>=6.3.13 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.8.0.tgz" + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.15.0", + "from": "babel-plugin-transform-es2015-block-scoping@>=6.14.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.15.0.tgz" + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.14.0", + "from": "babel-plugin-transform-es2015-classes@>=6.14.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.14.0.tgz" + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.8.0", + "from": "babel-plugin-transform-es2015-computed-properties@>=6.3.13 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.8.0.tgz" + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.16.0", + "from": "babel-plugin-transform-es2015-destructuring@>=6.16.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.16.0.tgz" + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.8.0", + "from": "babel-plugin-transform-es2015-duplicate-keys@>=6.6.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.8.0.tgz" + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.8.0", + "from": "babel-plugin-transform-es2015-for-of@>=6.6.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.8.0.tgz" + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.9.0", + "from": "babel-plugin-transform-es2015-function-name@>=6.9.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.9.0.tgz" + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.8.0", + "from": "babel-plugin-transform-es2015-literals@>=6.3.13 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.8.0.tgz" + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.8.0", + "from": "babel-plugin-transform-es2015-modules-amd@>=6.8.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.8.0.tgz" + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.16.0", + "from": "babel-plugin-transform-es2015-modules-commonjs@>=6.16.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.16.0.tgz" + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.14.0", + "from": "babel-plugin-transform-es2015-modules-systemjs@>=6.14.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.14.0.tgz" + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.12.0", + "from": "babel-plugin-transform-es2015-modules-umd@>=6.12.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.12.0.tgz" + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.8.0", + "from": "babel-plugin-transform-es2015-object-super@>=6.3.13 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.8.0.tgz" + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.17.0", + "from": "babel-plugin-transform-es2015-parameters@>=6.16.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.17.0.tgz" + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.8.0", + "from": "babel-plugin-transform-es2015-shorthand-properties@>=6.3.13 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.8.0.tgz" + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.8.0", + "from": "babel-plugin-transform-es2015-spread@>=6.3.13 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.8.0.tgz" + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.8.0", + "from": "babel-plugin-transform-es2015-sticky-regex@>=6.3.13 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.8.0.tgz" + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.8.0", + "from": "babel-plugin-transform-es2015-template-literals@>=6.6.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.8.0.tgz" + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.8.0", + "from": "babel-plugin-transform-es2015-typeof-symbol@>=6.6.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.8.0.tgz" + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.11.0", + "from": "babel-plugin-transform-es2015-unicode-regex@>=6.3.13 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.11.0.tgz" + }, + "babel-plugin-transform-regenerator": { + "version": "6.16.1", + "from": "babel-plugin-transform-regenerator@>=6.16.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.16.1.tgz" + }, + "babel-plugin-transform-runtime": { + "version": "6.15.0", + "from": "babel-plugin-transform-runtime@>=6.9.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.15.0.tgz" + }, + "babel-plugin-transform-strict-mode": { + "version": "6.11.3", + "from": "babel-plugin-transform-strict-mode@>=6.8.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.11.3.tgz" + }, + "babel-polyfill": { + "version": "6.16.0", + "from": "babel-polyfill@>=6.16.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.16.0.tgz" + }, + "babel-preset-es2015": { + "version": "6.16.0", + "from": "babel-preset-es2015@>=6.9.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.16.0.tgz" + }, + "babel-preset-taskcluster": { + "version": "3.0.0", + "from": "babel-preset-taskcluster@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-taskcluster/-/babel-preset-taskcluster-3.0.0.tgz" + }, + "babel-register": { + "version": "6.16.3", + "from": "babel-register@>=6.16.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.16.3.tgz" + }, + "babel-runtime": { + "version": "6.11.6", + "from": "babel-runtime@>=6.11.6 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.11.6.tgz" + }, + "babel-template": { + "version": "6.16.0", + "from": "babel-template@>=6.16.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.16.0.tgz" + }, + "babel-traverse": { + "version": "6.16.0", + "from": "babel-traverse@>=6.16.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.16.0.tgz" + }, + "babel-types": { + "version": "6.16.0", + "from": "babel-types@>=6.16.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.16.0.tgz" + }, + "babylon": { + "version": "6.11.6", + "from": "babylon@>=6.11.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.11.6.tgz" + }, + "balanced-match": { + "version": "0.4.2", + "from": "balanced-match@>=0.4.1 <0.5.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz" + }, + "bcrypt-pbkdf": { + "version": "1.0.0", + "from": "bcrypt-pbkdf@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz" + }, + "bin-version": { + "version": "1.0.4", + "from": "bin-version@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-1.0.4.tgz" + }, + "bin-version-check": { + "version": "2.1.0", + "from": "bin-version-check@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-2.1.0.tgz" + }, + "binary-extensions": { + "version": "1.7.0", + "from": "binary-extensions@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.7.0.tgz" + }, + "bitsyntax": { + "version": "0.0.4", + "from": "bitsyntax@>=0.0.4 <0.1.0", + "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.0.4.tgz" + }, + "bl": { + "version": "1.1.2", + "from": "bl@>=1.1.2 <1.2.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "from": "readable-stream@>=2.0.5 <2.1.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz" + } + } + }, + "boom": { + "version": "2.10.1", + "from": "boom@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz" + }, + "brace-expansion": { + "version": "1.1.6", + "from": "brace-expansion@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz" + }, + "braces": { + "version": "1.8.5", + "from": "braces@>=1.8.2 <2.0.0", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz" + }, + "buffer-more-ints": { + "version": "0.0.2", + "from": "buffer-more-ints@0.0.2", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz" + }, + "buffer-shims": { + "version": "1.0.0", + "from": "buffer-shims@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" + }, + "builtin-modules": { + "version": "1.1.1", + "from": "builtin-modules@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz" + }, + "camelcase": { + "version": "2.1.1", + "from": "camelcase@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz" + }, + "camelcase-keys": { + "version": "2.1.0", + "from": "camelcase-keys@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz" + }, + "caseless": { + "version": "0.11.0", + "from": "caseless@>=0.11.0 <0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz" + }, + "chalk": { + "version": "1.1.1", + "from": "chalk@1.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.1.tgz" + }, + "chokidar": { + "version": "1.6.0", + "from": "chokidar@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.6.0.tgz" + }, + "combined-stream": { + "version": "1.0.5", + "from": "combined-stream@>=1.0.5 <1.1.0", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz" + }, + "commander": { + "version": "2.9.0", + "from": "commander@>=2.8.1 <3.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz" + }, + "component-emitter": { + "version": "1.2.1", + "from": "component-emitter@>=1.2.0 <1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz" + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + }, + "convert-source-map": { + "version": "1.3.0", + "from": "convert-source-map@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.3.0.tgz" + }, + "cookiejar": { + "version": "2.0.6", + "from": "cookiejar@2.0.6", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.0.6.tgz" + }, + "core-js": { + "version": "2.4.1", + "from": "core-js@>=2.4.0 <3.0.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz" + }, + "core-util-is": { + "version": "1.0.2", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + }, + "cryptiles": { + "version": "2.0.5", + "from": "cryptiles@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz" + }, + "currently-unhandled": { + "version": "0.4.1", + "from": "currently-unhandled@>=0.4.1 <0.5.0", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz" + }, + "dashdash": { + "version": "1.14.0", + "from": "dashdash@>=1.12.0 <2.0.0", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.0.tgz", + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "from": "assert-plus@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + } + } + }, + "debug": { + "version": "2.2.0", + "from": "debug@>=2.1.1 <3.0.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz" + }, + "decamelize": { + "version": "1.2.0", + "from": "decamelize@>=1.1.2 <2.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" + }, + "delayed-stream": { + "version": "1.0.0", + "from": "delayed-stream@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + }, + "detect-indent": { + "version": "3.0.1", + "from": "detect-indent@>=3.0.1 <4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-3.0.1.tgz" + }, + "ecc-jsbn": { + "version": "0.1.1", + "from": "ecc-jsbn@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz" + }, + "error-ex": { + "version": "1.3.0", + "from": "error-ex@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.0.tgz" + }, + "escape-string-regexp": { + "version": "1.0.5", + "from": "escape-string-regexp@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + }, + "esprima": { + "version": "2.7.3", + "from": "esprima@>=2.6.0 <3.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz" + }, + "esutils": { + "version": "2.0.2", + "from": "esutils@>=2.0.2 <3.0.0", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz" + }, + "eventsource": { + "version": "0.1.6", + "from": "eventsource@>=0.1.6 <0.2.0", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz" + }, + "expand-brackets": { + "version": "0.1.5", + "from": "expand-brackets@>=0.1.4 <0.2.0", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz" + }, + "expand-range": { + "version": "1.8.2", + "from": "expand-range@>=1.8.1 <2.0.0", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz" + }, + "extend": { + "version": "3.0.0", + "from": "extend@>=3.0.0 <3.1.0", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz" + }, + "extglob": { + "version": "0.3.2", + "from": "extglob@>=0.3.1 <0.4.0", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz" + }, + "extsprintf": { + "version": "1.0.2", + "from": "extsprintf@1.0.2", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz" + }, + "faye-websocket": { + "version": "0.11.0", + "from": "faye-websocket@>=0.11.0 <0.12.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.0.tgz" + }, + "filename-regex": { + "version": "2.0.0", + "from": "filename-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.0.tgz" + }, + "fill-range": { + "version": "2.2.3", + "from": "fill-range@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz" + }, + "find-up": { + "version": "1.1.2", + "from": "find-up@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "dependencies": { + "path-exists": { + "version": "2.1.0", + "from": "path-exists@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz" + } + } + }, + "find-versions": { + "version": "1.2.1", + "from": "find-versions@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-1.2.1.tgz" + }, + "flatmap": { + "version": "0.0.3", + "from": "flatmap@0.0.3", + "resolved": "https://registry.npmjs.org/flatmap/-/flatmap-0.0.3.tgz" + }, + "for-in": { + "version": "0.1.6", + "from": "for-in@>=0.1.5 <0.2.0", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.6.tgz" + }, + "for-own": { + "version": "0.1.4", + "from": "for-own@>=0.1.3 <0.2.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.4.tgz" + }, + "forever-agent": { + "version": "0.6.1", + "from": "forever-agent@>=0.6.1 <0.7.0", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" + }, + "form-data": { + "version": "2.0.0", + "from": "form-data@>=2.0.0 <2.1.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.0.0.tgz" + }, + "formidable": { + "version": "1.0.17", + "from": "formidable@>=1.0.14 <1.1.0", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.17.tgz" + }, + "fs-readdir-recursive": { + "version": "0.1.2", + "from": "fs-readdir-recursive@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz" + }, + "fs-walk": { + "version": "0.0.1", + "from": "fs-walk@0.0.1", + "resolved": "https://registry.npmjs.org/fs-walk/-/fs-walk-0.0.1.tgz" + }, + "fs.realpath": { + "version": "1.0.0", + "from": "fs.realpath@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + }, + "generate-function": { + "version": "2.0.0", + "from": "generate-function@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz" + }, + "generate-object-property": { + "version": "1.2.0", + "from": "generate-object-property@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz" + }, + "get-stdin": { + "version": "4.0.1", + "from": "get-stdin@>=4.0.1 <5.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz" + }, + "getpass": { + "version": "0.1.6", + "from": "getpass@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz", + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "from": "assert-plus@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + } + } + }, + "glob": { + "version": "5.0.15", + "from": "glob@>=5.0.5 <6.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz" + }, + "glob-base": { + "version": "0.3.0", + "from": "glob-base@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz" + }, + "glob-parent": { + "version": "2.0.0", + "from": "glob-parent@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz" + }, + "globals": { + "version": "8.18.0", + "from": "globals@>=8.3.0 <9.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-8.18.0.tgz" + }, + "graceful-fs": { + "version": "4.1.9", + "from": "graceful-fs@>=4.1.2 <5.0.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.9.tgz" + }, + "graceful-readlink": { + "version": "1.0.1", + "from": "graceful-readlink@>=1.0.0", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" + }, + "har-validator": { + "version": "2.0.6", + "from": "har-validator@>=2.0.6 <2.1.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz" + }, + "has-ansi": { + "version": "2.0.0", + "from": "has-ansi@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" + }, + "hawk": { + "version": "3.1.3", + "from": "hawk@>=3.1.3 <3.2.0", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz" + }, + "hoek": { + "version": "2.16.3", + "from": "hoek@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz" + }, + "home-or-tmp": { + "version": "1.0.0", + "from": "home-or-tmp@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-1.0.0.tgz" + }, + "hosted-git-info": { + "version": "2.1.5", + "from": "hosted-git-info@>=2.1.4 <3.0.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.1.5.tgz" + }, + "http-signature": { + "version": "1.1.1", + "from": "http-signature@>=1.1.0 <1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz" + }, + "indent-string": { + "version": "2.1.0", + "from": "indent-string@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "dependencies": { + "repeating": { + "version": "2.0.1", + "from": "repeating@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz" + } + } + }, + "inflight": { + "version": "1.0.6", + "from": "inflight@>=1.0.4 <2.0.0", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + }, + "inherits": { + "version": "2.0.3", + "from": "inherits@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + }, + "intersect": { + "version": "1.0.1", + "from": "intersect@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/intersect/-/intersect-1.0.1.tgz" + }, + "invariant": { + "version": "2.2.1", + "from": "invariant@>=2.2.0 <3.0.0", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.1.tgz" + }, + "is-arrayish": { + "version": "0.2.1", + "from": "is-arrayish@>=0.2.1 <0.3.0", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + }, + "is-binary-path": { + "version": "1.0.1", + "from": "is-binary-path@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz" + }, + "is-buffer": { + "version": "1.1.4", + "from": "is-buffer@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.4.tgz" + }, + "is-builtin-module": { + "version": "1.0.0", + "from": "is-builtin-module@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz" + }, + "is-dotfile": { + "version": "1.0.2", + "from": "is-dotfile@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz" + }, + "is-equal-shallow": { + "version": "0.1.3", + "from": "is-equal-shallow@>=0.1.3 <0.2.0", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz" + }, + "is-extendable": { + "version": "0.1.1", + "from": "is-extendable@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" + }, + "is-extglob": { + "version": "1.0.0", + "from": "is-extglob@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz" + }, + "is-finite": { + "version": "1.0.2", + "from": "is-finite@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz" + }, + "is-glob": { + "version": "2.0.1", + "from": "is-glob@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz" + }, + "is-my-json-valid": { + "version": "2.15.0", + "from": "is-my-json-valid@>=2.12.4 <3.0.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz" + }, + "is-number": { + "version": "2.1.0", + "from": "is-number@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz" + }, + "is-posix-bracket": { + "version": "0.1.1", + "from": "is-posix-bracket@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz" + }, + "is-primitive": { + "version": "2.0.0", + "from": "is-primitive@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz" + }, + "is-property": { + "version": "1.0.2", + "from": "is-property@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz" + }, + "is-typedarray": { + "version": "1.0.0", + "from": "is-typedarray@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" + }, + "is-utf8": { + "version": "0.2.1", + "from": "is-utf8@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz" + }, + "isarray": { + "version": "1.0.0", + "from": "isarray@1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + }, + "isobject": { + "version": "2.1.0", + "from": "isobject@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz" + }, + "isstream": { + "version": "0.1.2", + "from": "isstream@>=0.1.2 <0.2.0", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" + }, + "jodid25519": { + "version": "1.0.2", + "from": "jodid25519@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz" + }, + "js-tokens": { + "version": "2.0.0", + "from": "js-tokens@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-2.0.0.tgz" + }, + "js-yaml": { + "version": "3.6.1", + "from": "js-yaml@>=3.6.1 <4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz" + }, + "jsbn": { + "version": "0.1.0", + "from": "jsbn@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz" + }, + "jsesc": { + "version": "1.3.0", + "from": "jsesc@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz" + }, + "json-schema": { + "version": "0.2.3", + "from": "json-schema@0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz" + }, + "json-stringify-safe": { + "version": "5.0.1", + "from": "json-stringify-safe@>=5.0.1 <5.1.0", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + }, + "json3": { + "version": "3.3.2", + "from": "json3@>=3.3.2 <4.0.0", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz" + }, + "json5": { + "version": "0.4.0", + "from": "json5@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz" + }, + "jsonpointer": { + "version": "4.0.0", + "from": "jsonpointer@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.0.tgz" + }, + "jsprim": { + "version": "1.3.1", + "from": "jsprim@>=1.2.2 <2.0.0", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz" + }, + "kind-of": { + "version": "3.0.4", + "from": "kind-of@>=3.0.2 <4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.0.4.tgz" + }, + "load-json-file": { + "version": "1.1.0", + "from": "load-json-file@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz" + }, + "lodash": { + "version": "4.16.4", + "from": "lodash@>=4.2.0 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.16.4.tgz" + }, + "log-symbols": { + "version": "1.0.2", + "from": "log-symbols@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz" + }, + "loose-envify": { + "version": "1.2.0", + "from": "loose-envify@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.2.0.tgz", + "dependencies": { + "js-tokens": { + "version": "1.0.3", + "from": "js-tokens@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.3.tgz" + } + } + }, + "loud-rejection": { + "version": "1.6.0", + "from": "loud-rejection@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz" + }, + "map-obj": { + "version": "1.0.1", + "from": "map-obj@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz" + }, + "meow": { + "version": "3.7.0", + "from": "meow@>=3.5.0 <4.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz" + }, + "merge": { + "version": "1.2.0", + "from": "merge@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz" + }, + "methods": { + "version": "1.1.2", + "from": "methods@>=1.1.1 <1.2.0", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" + }, + "micromatch": { + "version": "2.3.11", + "from": "micromatch@>=2.1.5 <3.0.0", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz" + }, + "mime": { + "version": "1.3.4", + "from": "mime@1.3.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz" + }, + "mime-db": { + "version": "1.24.0", + "from": "mime-db@>=1.24.0 <1.25.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.24.0.tgz" + }, + "mime-types": { + "version": "2.1.12", + "from": "mime-types@>=2.1.7 <2.2.0", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.12.tgz" + }, + "minimatch": { + "version": "3.0.3", + "from": "minimatch@>=3.0.2 <4.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz" + }, + "minimist": { + "version": "1.2.0", + "from": "minimist@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" + }, + "mkdirp": { + "version": "0.5.1", + "from": "mkdirp@>=0.5.1 <0.6.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "dependencies": { + "minimist": { + "version": "0.0.8", + "from": "minimist@0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" + } + } + }, + "ms": { + "version": "0.7.1", + "from": "ms@0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz" + }, + "node-uuid": { + "version": "1.4.7", + "from": "node-uuid@>=1.4.7 <1.5.0", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz" + }, + "normalize-package-data": { + "version": "2.3.5", + "from": "normalize-package-data@>=2.3.4 <3.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.5.tgz" + }, + "normalize-path": { + "version": "2.0.1", + "from": "normalize-path@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.0.1.tgz" + }, + "number-is-nan": { + "version": "1.0.1", + "from": "number-is-nan@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" + }, + "oauth-sign": { + "version": "0.8.2", + "from": "oauth-sign@>=0.8.1 <0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz" + }, + "object-assign": { + "version": "4.1.0", + "from": "object-assign@>=4.0.1 <5.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz" + }, + "object.omit": { + "version": "2.0.0", + "from": "object.omit@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.0.tgz" + }, + "once": { + "version": "1.4.0", + "from": "once@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + }, + "original": { + "version": "1.0.0", + "from": "original@>=0.0.5", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz", + "dependencies": { + "url-parse": { + "version": "1.0.5", + "from": "url-parse@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz" + } + } + }, + "os-tmpdir": { + "version": "1.0.2", + "from": "os-tmpdir@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" + }, + "output-file-sync": { + "version": "1.1.2", + "from": "output-file-sync@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz" + }, + "parse-glob": { + "version": "3.0.4", + "from": "parse-glob@>=3.0.4 <4.0.0", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz" + }, + "parse-json": { + "version": "2.2.0", + "from": "parse-json@>=2.2.0 <3.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz" + }, + "path-exists": { + "version": "1.0.0", + "from": "path-exists@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz" + }, + "path-is-absolute": { + "version": "1.0.1", + "from": "path-is-absolute@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + }, + "path-type": { + "version": "1.1.0", + "from": "path-type@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz" + }, + "pify": { + "version": "2.3.0", + "from": "pify@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" + }, + "pinkie": { + "version": "2.0.4", + "from": "pinkie@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" + }, + "pinkie-promise": { + "version": "2.0.1", + "from": "pinkie-promise@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz" + }, + "preserve": { + "version": "0.2.0", + "from": "preserve@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz" + }, + "private": { + "version": "0.1.6", + "from": "private@>=0.1.6 <0.2.0", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.6.tgz" + }, + "process-nextick-args": { + "version": "1.0.7", + "from": "process-nextick-args@>=1.0.6 <1.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" + }, + "promise": { + "version": "6.1.0", + "from": "promise@>=6.1.0 <7.0.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-6.1.0.tgz" + }, + "qs": { + "version": "6.2.1", + "from": "qs@>=6.2.0 <6.3.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.1.tgz" + }, + "querystringify": { + "version": "0.0.4", + "from": "querystringify@>=0.0.0 <0.1.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz" + }, + "randomatic": { + "version": "1.1.5", + "from": "randomatic@>=1.1.3 <2.0.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.5.tgz" + }, + "read-pkg": { + "version": "1.1.0", + "from": "read-pkg@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz" + }, + "read-pkg-up": { + "version": "1.0.1", + "from": "read-pkg-up@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz" + }, + "readable-stream": { + "version": "2.1.5", + "from": "readable-stream@>=2.0.2 <3.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz" + }, + "readdirp": { + "version": "2.1.0", + "from": "readdirp@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz" + }, + "redent": { + "version": "1.0.0", + "from": "redent@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz" + }, + "reduce-component": { + "version": "1.0.1", + "from": "reduce-component@1.0.1", + "resolved": "https://registry.npmjs.org/reduce-component/-/reduce-component-1.0.1.tgz" + }, + "regenerate": { + "version": "1.3.1", + "from": "regenerate@>=1.2.1 <2.0.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.1.tgz" + }, + "regenerator-runtime": { + "version": "0.9.5", + "from": "regenerator-runtime@>=0.9.5 <0.10.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.9.5.tgz" + }, + "regex-cache": { + "version": "0.4.3", + "from": "regex-cache@>=0.4.2 <0.5.0", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz" + }, + "regexpu-core": { + "version": "2.0.0", + "from": "regexpu-core@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz" + }, + "regjsgen": { + "version": "0.2.0", + "from": "regjsgen@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz" + }, + "regjsparser": { + "version": "0.1.5", + "from": "regjsparser@>=0.1.4 <0.2.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "dependencies": { + "jsesc": { + "version": "0.5.0", + "from": "jsesc@>=0.5.0 <0.6.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" + } + } + }, + "repeat-element": { + "version": "1.1.2", + "from": "repeat-element@>=1.1.2 <2.0.0", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz" + }, + "repeat-string": { + "version": "1.5.4", + "from": "repeat-string@>=1.5.2 <2.0.0", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.5.4.tgz" + }, + "repeating": { + "version": "1.1.3", + "from": "repeating@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz" + }, + "request": { + "version": "2.75.0", + "from": "request@>=2.65.0 <3.0.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.75.0.tgz" + }, + "requires-port": { + "version": "1.0.0", + "from": "requires-port@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" + }, + "rimraf": { + "version": "2.5.4", + "from": "rimraf@>=2.4.3 <3.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", + "dependencies": { + "glob": { + "version": "7.1.1", + "from": "glob@>=7.0.5 <8.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz" + } + } + }, + "semver": { + "version": "4.3.6", + "from": "semver@>=4.0.3 <5.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz" + }, + "semver-regex": { + "version": "1.0.0", + "from": "semver-regex@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-1.0.0.tgz" + }, + "semver-truncate": { + "version": "1.1.2", + "from": "semver-truncate@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz", + "dependencies": { + "semver": { + "version": "5.3.0", + "from": "semver@>=5.3.0 <6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz" + } + } + }, + "set-immediate-shim": { + "version": "1.0.1", + "from": "set-immediate-shim@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz" + }, + "shebang-regex": { + "version": "1.0.0", + "from": "shebang-regex@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz" + }, + "signal-exit": { + "version": "3.0.1", + "from": "signal-exit@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.1.tgz" + }, + "slash": { + "version": "1.0.0", + "from": "slash@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz" + }, + "slugid": { + "version": "1.1.0", + "from": "slugid@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/slugid/-/slugid-1.1.0.tgz" + }, + "sntp": { + "version": "1.0.9", + "from": "sntp@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz" + }, + "sockjs-client": { + "version": "1.1.1", + "from": "sockjs-client@>=1.0.3 <2.0.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.1.tgz" + }, + "source-map": { + "version": "0.5.6", + "from": "source-map@>=0.5.0 <0.6.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz" + }, + "source-map-support": { + "version": "0.4.3", + "from": "source-map-support@>=0.4.2 <0.5.0", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.3.tgz" + }, + "spdx-correct": { + "version": "1.0.2", + "from": "spdx-correct@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz" + }, + "spdx-expression-parse": { + "version": "1.0.4", + "from": "spdx-expression-parse@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz" + }, + "spdx-license-ids": { + "version": "1.2.2", + "from": "spdx-license-ids@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz" + }, + "sprintf-js": { + "version": "1.0.3", + "from": "sprintf-js@>=1.0.2 <1.1.0", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + }, + "sshpk": { + "version": "1.10.1", + "from": "sshpk@>=1.7.0 <2.0.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.10.1.tgz", + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "from": "assert-plus@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + } + } + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "stringstream": { + "version": "0.0.5", + "from": "stringstream@>=0.0.4 <0.1.0", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz" + }, + "strip-ansi": { + "version": "3.0.1", + "from": "strip-ansi@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" + }, + "strip-bom": { + "version": "2.0.0", + "from": "strip-bom@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz" + }, + "strip-indent": { + "version": "1.0.1", + "from": "strip-indent@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz" + }, + "superagent": { + "version": "1.7.2", + "from": "superagent@>=1.7.0 <1.8.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-1.7.2.tgz", + "dependencies": { + "async": { + "version": "0.9.2", + "from": "async@>=0.9.0 <0.10.0", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz" + }, + "combined-stream": { + "version": "0.0.7", + "from": "combined-stream@>=0.0.4 <0.1.0", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz" + }, + "delayed-stream": { + "version": "0.0.5", + "from": "delayed-stream@0.0.5", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz" + }, + "form-data": { + "version": "0.2.0", + "from": "form-data@0.2.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz" + }, + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "mime-db": { + "version": "1.12.0", + "from": "mime-db@>=1.12.0 <1.13.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz" + }, + "mime-types": { + "version": "2.0.14", + "from": "mime-types@>=2.0.3 <2.1.0", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz" + }, + "qs": { + "version": "2.3.3", + "from": "qs@2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz" + }, + "readable-stream": { + "version": "1.0.27-1", + "from": "readable-stream@1.0.27-1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.27-1.tgz" + } + } + }, + "superagent-hawk": { + "version": "0.0.6", + "from": "superagent-hawk@>=0.0.6 <0.0.7", + "resolved": "https://registry.npmjs.org/superagent-hawk/-/superagent-hawk-0.0.6.tgz", + "dependencies": { + "boom": { + "version": "0.4.2", + "from": "boom@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz" + }, + "cryptiles": { + "version": "0.2.2", + "from": "cryptiles@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz" + }, + "hawk": { + "version": "1.0.0", + "from": "hawk@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz" + }, + "hoek": { + "version": "0.9.1", + "from": "hoek@>=0.9.0 <0.10.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz" + }, + "qs": { + "version": "0.6.6", + "from": "qs@>=0.6.6 <0.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz" + }, + "sntp": { + "version": "0.2.4", + "from": "sntp@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz" + } + } + }, + "superagent-promise": { + "version": "0.2.0", + "from": "superagent-promise@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/superagent-promise/-/superagent-promise-0.2.0.tgz" + }, + "supports-color": { + "version": "2.0.0", + "from": "supports-color@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" + }, + "taskcluster-client": { + "version": "1.4.0", + "from": "taskcluster-client@>=1.2.1 <2.0.0", + "resolved": "https://registry.npmjs.org/taskcluster-client/-/taskcluster-client-1.4.0.tgz", + "dependencies": { + "hawk": { + "version": "2.3.1", + "from": "hawk@>=2.3.1 <3.0.0", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz" + }, + "lodash": { + "version": "3.10.1", + "from": "lodash@>=3.6.0 <4.0.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" + } + } + }, + "to-fast-properties": { + "version": "1.0.2", + "from": "to-fast-properties@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.2.tgz" + }, + "tough-cookie": { + "version": "2.3.1", + "from": "tough-cookie@>=2.3.0 <2.4.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz" + }, + "trim-newlines": { + "version": "1.0.0", + "from": "trim-newlines@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz" + }, + "tunnel-agent": { + "version": "0.4.3", + "from": "tunnel-agent@>=0.4.1 <0.5.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz" + }, + "tweetnacl": { + "version": "0.14.3", + "from": "tweetnacl@>=0.14.0 <0.15.0", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.3.tgz" + }, + "url-join": { + "version": "0.0.1", + "from": "url-join@>=0.0.1 <0.0.2", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz" + }, + "url-parse": { + "version": "1.1.6", + "from": "url-parse@>=1.1.1 <2.0.0", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.1.6.tgz" + }, + "user-home": { + "version": "1.1.1", + "from": "user-home@>=1.1.1 <2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz" + }, + "util-deprecate": { + "version": "1.0.2", + "from": "util-deprecate@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + }, + "uuid": { + "version": "2.0.3", + "from": "uuid@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz" + }, + "v8flags": { + "version": "2.0.11", + "from": "v8flags@>=2.0.10 <3.0.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.0.11.tgz" + }, + "validate-npm-package-license": { + "version": "3.0.1", + "from": "validate-npm-package-license@>=3.0.1 <4.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz" + }, + "verror": { + "version": "1.3.6", + "from": "verror@1.3.6", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz" + }, + "websocket-driver": { + "version": "0.6.5", + "from": "websocket-driver@>=0.5.1", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz" + }, + "websocket-extensions": { + "version": "0.1.1", + "from": "websocket-extensions@>=0.1.1", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.1.tgz" + }, + "when": { + "version": "3.6.4", + "from": "when@>=3.6.2 <3.7.0", + "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz" + }, + "wrappy": { + "version": "1.0.2", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + }, + "xtend": { + "version": "4.0.1", + "from": "xtend@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + } + } +} diff --git a/security/nss/automation/taskcluster/graph/package.json b/security/nss/automation/taskcluster/graph/package.json new file mode 100644 index 000000000..d866adebc --- /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": "^1.2.1" + } +} 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 000000000..f0a2e9a88 --- /dev/null +++ b/security/nss/automation/taskcluster/graph/src/context_hash.js @@ -0,0 +1,43 @@ +/* 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]; + }); +} + +// Compute a context hash for the given context path. +export default function (context_path) { + let root = path.join(__dirname, "../../../.."); + let dir = path.join(root, context_path); + let files = collectFilesInDirectory(dir).sort(); + let hashes = files.map(file => { + return sha256(file + "|" + fs.readFileSync(file, "utf-8")); + }); + + // 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 000000000..a6a8fcbe2 --- /dev/null +++ b/security/nss/automation/taskcluster/graph/src/extend.js @@ -0,0 +1,572 @@ +/* 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 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)\""; + +/*****************************************************************************/ + +queue.filter(task => { + if (task.group == "Builds") { + // Remove extra builds on {A,UB}San and ARM. + if (task.collection == "asan" || task.collection == "arm-debug" || + task.collection == "gyp-asan") { + return false; + } + + // Remove extra builds w/o libpkix for non-linux64-debug. + if (task.symbol == "noLibpkix" && + (task.platform != "linux64" || task.collection != "debug")) { + return false; + } + } + + if (task.tests == "bogo") { + // No BoGo tests on Windows. + if (task.platform == "windows2012-64") { + return false; + } + + // No BoGo tests on ARM. + if (task.collection == "arm-debug") { + return false; + } + } + + // GYP builds with -Ddisable_libpkix=1 by default. + if ((task.collection == "gyp" || task.collection == "gyp-asan") && + task.tests == "chains") { + return false; + } + + return true; +}); + +queue.map(task => { + if (task.collection == "asan" || task.collection == "gyp-asan") { + // CRMF and FIPS tests still leak, unfortunately. + if (task.tests == "crmf" || task.tests == "fips") { + task.env.ASAN_OPTIONS = "detect_leaks=0"; + } + } + + if (task.collection == "arm-debug") { + // These tests take quite some time on our poor ARM devices. + if (task.tests == "chains" || (task.tests == "ssl" && task.cycle == "standard")) { + task.maxRunTime = 14400; + } + } + + // Windows is slow. + if (task.platform == "windows2012-64" && task.tests == "chains") { + task.maxRunTime = 7200; + } + + // Enable TLS 1.3 for every task. + task.env = task.env || {}; + task.env.NSS_ENABLE_TLS_1_3 = "1"; + + return task; +}); + +/*****************************************************************************/ + +export default async function main() { + await scheduleLinux("Linux 32 (opt)", { + env: {BUILD_OPT: "1"}, + platform: "linux32", + image: LINUX_IMAGE + }); + + await scheduleLinux("Linux 32 (debug)", { + platform: "linux32", + collection: "debug", + image: LINUX_IMAGE + }); + + await scheduleLinux("Linux 64 (opt)", { + env: {USE_64: "1", BUILD_OPT: "1"}, + platform: "linux64", + image: LINUX_IMAGE + }); + + await scheduleLinux("Linux 64 (debug)", { + env: {USE_64: "1"}, + platform: "linux64", + collection: "debug", + image: LINUX_IMAGE + }); + + await scheduleLinux("Linux 64 (debug, gyp)", { + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh" + ], + platform: "linux64", + collection: "gyp", + image: LINUX_IMAGE + }); + + await scheduleLinux("Linux 64 (debug, gyp, asan, ubsan)", { + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh -g -v --ubsan --asan" + ], + env: { + ASAN_OPTIONS: "detect_odr_violation=0", // bug 1316276 + UBSAN_OPTIONS: "print_stacktrace=1", + NSS_DISABLE_ARENA_FREE_LIST: "1", + NSS_DISABLE_UNLOAD: "1", + CC: "clang", + CCC: "clang++" + }, + platform: "linux64", + collection: "gyp-asan", + image: LINUX_IMAGE + }); + + 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++", + USE_UBSAN: "1", + USE_ASAN: "1", + USE_64: "1" + }, + platform: "linux64", + collection: "asan", + image: LINUX_IMAGE + }); + + await scheduleWindows("Windows 2012 64 (opt)", { + env: {BUILD_OPT: "1"} + }); + + await scheduleWindows("Windows 2012 64 (debug)", { + collection: "debug" + }); + + await scheduleFuzzing(); + + await scheduleTestBuilds(); + + await scheduleTools(); + + await scheduleLinux("Linux 32 (ARM, debug)", { + image: "franziskus/nss-arm-ci", + provisioner: "localprovisioner", + collection: "arm-debug", + workerType: "nss-rpi", + platform: "linux32", + maxRunTime: 7200, + tier: 3 + }); +} + +/*****************************************************************************/ + +async function scheduleLinux(name, base) { + // Build base definition. + let build_base = merge({ + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh" + ], + artifacts: { + public: { + expires: 24 * 7, + type: "directory", + path: "/home/worker/artifacts" + } + }, + kind: "build", + symbol: "B" + }, base); + + // 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: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/gen_certs.sh" + ], + parent: task_build, + symbol: "Certs" + })); + + // 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({group: "Builds"}, build_base); + queue.scheduleTask(merge(extra_base, { + name: `${name} w/ clang-3.9`, + env: { + CC: "clang", + CCC: "clang++", + }, + symbol: "clang-3.9" + })); + + queue.scheduleTask(merge(extra_base, { + name: `${name} w/ gcc-4.8`, + env: { + CC: "gcc-4.8", + CCC: "g++-4.8" + }, + symbol: "gcc-4.8" + })); + + queue.scheduleTask(merge(extra_base, { + name: `${name} w/ gcc-6.1`, + env: { + CC: "gcc-6", + CCC: "g++-6" + }, + symbol: "gcc-6.1" + })); + + queue.scheduleTask(merge(extra_base, { + name: `${name} w/ NSS_DISABLE_LIBPKIX=1`, + env: {NSS_DISABLE_LIBPKIX: "1"}, + symbol: "noLibpkix" + })); + + return queue.submit(); +} + +/*****************************************************************************/ + +async function scheduleFuzzing() { + let base = { + env: { + // bug 1316276 + ASAN_OPTIONS: "allocator_may_return_null=1:detect_odr_violation=0", + UBSAN_OPTIONS: "print_stacktrace=1", + NSS_DISABLE_ARENA_FREE_LIST: "1", + NSS_DISABLE_UNLOAD: "1", + CC: "clang", + CCC: "clang++" + }, + platform: "linux64", + collection: "fuzz", + image: LINUX_IMAGE + }; + + // Build base definition. + let build_base = merge({ + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && " + + "nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz" + ], + artifacts: { + public: { + expires: 24 * 7, + type: "directory", + path: "/home/worker/artifacts" + } + }, + kind: "build", + symbol: "B" + }, base); + + // The task that builds NSPR+NSS. + let task_build = queue.scheduleTask(merge(build_base, { + name: "Linux x64 (debug, fuzz)" + })); + + // Schedule tests. + queue.scheduleTask(merge(base, { + parent: task_build, + 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" + })); + + queue.scheduleTask(merge(base, { + parent: task_build, + name: "Cert", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/fuzz.sh " + + "cert nss/fuzz/corpus/cert -max_total_time=300" + ], + // Need a privileged docker container to remove this. + env: {ASAN_OPTIONS: "detect_leaks=0"}, + symbol: "SCert", + kind: "test" + })); + + queue.scheduleTask(merge(base, { + parent: task_build, + name: "SPKI", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/fuzz.sh " + + "spki nss/fuzz/corpus/spki -max_total_time=300" + ], + // Need a privileged docker container to remove this. + env: {ASAN_OPTIONS: "detect_leaks=0"}, + symbol: "SPKI", + kind: "test" + })); + + return queue.submit(); +} + +/*****************************************************************************/ + +async function scheduleTestBuilds() { + let base = { + platform: "linux64", + collection: "gyp", + group: "Test", + image: LINUX_IMAGE + }; + + // Build base definition. + let build = merge({ + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && " + + "nss/automation/taskcluster/scripts/build_gyp.sh -g -v --test" + ], + artifacts: { + public: { + expires: 24 * 7, + type: "directory", + path: "/home/worker/artifacts" + } + }, + kind: "build", + symbol: "B", + name: "Linux 64 (debug, gyp, test)" + }, base); + + // The task that builds NSPR+NSS. + let task_build = queue.scheduleTask(build); + + // Schedule tests. + queue.scheduleTask(merge(base, { + parent: task_build, + name: "mpi", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/run_tests.sh" + ], + tests: "mpi", + cycle: "standard", + symbol: "mpi", + kind: "test" + })); + + return queue.submit(); +} + + +/*****************************************************************************/ + +async function scheduleWindows(name, base) { + base = merge(base, { + workerType: "nss-win2012r2", + platform: "windows2012-64", + env: { + PATH: "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", + USE_64: "1" + } + }); + + // Build base definition. + let build_base = merge(base, { + command: [ + WINDOWS_CHECKOUT_CMD, + "bash -c nss/automation/taskcluster/windows/build.sh" + ], + artifacts: [{ + expires: 24 * 7, + type: "directory", + path: "public\\build" + }], + kind: "build", + 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: [ + 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({kind: "test"}, test_base); + + // Schedule tests that do NOT need certificates. + let no_cert_base = merge(test_base, {parent: task_build}); + 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" + })); + queue.scheduleTask(merge(no_cert_base, { + name: "Chains tests", symbol: "Chains", tests: "chains" + })); + queue.scheduleTask(merge(no_cert_base, { + name: "Cipher tests", symbol: "Cipher", tests: "cipher" + })); + queue.scheduleTask(merge(no_cert_base, { + name: "EC tests", symbol: "EC", tests: "ec" + })); + queue.scheduleTask(merge(no_cert_base, { + name: "Lowhash tests", symbol: "Lowhash", tests: "lowhash" + })); + queue.scheduleTask(merge(no_cert_base, { + name: "SDR tests", symbol: "SDR", tests: "sdr" + })); + + // Schedule tests that need certificates. + let cert_base = merge(test_base, {parent: task_cert}); + 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: "FIPS tests", symbol: "FIPS", tests: "fips" + })); + 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 (sharedb)", symbol: "sharedb", cycle: "sharedb" + })); + queue.scheduleTask(merge(ssl_base, { + name: "SSL tests (upgradedb)", symbol: "upgradedb", cycle: "upgradedb" + })); +} + +/*****************************************************************************/ + +async function scheduleTools() { + let base = { + image: LINUX_IMAGE, + platform: "nss-tools", + kind: "test" + }; + + queue.scheduleTask(merge(base, { + symbol: "clang-format-3.9", + name: "clang-format-3.9", + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/run_clang_format.sh" + ] + })); + + queue.scheduleTask(merge(base, { + symbol: "scan-build-3.9", + name: "scan-build-3.9", + 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" + ] + })); + + 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 000000000..bc90e0242 --- /dev/null +++ b/security/nss/automation/taskcluster/graph/src/image_builder.js @@ -0,0 +1,62 @@ +/* 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(); + let {artifacts} = await queue.listLatestArtifacts(taskId); + return artifacts.some(artifact => artifact.name == "public/image.tar"); +} + +async function findTaskWithImageArtifact(ns) { + let index = new taskcluster.Index(); + 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", + image: "taskcluster/image_builder:0.1.5", + routes: ["index." + ns], + env: { + HEAD_REPOSITORY: process.env.NSS_HEAD_REPOSITORY, + BASE_REPOSITORY: process.env.NSS_HEAD_REPOSITORY, + HEAD_REV: process.env.NSS_HEAD_REVISION, + HEAD_REF: process.env.NSS_HEAD_REVISION, + PROJECT: process.env.TC_PROJECT, + CONTEXT_PATH: path, + HASH: hash + }, + artifacts: { + "public/image.tar": { + type: "file", + expires: 24 * 90, + path: "/artifacts/image.tar" + } + }, + command: [ + "/bin/bash", + "-c", + "/home/worker/bin/build_image.sh" + ], + platform: "nss-decision", + features: ["dind"], + 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 000000000..4153e1b18 --- /dev/null +++ b/security/nss/automation/taskcluster/graph/src/index.js @@ -0,0 +1,14 @@ +/* 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 extend from "./extend"; + +// Init try syntax filter. +if (process.env.TC_PROJECT == "nss-try") { + try_syntax.initFilter(); +} + +// Extend the task graph. +extend().catch(console.error); 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 000000000..17043dd8e --- /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 000000000..2a4a7b3fe --- /dev/null +++ b/security/nss/automation/taskcluster/graph/src/queue.js @@ -0,0 +1,242 @@ +/* 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 image_tasks = new Map(); + +let queue = new taskcluster.Queue({ + baseUrl: "http://taskcluster/queue/v1" +}); + +function fromNow(hours) { + let d = new Date(); + d.setHours(d.getHours() + (hours|0)); + return d.toJSON(); +} + +function parseRoutes(routes) { + return [ + `tc-treeherder.v2.${process.env.TC_PROJECT}.${process.env.NSS_HEAD_REVISION}.${process.env.NSS_PUSHLOG_ID}`, + ...routes + ]; +} + +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 dependencies = []; + + let env = merge({ + NSS_HEAD_REPOSITORY: process.env.NSS_HEAD_REPOSITORY, + NSS_HEAD_REVISION: process.env.NSS_HEAD_REVISION + }, def.env || {}); + + if (def.parent) { + dependencies.push(def.parent); + env.TC_PARENT_TASK_ID = def.parent; + } + + if (def.tests) { + env.NSS_TESTS = def.tests; + } + + if (def.cycle) { + env.NSS_CYCLES = def.cycle; + } + + let payload = { + env, + command: def.command, + maxRunTime: def.maxRunTime || 3600 + }; + + if (def.image) { + payload.image = def.image; + } + + if (def.features) { + payload.features = parseFeatures(def.features); + } + + if (def.artifacts) { + payload.artifacts = parseArtifacts(def.artifacts); + } + + return { + provisionerId: def.provisioner || "aws-provisioner-v1", + workerType: def.workerType || "hg-worker", + schedulerId: "task-graph-scheduler", + + created: fromNow(0), + deadline: fromNow(24), + + dependencies, + routes: parseRoutes(def.routes || []), + + metadata: { + name: def.name, + description: def.name, + owner: process.env.TC_OWNER, + source: process.env.TC_SOURCE + }, + + payload, + + extra: { + treeherder: parseTreeherder(def) + } + }; +} + +export function map(fun) { + maps.push(fun); +} + +export function filter(fun) { + filters.push(fun); +} + +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"}]`; + console.log(`+ Submitting ${log_id}.`); + + 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", + 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 000000000..695c9e92f --- /dev/null +++ b/security/nss/automation/taskcluster/graph/src/try_syntax.js @@ -0,0 +1,159 @@ +/* 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 intersect from "intersect"; +import parse_args from "minimist"; + +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", "win64", "arm", + "linux64-gyp", "linux64-gyp-asan", "linux64-fuzz"]; + 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", "lowhash", "merge", "sdr", "smime", "tools", + "ssl", "mpi", "scert", "spki"]; + 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"]; + 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); + }); + } + + // Filter unit tests. + if (task.tests) { + let found = opts.unittests.some(test => { + // TODO: think of something more intelligent here. + if (task.symbol.toLowerCase().startsWith("mpi") && test == "mpi") { + return true; + } + return (task.group || 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 = { + "linux": "linux32", + "linux64-asan": "linux64", + "linux64-fuzz": "linux64", + "linux64-gyp": "linux64", + "linux64-gyp-asan": "linux64", + "win64": "windows2012-64", + "arm": "linux32" + }; + + // Check the platform name. + let keep = (task.platform == (aliases[platform] || platform)); + + // Additional checks. + if (platform == "linux64-asan") { + keep &= coll("asan"); + } else if (platform == "arm") { + keep &= coll("arm-opt") || coll("arm-debug"); + } else if (platform == "linux64-gyp") { + keep &= coll("gyp"); + } else if (platform == "linux64-gyp-asan") { + keep &= coll("gyp-asan"); + } else if (platform == "linux64-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("arm-debug") || + coll("gyp") || coll("fuzz"); + return (isDebug && opts.builds.includes("d")) || + (!isDebug && opts.builds.includes("o")); + } +} + +export function initFilter() { + let comment = process.env.TC_COMMENT || ""; + + // Check for try syntax in changeset comment. + let match = comment.match(/^\s*try:\s*(.*)\s*$/); + + // Add try syntax filter. + if (match) { + queue.filter(filter(parseOptions(match[1]))); + } +} diff --git a/security/nss/automation/taskcluster/scripts/build.sh b/security/nss/automation/taskcluster/scripts/build.sh new file mode 100755 index 000000000..69968b138 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/build.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +source $(dirname $0)/tools.sh + +if [[ $(id -u) -eq 0 ]]; then + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# Clone NSPR if needed. +hg_clone https://hg.mozilla.org/projects/nspr nspr default + +# 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 000000000..590e634a3 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/build_gyp.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +source $(dirname $0)/tools.sh + +if [[ $(id -u) -eq 0 ]]; then + # Drop privileges by re-running this script. + exec su worker -c "$0 $*" +fi + +# Clone NSPR if needed. +hg_clone https://hg.mozilla.org/projects/nspr nspr default + +# Build. +nss/build.sh ${*--g -v} + +# Package. +mkdir artifacts +tar cvfjh artifacts/dist.tar.bz2 dist 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 000000000..5a3fb8d98 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/extend_task_graph.sh @@ -0,0 +1,16 @@ +#!/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 + +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 000000000..5f8dd7bff --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/fuzz.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +source $(dirname $0)/tools.sh + +if [ $(id -u) = 0 ]; then + # Drop privileges by re-running this script. + exec su worker -c "$0 $*" +fi + +# Fetch artifact if needed. +fetch_dist + +# Clone corpus. +./nss/fuzz/clone_corpus.sh + +# Fetch objdir name. +objdir=$(cat dist/latest) + +# Run nssfuzz. +LD_LIBRARY_PATH=$LD_LIBRARY_PATH:dist/$objdir/lib dist/$objdir/bin/nssfuzz $* 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 000000000..aee100147 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/gen_certs.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +set -v -e -x + +source $(dirname $0)/tools.sh + +if [ $(id -u) = 0 ]; then + # Stupid Docker. + echo "127.0.0.1 localhost.localdomain" >> /etc/hosts + + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# 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. +mkdir artifacts +tar cvfjh artifacts/dist.tar.bz2 dist tests_results diff --git a/security/nss/automation/taskcluster/scripts/run_clang_format.sh b/security/nss/automation/taskcluster/scripts/run_clang_format.sh new file mode 100755 index 000000000..c4b60290f --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/run_clang_format.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +set -v -e -x + +if [ $(id -u) -eq 0 ]; then + # Drop privileges by re-running this script. + exec su worker $0 "$@" +fi + +# 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. + +if [ $# -gt 0 ]; then + dirs=("$@") +else + top=$(dirname $0)/../../.. + dirs=( \ + "$top/cmd" \ + "$top/fuzz" \ + "$top/lib/base" \ + "$top/lib/certdb" \ + "$top/lib/certhigh" \ + "$top/lib/ckfw" \ + "$top/lib/crmf" \ + "$top/lib/cryptohi" \ + "$top/lib/dbm" \ + "$top/lib/dev" \ + "$top/lib/freebl" \ + "$top/lib/jar" \ + "$top/lib/nss" \ + "$top/lib/pk11wrap" \ + "$top/lib/pkcs7" \ + "$top/lib/pkcs12" \ + "$top/lib/pki" \ + "$top/lib/smime" \ + "$top/lib/softoken" \ + "$top/lib/ssl" \ + "$top/lib/sysinit" \ + "$top/lib/util" \ + "$top/gtests/common" \ + "$top/gtests/der_gtest" \ + "$top/gtests/freebl_gtest" \ + "$top/gtests/pk11_gtest" \ + "$top/gtests/ssl_gtest" \ + "$top/gtests/util_gtest" \ + ) +fi + +for dir in "${dirs[@]}"; do + find "$dir" -type f \( -name '*.[ch]' -o -name '*.cc' \) -exec clang-format -i {} \+ +done + +TMPFILE=$(mktemp /tmp/$(basename $0).XXXXXX) +trap 'rm $TMPFILE' exit +if (cd $(dirname $0); hg root >/dev/null 2>&1); then + hg diff --git "$top" | tee $TMPFILE +else + git -C "$top" diff | tee $TMPFILE +fi +[[ ! -s $TMPFILE ]] 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 000000000..99f80ab5f --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/run_scan_build.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +source $(dirname $0)/tools.sh + +if [ $(id -u) = 0 ]; then + # Drop privileges by re-running this script. + exec su worker $0 $@ +fi + +# Clone NSPR if needed. +if [ ! -d "nspr" ]; then + hg_clone https://hg.mozilla.org/projects/nspr nspr default +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 -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 000000000..4c87e7e32 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/run_tests.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +source $(dirname $0)/tools.sh + +if [ $(id -u) = 0 ]; then + # Stupid Docker. + echo "127.0.0.1 localhost.localdomain" >> /etc/hosts + + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# Fetch artifact if needed. +fetch_dist + +# Run tests. +cd nss/tests && ./all.sh diff --git a/security/nss/automation/taskcluster/scripts/tools.sh b/security/nss/automation/taskcluster/scripts/tools.sh new file mode 100644 index 000000000..dacfdeb28 --- /dev/null +++ b/security/nss/automation/taskcluster/scripts/tools.sh @@ -0,0 +1,28 @@ +#!/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 +} + +fetch_dist() { + url=https://queue.taskcluster.net/v1/task/$TC_PARENT_TASK_ID/artifacts/public/dist.tar.bz2 + 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 000000000..6c8a47470 --- /dev/null +++ b/security/nss/automation/taskcluster/windows/build.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Set up the toolchain. +source $(dirname $0)/setup.sh + +# Clone NSPR. +hg_clone https://hg.mozilla.org/projects/nspr nspr default + +# Build. +make -C nss nss_build_all + +# 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 000000000..ead16bbc3 --- /dev/null +++ b/security/nss/automation/taskcluster/windows/gen_certs.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Set up the toolchain. +source $(dirname $0)/setup.sh + +# Fetch artifact. +wget -t 3 --retry-connrefused -w 5 --random-wait https://queue.taskcluster.net/v1/task/$TC_PARENT_TASK_ID/artifacts/public/build/dist.7z -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 000000000..b3f449854 --- /dev/null +++ b/security/nss/automation/taskcluster/windows/releng.manifest @@ -0,0 +1,10 @@ +[ + { + "version": "Visual Studio 2015 Update 2 / SDK 10.0.10586.0/212", + "size": 332442800, + "digest": "995394a4a515c7cb0f8595f26f5395361a638870dd0bbfcc22193fe1d98a0c47126057d5999cc494f3f3eac5cb49160e79757c468f83ee5797298e286ef6252c", + "algorithm": "sha512", + "filename": "vs2015u2.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 000000000..f64a78e30 --- /dev/null +++ b/security/nss/automation/taskcluster/windows/run_tests.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Set up the toolchain. +source $(dirname $0)/setup.sh + +# Fetch artifact. +wget -t 3 --retry-connrefused -w 5 --random-wait https://queue.taskcluster.net/v1/task/$TC_PARENT_TASK_ID/artifacts/public/build/dist.7z -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 000000000..80cee2850 --- /dev/null +++ b/security/nss/automation/taskcluster/windows/setup.sh @@ -0,0 +1,30 @@ +#!/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 default + +tools/scripts/tooltool/tooltool_wrapper.sh $(dirname $0)/releng.manifest https://api.pub.build.mozilla.org/tooltool/ non-existant-file.sh /c/mozilla-build/python/python.exe /c/builds/tooltool.py --authentication-file /c/builds/relengapi.tok -c /c/builds/tooltool_cache +VSPATH="$(pwd)/vs2015u2" + +export WINDOWSSDKDIR="${VSPATH}/SDK" +export WIN32_REDIST_DIR="${VSPATH}/VC/redist/x64/Microsoft.VC140.CRT" +export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x64" + +export PATH="${VSPATH}/VC/bin/amd64:${VSPATH}/VC/bin:${VSPATH}/SDK/bin/x64:${VSPATH}/VC/redist/x64/Microsoft.VC140.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${PATH}" + +export INCLUDE="${VSPATH}/VC/include:${VSPATH}/SDK/Include/10.0.10586.0/ucrt:${VSPATH}/SDK/Include/10.0.10586.0/shared:${VSPATH}/SDK/Include/10.0.10586.0/um" +export LIB="${VSPATH}/VC/lib/amd64:${VSPATH}/SDK/lib/10.0.10586.0/ucrt/x64:${VSPATH}/SDK/lib/10.0.10586.0/um/x64" |