Skip to content
This repository was archived by the owner on Jan 12, 2025. It is now read-only.

Commit 696aa94

Browse files
feat: added feature azure apiops (#519)
1 parent 10a3894 commit 696aa94

File tree

6 files changed

+262
-0
lines changed

6 files changed

+262
-0
lines changed

src/azure-apiops/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
# Azure Apiops (Extractor and Publisher) (via Github Releases) (azure-apiops)
3+
4+
APIOps applies the concepts of GitOps and DevOps to API deployment. By using practices from these two methodologies, APIOps can enable everyone involved in the lifecycle of API design, development, and deployment with self-service and automated tools to ensure the quality of the specifications and APIs that theyre building.
5+
6+
## Example DevContainer Usage
7+
8+
```json
9+
"features": {
10+
"ghcr.io/devcontainers-contrib/features/azure-apiops:1": {}
11+
}
12+
```
13+
14+
## Options
15+
16+
| Options Id | Description | Type | Default Value |
17+
|-----|-----|-----|-----|
18+
| version | Select the version you would like to install. | string | latest |
19+
20+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"id": "azure-apiops",
3+
"version": "1.0.0",
4+
"name": "Azure Apiops (Extractor and Publisher) (via Github Releases)",
5+
"documentationURL": "http://github.com/devcontainers-contrib/features/tree/main/src/azure-apiops",
6+
"description": "APIOps applies the concepts of GitOps and DevOps to API deployment. By using practices from these two methodologies, APIOps can enable everyone involved in the lifecycle of API design, development, and deployment with self-service and automated tools to ensure the quality of the specifications and APIs that theyre building.",
7+
"options": {
8+
"version": {
9+
"default": "latest",
10+
"description": "Select the version you would like to install.",
11+
"proposals": [
12+
"latest"
13+
],
14+
"type": "string"
15+
}
16+
},
17+
"installsAfter": [
18+
"ghcr.io/devcontainers-contrib/features/gh-release"
19+
]
20+
}

src/azure-apiops/install.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
set -e
3+
4+
. ./library_scripts.sh
5+
6+
# nanolayer is a cli utility which keeps container layers as small as possible
7+
# source code: https://github.com/devcontainers-contrib/nanolayer
8+
# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations,
9+
# and if missing - will download a temporary copy that automatically get deleted at the end
10+
# of the script
11+
ensure_nanolayer nanolayer_location "v0.5.3"
12+
13+
14+
$nanolayer_location \
15+
install \
16+
devcontainer-feature \
17+
"ghcr.io/devcontainers-contrib/features/gh-release:1.0.21" \
18+
--option repo='Azure/apiops' --option binaryNames='extractor' --option assetRegex='^extractor.linux-x64.exe' --option version="$VERSION"
19+
20+
21+
22+
$nanolayer_location \
23+
install \
24+
devcontainer-feature \
25+
"ghcr.io/devcontainers-contrib/features/gh-release:1.0.21" \
26+
--option repo='Azure/apiops' --option binaryNames='publisher' --option assetRegex='^publisher.linux-x64.exe' --option version="$VERSION"
27+
28+
29+
30+
echo 'Done!'
31+

