From e7010b7bbca1fd1fa3674efda7ba34d3dd0327e0 Mon Sep 17 00:00:00 2001 From: sophia Date: Mon, 26 Oct 2020 11:52:52 -0500 Subject: [PATCH] Load ci --- .ci/common.sh | 551 -------------------------------------- .ci/init.sh | 2 +- .ci/load-ci.sh | 52 ++++ .ci/slack | 176 ------------ .ci/spec/clean-packet.sh | 2 +- .ci/spec/create-hosts.sh | 2 +- .ci/spec/create-packet.sh | 2 +- .ci/spec/run-test.sh | 2 +- .ci/sync.sh | 2 +- 9 files changed, 58 insertions(+), 733 deletions(-) delete mode 100755 .ci/common.sh create mode 100644 .ci/load-ci.sh delete mode 100755 .ci/slack diff --git a/.ci/common.sh b/.ci/common.sh deleted file mode 100755 index d4e594893..000000000 --- a/.ci/common.sh +++ /dev/null @@ -1,551 +0,0 @@ -# last-modified: Thu Sep 3 20:54:51 UTC 2020 -#!/usr/bin/env bash - -# Path to file used for output redirect -# and extracting messages for warning and -# failure information sent to slack -function output_file() { - if [ "${1}" = "clean" ] && [ -f "${ci_output_file_path}" ]; then - rm -f "${ci_output_file_path}" - fi - if [ -z "${ci_output_file_path}" ] || [ ! -f "${ci_output_file_path}" ]; then - ci_output_file_path="$(mktemp)" - fi - printf "${ci_output_file_path}" -} - -# Write failure message, send error to configured -# slack, and exit with non-zero status. If an -# "$(output_file)" file exists, the last 5 lines will be -# included in the slack message. -# -# $1: Failure message -function fail() { - (>&2 echo "ERROR: ${1}") - if [ -f ""$(output_file)"" ]; then - slack -s error -m "ERROR: ${1}" -f "$(output_file)" -T 5 - else - slack -s error -m "ERROR: ${1}" - fi - exit 1 -} - -# Write warning message, send warning to configured -# slack -# -# $1: Warning message -function warn() { - (>&2 echo "WARN: ${1}") - if [ -f ""$(output_file)"" ]; then - slack -s warn -m "WARNING: ${1}" -f "$(output_file)" - else - slack -s warn -m "WARNING: ${1}" - fi -} - -# Execute command while redirecting all output to -# a file (file is used within fail mesage on when -# command is unsuccessful). Final argument is the -# error message used when the command fails. -# -# $@{1:$#-1}: Command to execute -# $@{$#}: Failure message -function wrap() { - i=$(("${#}" - 1)) - wrap_raw "${@:1:$i}" - if [ $? -ne 0 ]; then - cat "$(output_file)" - fail "${@:$#}" - fi - rm "$(output_file)" -} - -# Execute command while redirecting all output to -# a file. Exit status is returned. -function wrap_raw() { - output_file "clean" - "${@}" > "$(output_file)" 2>&1 - return $? -} - -# Execute command while redirecting all output to -# a file (file is used within fail mesage on when -# command is unsuccessful). Command output will be -# streamed during execution. Final argument is the -# error message used when the command fails. -# -# $@{1:$#-1}: Command to execute -# $@{$#}: Failure message -function wrap_stream() { - i=$(("${#}" - 1)) - wrap_stream_raw "${@:1:$i}" - if [ $? -ne 0 ]; then - fail "${@:$#}" - fi - rm "$(output_file)" -} - -# Execute command while redirecting all output -# to a file. Command output will be streamed -# during execution. Exit status is returned -function wrap_stream_raw() { - output_file "clean" - "${@}" > "$(output_file)" 2>&1 & - pid=$! - until [ -f "$(output_file)" ]; do - sleep 0.1 - done - tail -f --quiet --pid "${pid}" "$(output_file)" - wait "${pid}" - return $? -} - - -# Send command to packet device and wrap -# execution -# $@{1:$#-1}: Command to execute -# $@{$#}: Failure message -function pkt_wrap() { - wrap packet-exec run -quiet -- "${@}" -} - -# Send command to packet device and wrap -# execution -# $@: Command to execute -function pkt_wrap_raw() { - wrap_raw packet-exec run -quiet -- "${@}" -} - -# Send command to packet device and wrap -# execution with output streaming -# $@{1:$#-1}: Command to execute -# $@{$#}: Failure message -function pkt_wrap_stream() { - wrap_stream packet-exec run -quiet -- "${@}" -} - -# Send command to packet device and wrap -# execution with output streaming -# $@: Command to execute -function pkt_wrap_stream_raw() { - wrap_stream_raw packet-exec run -quiet -- "${@}" -} - -# Generates location within the asset storage -# bucket to retain built assets. -function asset_location() { - if [ ! -z "${tag}" ]; then - dst="${ASSETS_PRIVATE_LONGTERM}/${repository}/${ident_ref}" - else - if [[ "${tag}" = *"+"* ]]; then - dst="${ASSETS_PRIVATE_LONGTERM}/${repository}/${tag}" - else - dst="${ASSETS_PRIVATE_BUCKET}/${repository}/${tag}" - fi - fi - echo -n "${dst}" -} - -# Upload assets to the asset storage bucket. -# -# $1: Path to asset file or directory to upload -function upload_assets() { - if [ "${1}" = "" ]; then - fail "Parameter required for asset upload" - fi - if [ -d "${1}" ]; then - wrap aws s3 cp --recursive "${1}" "$(asset_location)/" \ - "Upload to asset storage failed" - else - wrap aws s3 cp "${1}" "$(asset_location)/" \ - "Upload to asset storage failed" - fi -} - -# Download assets from the asset storage bucket. If -# destination is not provided, remote path will be -# used locally. -# -# $1: Path to asset or directory to download -# $2: Optional destination for downloaded assets -function download_assets() { - if [ "${1}" = "" ]; then - fail "At least one parameter required for asset download" - fi - if [ "${2}" = "" ]; then - dst="${1#/}" - else - dst="${2}" - fi - mkdir -p "${dst}" - src="$(asset_location)/${1#/}" - remote=$(aws s3 ls "${src}") - if [[ "${remote}" = *" PRE "* ]]; then - mkdir -p "${dst}" - wrap aws s3 cp --recursive "${src%/}/" "${dst}" \ - "Download from asset storage failed" - else - mkdir -p "$(dirname "${dst}")" - wrap aws s3 cp "${src}" "${dst}" \ - "Download from asset storage failed" - fi -} - -# Upload assets to the cache storage bucket. -# -# $1: Path to asset file or directory to upload -function upload_cache() { - if [ "${1}" = "" ]; then - fail "Parameter required for cache upload" - fi - if [ -d "${1}" ]; then - wrap aws s3 cp --recursive "${1}" "${asset_cache}/" \ - "Upload to cache failed" - else - wrap aws s3 cp "${1}" "${asset_cache}/" \ - "Upload to cache failed" - fi -} - -# Download assets from the cache storage bucket. If -# destination is not provided, remote path will be -# used locally. -# -# $1: Path to asset or directory to download -# $2: Optional destination for downloaded assets -function download_cache() { - if [ "${1}" = "" ]; then - fail "At least one parameter required for cache download" - fi - if [ "${2}" = "" ]; then - dst="${1#/}" - else - dst="${2}" - fi - mkdir -p "${dst}" - src="${asset_cache}/${1#/}" - remote=$(aws s3 ls "${src}") - if [[ "${remote}" = *" PRE "* ]]; then - mkdir -p "${dst}" - wrap aws s3 cp --recursive "${src%/}/" "${dst}" \ - "Download from cache storage failed" - else - mkdir -p "$(dirname "${dst}")" - wrap aws s3 cp "${src}" "${dst}" \ - "Download from cache storage failed" - fi -} - -# Validate arguments for GitHub release. Checks for -# two arguments and that second argument is an exiting -# file asset, or directory. -# -# $1: GitHub tag name -# $2: Asset file or directory of assets -function release_validate() { - if [ "${1}" = "" ]; then - fail "Missing required position 1 argument (TAG) for release" - fi - if [ "${2}" = "" ]; then - fail "Missing required position 2 argument (PATH) for release" - fi - if [ ! -e "${2}" ]; then - fail "Path provided for release (${2}) does not exist" - fi -} - -# Generate a GitHub release -# -# $1: GitHub tag name -# $2: Asset file or directory of assets -function release() { - release_validate "${@}" - tag_name="${1}" - assets="${2}" - body="$(release_details)" - body="${body:-New ${repo_name} release - ${tag_name}}" - wrap_raw ghr -u "${repo_owner}" -r "${repo_name}" -c "${full_sha}" -n "${tag_name}" \ - -b "${body}" -delete "${assets}" - if [ $? -ne 0 ]; then - wrap ghr -u "${repo_owner}" -r "${repo_name}" -c "${full_sha}" -n "${tag_name}" \ - -b "${body}" "${tag_name}" "${assets}" "Failed to create release for version ${tag_name}" - fi -} - -# Generate a GitHub prerelease -# -# $1: GitHub tag name -# $2: Asset file or directory of assets -function prerelease() { - release_validate "${@}" - if [[ "${1}" != *"+"* ]]; then - ptag="${1}+${short_sha}" - else - ptag="${1}" - fi - assets="${2}" - - wrap_raw ghr -u "${repo_owner}" -r "${repo_name}" -c "${full_sha}" -n "${ptag}" \ - -delete -prerelease "${ptag}" "${assets}" - if [ $? -ne 0 ]; then - wrap ghr -u "${repo_owner}" -r "${repo_name}" -c "${full_sha}" -n "${ptag}" \ - -prerelease "${ptag}" "${assets}" \ - "Failed to create prerelease for version ${1}" - fi - echo -n "${ptag}" -} - -# Generate details of the release. This will consist -# of a link to the changelog if we can properly detect -# it based on current location. -# -# $1: Tag name -# -# Returns: details content -function release_details() { - tag_name="${1}" - proj_root="$(git rev-parse --show-toplevel)" - if [ $? -ne 0 ] || [ -z "$(git tag -l "${tag_name}")"] || [ ! -f "${proj_root}/CHANGELOG.md" ]; then - return - fi - echo -en "CHANGELOG:\n\nhttps://github.com/${repository}/blob/${tag_name}/CHANGELOG.md" -} - -# Check if version string is valid for release -# -# $1: Version -# Returns: 0 if valid, 1 if invalid -function valid_release_version() { - if [[ "${1}" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - return 0 - else - return 1 - fi -} - -# Validate arguments for HashiCorp release. Ensures asset -# directory exists, and checks that the SHASUMS and SHASUM.sig -# files are present. -# -# $1: Asset directory -function hashicorp_release_validate() { - directory="${1}" - - # Directory checks - if [ "${directory}" = "" ]; then - fail "No asset directory was provided for HashiCorp release" - fi - if [ ! -d "${directory}" ]; then - fail "Asset directory for HashiCorp release does not exist" - fi - - # SHASUMS checks - if [ ! -e "${directory}/"*SHA256SUMS ]; then - fail "Asset directory is missing SHASUMS file" - fi - if [ ! -e "${directory}/"*SHA256SUMS.sig ]; then - fail "Asset directory is missing SHASUMS signature file" - fi -} - -# Verify release assets by validating checksum properly match -# and that signature file is valid -# -# $1: Asset directory -function hashicorp_release_verify() { - directory="${1}" - pushd "${directory}" > "${output}" - - # First do a checksum validation - wrap shasum -a 256 -c *_SHA256SUMS \ - "Checksum validation of release assets failed" - # Next check that the signature is valid - gpghome=$(mktemp -qd) - export GNUPGHOME="${gpghome}" - wrap gpg --keyserver keyserver.ubuntu.com --recv "${HASHICORP_PUBLIC_GPG_KEY_ID}" \ - "Failed to import HashiCorp public GPG key" - wrap gpg --verify *SHA256SUMS.sig *SHA256SUMS \ - "Validation of SHA256SUMS signature failed" - rm -rf "${gpghome}" > "${output}" 2>&1 - popd > "${output}" -} - -# Generate a HashiCorp release -# -# $1: Asset directory -# $2: Product name (e.g. "vagrant") defaults to $repo_name -function hashicorp_release() { - directory="${1}" - product="${2}" - - if [ -z "${product}" ]; then - product="${repo_name}" - fi - - hashicorp_release_validate "${directory}" - hashicorp_release_verify "${directory}" - - oid="${AWS_ACCESS_KEY_ID}" - okey="${AWS_SECRET_ACCESS_KEY}" - export AWS_ACCESS_KEY_ID="${RELEASE_AWS_ACCESS_KEY_ID}" - export AWS_SECRET_ACCESS_KEY="${RELEASE_AWS_SECRET_ACCESS_KEY}" - - wrap_stream hc-releases upload "${directory}" \ - "Failed to upload HashiCorp release assets" - wrap_stream hc-releases publish -product="${product}" \ - "Failed to publish HashiCorp release" - - export AWS_ACCESS_KEY_ID="${oid}" - export AWS_SECRET_ACCESS_KEY="${okey}" -} - -# Build and release project gem to RubyGems -function publish_to_rubygems() { - if [ -z "${RUBYGEMS_API_KEY}" ]; then - fail "RUBYGEMS_API_KEY is currently unset" - fi - - gem_config="$(mktemp -p ./)" || fail "Failed to create temporary credential file" - wrap gem build *.gemspec \ - "Failed to build RubyGem" - printf -- "---\n:rubygems_api_key: ${RUBYGEMS_API_KEY}\n" > "${gem_config}" - wrap_raw gem push --config-file "${gem_config}" *.gem - result=$? - rm -f "${gem_config}" - - if [ $result -ne 0 ]; then - fail "Failed to publish RubyGem" - fi -} - -# Publish gem to the hashigems repository -# -# $1: Path to gem file to publish -function publish_to_hashigems() { - path="${1}" - if [ -z "${path}" ]; then - fail "Path to built gem required for publishing to hashigems" - fi - - wrap_stream gem install --user-install --no-document reaper-man \ - "Failed to install dependency for hashigem generation" - user_bin="$(ruby -e 'puts Gem.user_dir')/bin" - reaper="${user_bin}/reaper-man" - - # Create a temporary directory to work from - tmpdir="$(mktemp -d -p ./)" || - fail "Failed to create working directory for hashigems publish" - mkdir -p "${tmpdir}/hashigems/gems" - wrap cp "${path}" "${tmpdir}/hashigems/gems" \ - "Failed to copy gem to working directory" - wrap_raw pushd "${tmpdir}" - - # Run quick test to ensure bucket is accessible - wrap aws s3 ls "${HASHIGEMS_METADATA_BUCKET}" \ - "Failed to access hashigems asset bucket" - - # Grab our remote metadata. If the file doesn't exist, that is always an error. - wrap aws s3 cp "${HASHIGEMS_METADATA_BUCKET}/vagrant-rubygems.list" ./ \ - "Failed to retrieve hashigems metadata list" - - # Add the new gem to the metadata file - wrap_stream "${reaper}" package add -S rubygems -p vagrant-rubygems.list ./hashigems/gems/*.gem \ - "Failed to add new gem to hashigems metadata list" - # Generate the repository - wrap_stream "${reaper}" repo generate -p vagrant-rubygems.list -o hashigems -S rubygems \ - "Failed to generate the hashigems repository" - # Upload the updated repository - wrap_raw pushd ./hashigems - wrap_stream aws s3 sync . "${HASHIGEMS_PUBLIC_BUCKET}" \ - "Failed to upload the hashigems repository" - # Store the updated metadata - wrap_raw popd - wrap_stream aws s3 cp vagrant-rubygems.list "${HASHIGEMS_METADATA_BUCKET}/vagrant-rubygems.list" \ - "Failed to upload the updated hashigems metadata file" - - # Invalidate cloudfront so the new content is available - invalid="$(aws cloudfront create-invalidation --distribution-id "${HASHIGEMS_CLOUDFRONT_ID}" --paths "/*")" - if [ $? -ne 0 ]; then - fail "Invalidation of hashigems CDN distribution failed" - fi - invalid_id="$(printf '%s' "${invalid}" | jq -r ".Invalidation.Id")" - if [ -z "${invalid_id}" ]; then - fail "Failed to determine the ID of the hashigems CDN invalidation request" - fi - - # Wait for the invalidation process to complete - wrap aws cloudfront wait invalidation-completed --distribution-id "${HASHIGEMS_CLOUDFRONT_ID}" --id "${invalid_id}" \ - "Failure encountered while waiting for hashigems CDN invalidation request to complete (ID: ${invalid_id})" - - # Clean up and we are done - wrap_raw popd - rm -rf "${tmpdir}" -} - -# Configures git for hashibot usage -function hashibot_git() { - wrap git config user.name "${HASHIBOT_USERNAME}" \ - "Failed to setup git for hashibot usage (username)" - wrap git config user.email "${HASHIBOT_EMAIL}" \ - "Failed to setup git for hashibot usage (email)" - wrap git remote set-url origin "https://${HASHIBOT_USERNAME}:${HASHIBOT_TOKEN}@github.com/${repository}" \ - "Failed to setup git for hashibot usage (remote)" -} - -# Stub cleanup method which can be redefined -# within actual script -function cleanup() { - (>&2 echo "** No cleanup tasks defined") -} - -trap cleanup EXIT - -# Enable debugging. This needs to be enabled with -# extreme caution when used on public repositories. -# Output with debugging enabled will likely include -# secret values which should not be publicly exposed. -# -# If repository is public, FORCE_PUBLIC_DEBUG environment -# variable must also be set. - -is_private=$(curl -H "Authorization: token ${HASHIBOT_TOKEN}" -s "https://api.github.com/repos/${GITHUB_REPOSITORY}" | jq .private) - -if [ "${DEBUG}" != "" ]; then - if [ "${is_private}" = "false" ]; then - if [ "${FORCE_PUBLIC_DEBUG}" != "" ]; then - set -x - output="/dev/stdout" - else - fail "Cannot enable debug mode on public repository unless forced" - fi - else - set -x - output="/dev/stdout" - fi -else - output="/dev/null" -fi - -# Check if we are running a public repository on private runners -if [ "${VAGRANT_PRIVATE}" != "" ] && [ "${is_private}" = "false" ]; then - fail "Cannot run public repositories on private Vagrant runners. Disable runners now!" -fi - -# Common variables -full_sha="${GITHUB_SHA}" -short_sha="${full_sha:0:8}" -ident_ref="${GITHUB_REF#*/*/}" -if [[ "${GITHUB_REF}" == *"refs/tags/"* ]]; then - tag="${GITHUB_REF##*tags/}" - valid_release_version "${tag}" - if [ $? -eq 0 ]; then - release=1 - fi -fi -repository="${GITHUB_REPOSITORY}" -repo_owner="${repository%/*}" -repo_name="${repository#*/}" -asset_cache="${ASSETS_PRIVATE_SHORTTERM}/${repository}/${GITHUB_ACTION}" -run_number="${GITHUB_RUN_NUMBER}" -run_id="${GITHUB_RUN_ID}" -job_id="${run_id}-${run_number}" diff --git a/.ci/init.sh b/.ci/init.sh index 8fb4b988a..b46e51ff3 100644 --- a/.ci/init.sh +++ b/.ci/init.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -. "${root}/.ci/common.sh" +. "${root}/.ci/load-ci.sh" export DEBIAN_FRONTEND="noninteractive" export PATH="${PATH}:${root}/.ci" diff --git a/.ci/load-ci.sh b/.ci/load-ci.sh new file mode 100644 index 000000000..a73ad591d --- /dev/null +++ b/.ci/load-ci.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +echo "🤖 Loading VagrantCI 🤖" + +ldir="$(realpath ./.ci-utility-files)" + +# If utility files have not yet been pulled, fetch them +if [ ! -e "${ldir}/.complete" ]; then + + # Validate that we have the AWS CLI available + if ! command -v aws > /dev/null 2>&1; then + echo "⚠ ERROR: Missing required aws executable ⚠" + exit 1 + fi + + # Create a local directory to stash our stuff in + if ! mkdir -p "${ldir}"; then + echo "⛔ ERROR: Failed to create utility file directory ⛔" + exit 1 + fi + + # Jump into local directory and grab files + if ! pushd "${ldir}"; then + echo "⁉ ERROR: Unexpected error, failed to relocate to expected directory ⁉" + exit 1 + fi + + if ! aws s3 sync "${VAGRANT_CI_LOADER_BUCKET}/ci-files/" ./; then + echo "🛑 ERROR: Failed to retrieve utility files 🛑" + exit 1 + fi + + if ! chmod a+x ./*; then + echo "⛔ ERROR: Failed to set permissions on CI files ⛔" + exit 1 + fi + + # Mark that we have pulled files + touch .complete || echo "WARNING: Failed to mark CI files as fetched" +fi + +# Time to load and configure +if ! popd; then + echo "⁉ ERROR: Unexpected error, failed to relocate to expected directory ⁉" + exit 1 +fi + +source "${ldir}/common.sh" +export PATH="${PATH}:${ldir}" + +# And we are done! +echo "🎉 VagrantCI Loaded! 🎉" diff --git a/.ci/slack b/.ci/slack deleted file mode 100755 index 5c8548d62..000000000 --- a/.ci/slack +++ /dev/null @@ -1,176 +0,0 @@ -#!/usr/bin/env ruby - -require "optparse" -require "net/https" -require "uri" -require "json" - -OPTIONS = [:channel, :username, :icon, :state, :message, - :message_file, :file, :title, :tail, :webhook].freeze - -options = {} - -OptionParser.new do |opts| - opts.banner = "Usage: #{File.basename(__FILE__)} [options]" - - opts.on("-c", "--channel CHAN", "Send to channel") do |c| - options[:channel] = c - end - - opts.on("-u", "--username USER", "Send as username") do |u| - options[:username] = u - end - - opts.on("-i", "--icon URL", "User icon image") do |i| - options[:icon] = i - end - - opts.on("-s", "--state STATE", "Message state (success, warn, error, or color code)") do |s| - options[:state] = s - end - - opts.on("-m", "--message MESSAGE", "Message to send") do |m| - options[:message] = m - end - - opts.on("-M", "--message-file MESSAGE_FILE", "Use file contents as message") do |m| - options[:message_file] = m - end - - opts.on("-f", "--file MESSAGE_FILE", "Send raw contents of file in message") do |f| - options[:file] = f - end - - opts.on("-t", "--title TITLE", "Message title") do |t| - options[:title] = t - end - - opts.on("-T", "--tail N", "Send last N lines of content from raw message file") do |t| - options[:tail] = t - end - - opts.on("-w", "--webhook HOOK", "Slack webhook") do |w| - options[:webhook] = w - end - - opts.on("-h", "--help", "Print help") do - puts opts - exit - end -end.parse! - -OPTIONS.each do |key| - if !options.key?(key) - env_key = "SLACK_#{key.to_s.upcase}" - if ENV[env_key] - options[key] = ENV[env_key] - end - end -end - -if !options[:webhook] - $stderr.puts "ERROR: Webhook is required!" - exit 1 -end - -if ENV["CIRCLECI"] - options[:icon] = "https://emoji.slack-edge.com/TF1GCKJNM/circleci/054b58d488e65138.png" unless options[:icon] - options[:username] = "circleci" unless options[:username] - options[:footer] = "CircleCI - <#{ENV["CIRCLE_BUILD_URL"]}|#{ENV["CIRCLE_PROJECT_USERNAME"]}/#{ENV["CIRCLE_PROJECT_REPONAME"]}>" - options[:footer_icon] = "https://emoji.slack-edge.com/TF1GCKJNM/circleci/054b58d488e65138.png" -end - -if ENV["GITHUB_ACTIONS"] - options[:icon] = "https://ca.slack-edge.com/T024UT03C-WG8NDATGT-f82ae03b9fca-48" unless options[:icon] - options[:username] = "github" unless options[:username] - options[:footer] = "Actions - " - options[:footer_icon] = "https://ca.slack-edge.com/T024UT03C-WG8NDATGT-f82ae03b9fca-48" -end - -options[:state] = "success" unless options[:state] - -case options[:state] -when "success", "good" - options[:state] = "good" -when "warn", "warning" - options[:state] = "warning" -when "error", "danger" - options[:state] = "danger" -else - if !options[:state].start_with?("#") - $stderr.puts "ERROR: Invalid value for `state` (#{options[:state]})" - exit 1 - end -end - -msg = options[:message] - -# NOTE: Message provided from CLI argument will end up with -# double escaped newlines so remove one -msg.gsub!("\\n", "\n") if msg - -if options[:message_file] - if !File.exist?(options[:message_file]) - $stderr.puts "ERROR: Message file does not exist `#{options[:message_file]}`" - exit 1 - end - msg_c = File.read(options[:message_file]) - msg = msg ? "#{msg}\n\n#{msg_c}" : msg_c -end - -if options[:file] - if !File.exist?(options[:file]) - $stderr.puts "ERROR: Message file does not exist `#{options[:file]}`" - exit 1 - end - if (tail = options[:tail].to_i) > 0 - content = "" - buffer = 0 - File.open(options[:file], "r") do |f| - until (content.split("\n").size > tail) || buffer >= f.size - buffer += 1000 - buffer = f.size if buffer > f.size - f.seek(f.size - buffer) - content = f.read - end - end - parts = content.split("\n") - if parts.size > tail - parts = parts.slice(-tail, tail) - end - fmsg = parts ? parts.join("\n") : "" - else - fmsg = File.read(options[:file]) - end - fmsg = "```\n#{fmsg}\n```" - if msg - msg = msg << "\n\n" << fmsg - end -end - -if msg.to_s.empty? - $stderr.puts "ERROR: No message content provided!" - exit 1 -end - -attach = {text: msg, fallback: msg, color: options[:state], mrkdn: true} -attach[:title] = options[:title] if options[:title] -attach[:footer] = options[:footer] if options[:footer] -attach[:footer_icon] = options[:footer_icon] if options[:footer_icon] -attach[:ts] = Time.now.to_i - -payload = {}.tap do |pd| - pd[:username] = options.fetch(:username, "packet-exec") - pd[:channel] = options[:channel] if options[:channel] - pd[:icon_url] = options[:icon] if options[:icon] - pd[:attachments] = [attach] -end - -result = Net::HTTP.post(URI(options[:webhook]), payload.to_json, "Content-Type" => "application/json") - -if !result.code.start_with?("2") - $stderr.puts "Failed to send slack message" - exit 1 -else - $stdout.puts "ok" -end diff --git a/.ci/spec/clean-packet.sh b/.ci/spec/clean-packet.sh index f71bf8057..77ef5ee50 100755 --- a/.ci/spec/clean-packet.sh +++ b/.ci/spec/clean-packet.sh @@ -4,7 +4,7 @@ csource="${BASH_SOURCE[0]}" while [ -h "$csource" ] ; do csource="$(readlink "$csource")"; done root="$( cd -P "$( dirname "$csource" )/../../" && pwd )" -. "${root}/.ci/common.sh" +. "${root}/.ci/load-ci.sh" . "${root}/.ci/spec/env.sh" pushd "${root}" > "${output}" diff --git a/.ci/spec/create-hosts.sh b/.ci/spec/create-hosts.sh index 08210933b..bc7a57e63 100755 --- a/.ci/spec/create-hosts.sh +++ b/.ci/spec/create-hosts.sh @@ -4,7 +4,7 @@ csource="${BASH_SOURCE[0]}" while [ -h "$csource" ] ; do csource="$(readlink "$csource")"; done root="$( cd -P "$( dirname "$csource" )/../../" && pwd )" -. "${root}/.ci/common.sh" +. "${root}/.ci/load-ci.sh" . "${root}/.ci/spec/env.sh" pushd "${root}" > "${output}" diff --git a/.ci/spec/create-packet.sh b/.ci/spec/create-packet.sh index f08759848..db2c5b207 100755 --- a/.ci/spec/create-packet.sh +++ b/.ci/spec/create-packet.sh @@ -4,7 +4,7 @@ csource="${BASH_SOURCE[0]}" while [ -h "$csource" ] ; do csource="$(readlink "$csource")"; done root="$( cd -P "$( dirname "$csource" )/../../" && pwd )" -. "${root}/.ci/common.sh" +. "${root}/.ci/load-ci.sh" . "${root}/.ci/spec/env.sh" pushd "${root}" > "${output}" diff --git a/.ci/spec/run-test.sh b/.ci/spec/run-test.sh index c0a4651b8..13c049563 100755 --- a/.ci/spec/run-test.sh +++ b/.ci/spec/run-test.sh @@ -4,7 +4,7 @@ csource="${BASH_SOURCE[0]}" while [ -h "$csource" ] ; do csource="$(readlink "$csource")"; done root="$( cd -P "$( dirname "$csource" )/../../" && pwd )" -. "${root}/.ci/common.sh" +. "${root}/.ci/load-ci.sh" . "${root}/.ci/spec/env.sh" pushd "${root}" > "${output}" diff --git a/.ci/sync.sh b/.ci/sync.sh index 269b29bba..6ab8a57b5 100755 --- a/.ci/sync.sh +++ b/.ci/sync.sh @@ -4,7 +4,7 @@ csource="${BASH_SOURCE[0]}" while [ -h "$csource" ] ; do csource="$(readlink "$csource")"; done root="$( cd -P "$( dirname "$csource" )/../" && pwd )" -. "${root}/.ci/common.sh" +. "${root}/.ci/load-ci.sh" export PATH="${PATH}:${root}/.ci"