Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/outagedeck/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# OutageDeck CLI (via GitHub Releases) (outagedeck)

Check the live status of 170+ cloud and SaaS providers from a terminal or CI
script. OutageDeck normalizes each vendor's official status feed; it does not
replace synthetic monitoring.

## Example usage

```json
"features": {
"ghcr.io/devcontainers-extra/features/outagedeck:1": {}
}
```

Then query one or more provider slugs:

```bash
outagedeck status aws cloudflare github openai
```

For structured CI output and a nonzero exit code when a provider is down:

```bash
outagedeck status --json --fail-on=outage aws github openai
```

Find more examples in the [OutageDeck CLI repository](https://github.com/outagedeck/cli)
or review the [API documentation](https://outagedeck.com/developers/api?utm_source=devcontainers-extra&utm_medium=feature&utm_campaign=devcontainer_feature).

## Options

| Options Id | Description | Type | Default Value |
|------------|----------------------------------------------|--------|---------------|
| version | Select the OutageDeck CLI version to install. | string | latest |
21 changes: 21 additions & 0 deletions src/outagedeck/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"id": "outagedeck",
"version": "1.0.0",
"name": "OutageDeck CLI (via GitHub Releases)",
"documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/outagedeck",
"description": "Check the live status of cloud and SaaS providers from a terminal or CI script.",
"options": {
"version": {
"default": "latest",
"description": "Select the OutageDeck CLI version to install.",
"proposals": [
"latest",
"0.1.0"
],
"type": "string"
}
},
"installsAfter": [
"ghcr.io/devcontainers-extra/features/gh-release"
]
}
19 changes: 19 additions & 0 deletions src/outagedeck/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash

set -e

source ./library_scripts.sh

# nanolayer is a CLI utility which keeps container layers as small as possible.
# Source: https://github.com/devcontainers-extra/nanolayer
ensure_nanolayer nanolayer_location "v0.5.6"

"$nanolayer_location" \
install \
devcontainer-feature \
"ghcr.io/devcontainers-extra/features/gh-release:1" \
--option repo='outagedeck/cli' \
--option binaryNames='outagedeck' \
--option version="$VERSION"

echo 'Done!'
131 changes: 131 additions & 0 deletions src/outagedeck/library_scripts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#!/usr/bin/env bash

clean_download() {
local url=$1
local output_location=$2
local tempdir
tempdir=$(mktemp -d)
local downloader_installed=""

_apt_get_install() {
local apt_tempdir=$1
cp -p -R /var/lib/apt/lists "$apt_tempdir"
apt-get update -y
apt-get -y install --no-install-recommends wget ca-certificates
}

_apt_get_cleanup() {
local apt_tempdir=$1
apt-get -y purge wget --auto-remove
rm -rf /var/lib/apt/lists/*
rm -r /var/lib/apt/lists
mv "$apt_tempdir/lists" /var/lib/apt/lists
}

_apk_install() {
local apk_tempdir=$1
cp -p -R /var/cache/apk "$apk_tempdir"
apk add --no-cache wget
}

_apk_cleanup() {
apk del wget
}

local downloader
if type curl >/dev/null 2>&1; then
downloader=curl
elif type wget >/dev/null 2>&1; then
downloader=wget
else
downloader=""
fi

if [ -z "$downloader" ]; then
if [ -x "/usr/bin/apt-get" ]; then
_apt_get_install "$tempdir"
elif [ -x "/sbin/apk" ]; then
_apk_install "$tempdir"
else
echo "distro not supported"
exit 1
fi
downloader="wget"
downloader_installed="true"
fi

if [ "$downloader" = "wget" ]; then
wget -q "$url" -O "$output_location"
else
curl -sfL "$url" -o "$output_location"
fi

if [ -n "$downloader_installed" ]; then
if [ -x "/usr/bin/apt-get" ]; then
_apt_get_cleanup "$tempdir"
elif [ -x "/sbin/apk" ]; then
_apk_cleanup
fi
fi
}

ensure_nanolayer() {
local variable_name=$1
local required_version=$2

if [[ $required_version != v* ]]; then
required_version="v$required_version"
fi

local resolved_nanolayer=""
if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION:-}" ]]; then
if [[ -z "${NANOLAYER_CLI_LOCATION:-}" ]]; then
if type nanolayer >/dev/null 2>&1; then
resolved_nanolayer=nanolayer
fi
elif [[ -f "$NANOLAYER_CLI_LOCATION" && -x "$NANOLAYER_CLI_LOCATION" ]]; then
resolved_nanolayer=$NANOLAYER_CLI_LOCATION
fi

if [[ -n "$resolved_nanolayer" ]]; then
local current_version
current_version=$($resolved_nanolayer --version)
if [[ $current_version != v* ]]; then
current_version="v$current_version"
fi
if [[ $current_version != "$required_version" ]]; then
resolved_nanolayer=""
fi
fi
fi

if [[ -z "$resolved_nanolayer" ]]; then
if [[ "$(uname -sm)" != "Linux x86_64" && "$(uname -sm)" != "Linux aarch64" ]]; then
echo "No nanolayer binary for $(uname -sm)"
exit 1
fi

local nanolayer_tempdir
nanolayer_tempdir=$(mktemp -d -t nanolayer-XXXXXXXXXX)
clean_up() {
local exit_code=$?
rm -rf "$nanolayer_tempdir"
exit "$exit_code"
}
trap clean_up EXIT

local clib_type=gnu
if [ -x "/sbin/apk" ]; then
clib_type=musl
fi
local tar_filename="nanolayer-$(uname -m)-unknown-linux-$clib_type.tgz"
clean_download \
"https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename" \
"$nanolayer_tempdir/$tar_filename"
tar xfz "$nanolayer_tempdir/$tar_filename" -C "$nanolayer_tempdir"
chmod a+x "$nanolayer_tempdir/nanolayer"
resolved_nanolayer="$nanolayer_tempdir/nanolayer"
fi

declare -g "$variable_name=$resolved_nanolayer"
}
16 changes: 16 additions & 0 deletions test/outagedeck/scenarios.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"test_default": {
"image": "mcr.microsoft.com/devcontainers/base:debian",
"features": {
"outagedeck": {}
}
},
"test_specific_version": {
"image": "mcr.microsoft.com/devcontainers/base:debian",
"features": {
"outagedeck": {
"version": "0.1.0"
}
}
}
}
9 changes: 9 additions & 0 deletions test/outagedeck/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -e

source dev-container-features-test-lib

check "outagedeck is installed" outagedeck --version

reportResults
10 changes: 10 additions & 0 deletions test/outagedeck/test_default.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

set -e

source dev-container-features-test-lib

check "outagedeck is installed" outagedeck --version
check "outagedeck status command is available" sh -c "outagedeck help | grep 'outagedeck status'"

reportResults
9 changes: 9 additions & 0 deletions test/outagedeck/test_specific_version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -e

source dev-container-features-test-lib

check "outagedeck version is 0.1.0" sh -c "outagedeck --version | grep '0.1.0'"

reportResults
Loading