src/azure-apiops/library_scripts.sh

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
2+
3+
clean_download() {
4+
# The purpose of this function is to download a file with minimal impact on container layer size
5+
# this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a
6+
# temporary manner, and making sure to
7+
# 1. uninstall the downloader at the return of the function
8+
# 2. revert back any changes to the package installer database/cache (for example apt-get lists)
9+
# The above steps will minimize the leftovers being created while installing the downloader
10+
# Supported distros:
11+
# debian/ubuntu/alpine
12+
13+
url=$1
14+
output_location=$2
15+
tempdir=$(mktemp -d)
16+
downloader_installed=""
17+
18+
_apt_get_install() {
19+
tempdir=$1
20+
21+
# copy current state of apt list - in order to revert back later (minimize contianer layer size)
22+
cp -p -R /var/lib/apt/lists $tempdir
23+
apt-get update -y
24+
apt-get -y install --no-install-recommends wget ca-certificates
25+
}
26+
27+
_apt_get_cleanup() {
28+
tempdir=$1
29+
30+
echo "removing wget"
31+
apt-get -y purge wget --auto-remove
32+
33+
echo "revert back apt lists"
34+
rm -rf /var/lib/apt/lists/*
35+
rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists
36+
}
37+
38+
_apk_install() {
39+
tempdir=$1
40+
# copy current state of apk cache - in order to revert back later (minimize contianer layer size)
41+
cp -p -R /var/cache/apk $tempdir
42+
43+
apk add --no-cache wget
44+
}
45+
46+
_apk_cleanup() {
47+
tempdir=$1
48+
49+
echo "removing wget"
50+
apk del wget
51+
}
52+
# try to use either wget or curl if one of them already installer
53+
if type curl >/dev/null 2>&1; then
54+
downloader=curl
55+
elif type wget >/dev/null 2>&1; then
56+
downloader=wget
57+
else
58+
downloader=""
59+
fi
60+
61+
# in case none of them is installed, install wget temporarly
62+
if [ -z $downloader ] ; then
63+
if [ -x "/usr/bin/apt-get" ] ; then
64+
_apt_get_install $tempdir
65+
elif [ -x "/sbin/apk" ] ; then
66+
_apk_install $tempdir
67+
else
68+
echo "distro not supported"
69+
exit 1
70+
fi
71+
downloader="wget"
72+
downloader_installed="true"
73+
fi
74+
75+
if [ $downloader = "wget" ] ; then
76+
wget -q $url -O $output_location
77+
else
78+
curl -sfL $url -o $output_location
79+
fi
80+
81+
# NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because
82+
# alpine lack bash, and RETURN is not a valid signal under sh shell
83+
if ! [ -z $downloader_installed ] ; then
84+
if [ -x "/usr/bin/apt-get" ] ; then
85+
_apt_get_cleanup $tempdir
86+
elif [ -x "/sbin/apk" ] ; then
87+
_apk_cleanup $tempdir
88+
else
89+
echo "distro not supported"
90+
exit 1
91+
fi
92+
fi
93+
94+
}
95+
96+
97+
ensure_nanolayer() {
98+
# Ensure existance of the nanolayer cli program
99+
local variable_name=$1
100+
101+
local required_version=$2
102+
103+
local __nanolayer_location=""
104+
105+
# If possible - try to use an already installed nanolayer
106+
if [ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]; then
107+
if [ -z "${NANOLAYER_CLI_LOCATION}" ]; then
108+
if type nanolayer >/dev/null 2>&1; then
109+
echo "Found a pre-existing nanolayer in PATH"
110+
__nanolayer_location=nanolayer
111+
fi
112+
elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ] ; then
113+
__nanolayer_location=${NANOLAYER_CLI_LOCATION}
114+
echo "Found a pre-existing nanolayer which were given in env variable: $__nanolayer_location"
115+
fi
116+
117+
# make sure its of the required version
118+
if ! [ -z "${__nanolayer_location}" ]; then
119+
local current_version
120+
current_version=$($__nanolayer_location --version)
121+
122+
123+
if ! [ $current_version == $required_version ]; then
124+
echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)"
125+
__nanolayer_location=""
126+
fi
127+
fi
128+
129+
fi
130+
131+
# If not previuse installation found, download it temporarly and delete at the end of the script
132+
if [ -z "${__nanolayer_location}" ]; then
133+
134+
if [ "$(uname -sm)" = 'Linux x86_64' ] || [ "$(uname -sm)" = "Linux aarch64" ]; then
135+
tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX)
136+
137+
clean_up () {
138+
ARG=$?
139+
rm -rf $tmp_dir
140+
exit $ARG
141+
}
142+
trap clean_up EXIT
143+
144+
145+
if [ -x "/sbin/apk" ] ; then
146+
clib_type=musl
147+
else
148+
clib_type=gnu
149+
fi
150+
151+
tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz
152+
153+
# clean download will minimize leftover in case a downloaderlike wget or curl need to be installed
154+
clean_download https://github.com/devcontainers-contrib/cli/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename
155+
156+
tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir"
157+
chmod a+x $tmp_dir/nanolayer
158+
__nanolayer_location=$tmp_dir/nanolayer
159+
160+
161+
else
162+
echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)"
163+
exit 1
164+
fi
165+
fi
166+
167+
# Expose outside the resolved location
168+
export ${variable_name}=$__nanolayer_location
169+
170+
}
171+
172+

test/azure-apiops/scenarios.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"test": {
3+
"image": "mcr.microsoft.com/devcontainers/base:debian",
4+
"features": {
5+
"azure-apiops": {}
6+
}
7+
}
8+
}

test/azure-apiops/test.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash -i
2+
3+
set -e
4+
5+
source dev-container-features-test-lib
6+
7+
check "type extractor" type extractor
8+
9+
check "type publisher" type publisher
10+
11+
reportResults

0 commit comments

Comments
 (0)