From e294c2bddf111162a6fcc82340a13b4eb59efba0 Mon Sep 17 00:00:00 2001 From: Daniel Braun Date: Sat, 30 Sep 2023 14:43:17 +0000 Subject: [PATCH] feat: epinio and poppler-utils features. gh-release updated --- src/epinio/README.md | 20 ++ src/epinio/devcontainer-feature.json | 20 ++ src/epinio/install.sh | 23 +++ src/epinio/library_scripts.sh | 172 ++++++++++++++++++ src/gh-release/devcontainer-feature.json | 2 +- src/gh-release/install.sh | 2 +- src/poppler-utils-apt-get/README.md | 27 +++ .../devcontainer-feature.json | 11 ++ src/poppler-utils-apt-get/install.sh | 23 +++ src/poppler-utils-apt-get/library_scripts.sh | 172 ++++++++++++++++++ test/epinio/scenarios.json | 8 + test/epinio/test_defaults_debian.sh | 9 + test/poppler-utils-apt-get/scenarios.json | 8 + test/poppler-utils-apt-get/test.sh | 31 ++++ 14 files changed, 526 insertions(+), 2 deletions(-) create mode 100644 src/epinio/README.md create mode 100644 src/epinio/devcontainer-feature.json create mode 100755 src/epinio/install.sh create mode 100644 src/epinio/library_scripts.sh create mode 100644 src/poppler-utils-apt-get/README.md create mode 100644 src/poppler-utils-apt-get/devcontainer-feature.json create mode 100755 src/poppler-utils-apt-get/install.sh create mode 100644 src/poppler-utils-apt-get/library_scripts.sh create mode 100644 test/epinio/scenarios.json create mode 100755 test/epinio/test_defaults_debian.sh create mode 100644 test/poppler-utils-apt-get/scenarios.json create mode 100755 test/poppler-utils-apt-get/test.sh diff --git a/src/epinio/README.md b/src/epinio/README.md new file mode 100644 index 000000000..ab81d187b --- /dev/null +++ b/src/epinio/README.md @@ -0,0 +1,20 @@ + +# Epinio (via Github Releases) (epinio) + +Epinio is an opinionated platform that runs on Kubernetes to take you from Code to URL in one step. + +## Example DevContainer Usage + +```json +"features": { + "ghcr.io/devcontainers-contrib/features/epinio:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| version | Select the version to install. | string | latest | + + diff --git a/src/epinio/devcontainer-feature.json b/src/epinio/devcontainer-feature.json new file mode 100644 index 000000000..63a9db721 --- /dev/null +++ b/src/epinio/devcontainer-feature.json @@ -0,0 +1,20 @@ +{ + "id": "epinio", + "version": "1.0.0", + "name": "Epinio (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-contrib/features/tree/main/src/epinio", + "description": "Epinio is an opinionated platform that runs on Kubernetes to take you from Code to URL in one step.", + "options": { + "version": { + "default": "latest", + "description": "Select the version to install.", + "proposals": [ + "latest" + ], + "type": "string" + } + }, + "installsAfter": [ + "ghcr.io/devcontainers-contrib/features/gh-release" + ] +} \ No newline at end of file diff --git a/src/epinio/install.sh b/src/epinio/install.sh new file mode 100755 index 000000000..a228e4811 --- /dev/null +++ b/src/epinio/install.sh @@ -0,0 +1,23 @@ + +set -e + +. ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-contrib/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.5" + + +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-contrib/features/gh-release:1.0.23" \ + --option repo='epinio/epinio' --option binaryNames='epinio' --option version="$VERSION" + + + +echo 'Done!' + diff --git a/src/epinio/library_scripts.sh b/src/epinio/library_scripts.sh new file mode 100644 index 000000000..0d7f34d4b --- /dev/null +++ b/src/epinio/library_scripts.sh @@ -0,0 +1,172 @@ + + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + 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 + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ] ; then + if [ -x "/usr/bin/apt-get" ] ; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ] ; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + + local __nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]; then + if [ -z "${NANOLAYER_CLI_LOCATION}" ]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + __nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ] ; then + __nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $__nanolayer_location" + fi + + # make sure its of the required version + if ! [ -z "${__nanolayer_location}" ]; then + local current_version + current_version=$($__nanolayer_location --version) + + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + __nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [ -z "${__nanolayer_location}" ]; then + + if [ "$(uname -sm)" = 'Linux x86_64' ] || [ "$(uname -sm)" = "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up () { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + + if [ -x "/sbin/apk" ] ; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-contrib/cli/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + __nanolayer_location=$tmp_dir/nanolayer + + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + export ${variable_name}=$__nanolayer_location + +} + + diff --git a/src/gh-release/devcontainer-feature.json b/src/gh-release/devcontainer-feature.json index 3a34b1757..734b4c352 100644 --- a/src/gh-release/devcontainer-feature.json +++ b/src/gh-release/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gh-release", - "version": "1.0.23", + "version": "1.0.24", "name": "Github Release", "documentationURL": "http://github.com/devcontainers-contrib/features/tree/main/src/gh-release", "description": "Github Release feature will download, extract and add to path a release binary from a given repo", diff --git a/src/gh-release/install.sh b/src/gh-release/install.sh index e16731dc7..12bc96d40 100755 --- a/src/gh-release/install.sh +++ b/src/gh-release/install.sh @@ -8,7 +8,7 @@ set -e # `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, # and if missing - will download a temporary copy that automatically get deleted at the end # of the script -ensure_nanolayer nanolayer_location "v0.5.4" +ensure_nanolayer nanolayer_location "v0.5.5" diff --git a/src/poppler-utils-apt-get/README.md b/src/poppler-utils-apt-get/README.md new file mode 100644 index 000000000..4f1c75595 --- /dev/null +++ b/src/poppler-utils-apt-get/README.md @@ -0,0 +1,27 @@ + +# poppler-utils (pdftotext, pdftoppm, pdftops, pdfattach, pdfdetach, pdffonts, pdfimages, pdfinfo, pdfseparate, pdftocairo, pdftohtml, pdfunite) (via apt-get) (poppler-utils-apt-get) + +poppler-utils is a collection of command-line utilities built on Poppler's library API, to manage PDF and extract contents: +pdfattach - add a new embedded file (attachment) to an existing PDF +pdfdetach - extract embedded documents from a PDF +pdffonts - lists the fonts used in a PDF +pdfimages - extract all embedded images at native resolution from a PDF +pdfinfo - list all information of a PDF +pdfseparate - extract single pages from a PDF +pdftocairo - convert single pages from a PDF to vector or bitmap formats using cairo +pdftohtml - convert PDF to HTML format retaining formatting +pdftoppm - convert a PDF page to a bitmap +pdftops - convert PDF to printable PS format +pdftotext - extract all text from PDF +pdfunite - merges several PDFs. + +## Example DevContainer Usage + +```json +"features": { + "ghcr.io/devcontainers-contrib/features/poppler-utils-apt-get:1": {} +} +``` + + + diff --git a/src/poppler-utils-apt-get/devcontainer-feature.json b/src/poppler-utils-apt-get/devcontainer-feature.json new file mode 100644 index 000000000..73babbce9 --- /dev/null +++ b/src/poppler-utils-apt-get/devcontainer-feature.json @@ -0,0 +1,11 @@ +{ + "id": "poppler-utils-apt-get", + "version": "1.0.0", + "name": "poppler-utils (pdftotext, pdftoppm, pdftops, pdfattach, pdfdetach, pdffonts, pdfimages, pdfinfo, pdfseparate, pdftocairo, pdftohtml, pdfunite) (via apt-get)", + "documentationURL": "http://github.com/devcontainers-contrib/features/tree/main/src/curl-apt-get", + "description": "poppler-utils is a collection of command-line utilities built on Poppler's library API, to manage PDF and extract contents: \npdfattach - add a new embedded file (attachment) to an existing PDF \npdfdetach - extract embedded documents from a PDF \npdffonts - lists the fonts used in a PDF \npdfimages - extract all embedded images at native resolution from a PDF \npdfinfo - list all information of a PDF \npdfseparate - extract single pages from a PDF \npdftocairo - convert single pages from a PDF to vector or bitmap formats using cairo \npdftohtml - convert PDF to HTML format retaining formatting \npdftoppm - convert a PDF page to a bitmap \npdftops - convert PDF to printable PS format \npdftotext - extract all text from PDF \npdfunite - merges several PDFs.", + "options": {}, + "installsAfter": [ + "ghcr.io/devcontainers-contrib/features/apt-get-packages" + ] +} \ No newline at end of file diff --git a/src/poppler-utils-apt-get/install.sh b/src/poppler-utils-apt-get/install.sh new file mode 100755 index 000000000..7b72cd497 --- /dev/null +++ b/src/poppler-utils-apt-get/install.sh @@ -0,0 +1,23 @@ + +set -e + +. ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-contrib/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.5" + + +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-contrib/features/apt-get-packages:1.0.6" \ + --option packages='poppler-utils' + + + +echo 'Done!' + diff --git a/src/poppler-utils-apt-get/library_scripts.sh b/src/poppler-utils-apt-get/library_scripts.sh new file mode 100644 index 000000000..0d7f34d4b --- /dev/null +++ b/src/poppler-utils-apt-get/library_scripts.sh @@ -0,0 +1,172 @@ + + +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine + + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir + apt-get update -y + apt-get -y install --no-install-recommends wget ca-certificates + } + + _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } + + _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" + fi + + # in case none of them is installed, install wget temporarly + 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 + + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ] ; then + if [ -x "/usr/bin/apt-get" ] ; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ] ; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi + +} + + +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + + local __nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]; then + if [ -z "${NANOLAYER_CLI_LOCATION}" ]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + __nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ] ; then + __nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $__nanolayer_location" + fi + + # make sure its of the required version + if ! [ -z "${__nanolayer_location}" ]; then + local current_version + current_version=$($__nanolayer_location --version) + + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + __nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [ -z "${__nanolayer_location}" ]; then + + if [ "$(uname -sm)" = 'Linux x86_64' ] || [ "$(uname -sm)" = "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up () { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + + if [ -x "/sbin/apk" ] ; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-contrib/cli/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + __nanolayer_location=$tmp_dir/nanolayer + + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + export ${variable_name}=$__nanolayer_location + +} + + diff --git a/test/epinio/scenarios.json b/test/epinio/scenarios.json new file mode 100644 index 000000000..16ec5032a --- /dev/null +++ b/test/epinio/scenarios.json @@ -0,0 +1,8 @@ +{ + "test_defaults_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "epinio": {} + } + } +} \ No newline at end of file diff --git a/test/epinio/test_defaults_debian.sh b/test/epinio/test_defaults_debian.sh new file mode 100755 index 000000000..49a867087 --- /dev/null +++ b/test/epinio/test_defaults_debian.sh @@ -0,0 +1,9 @@ +#!/bin/bash -i + +set -e + +source dev-container-features-test-lib + +check "epinio --version" epinio --version + +reportResults diff --git a/test/poppler-utils-apt-get/scenarios.json b/test/poppler-utils-apt-get/scenarios.json new file mode 100644 index 000000000..50b1a4228 --- /dev/null +++ b/test/poppler-utils-apt-get/scenarios.json @@ -0,0 +1,8 @@ +{ + "test": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "poppler-utils-apt-get": {} + } + } +} \ No newline at end of file diff --git a/test/poppler-utils-apt-get/test.sh b/test/poppler-utils-apt-get/test.sh new file mode 100755 index 000000000..f9934f386 --- /dev/null +++ b/test/poppler-utils-apt-get/test.sh @@ -0,0 +1,31 @@ +#!/bin/bash -i + +set -e + +source dev-container-features-test-lib + +check "type pdfattach" type pdfattach + +check "type pdfdetach" type pdfdetach + +check "type pdffonts" type pdffonts + +check "type pdfimages" type pdfimages + +check "type pdfinfo" type pdfinfo + +check "type pdfseparate" type pdfseparate + +check "type pdftocairo" type pdftocairo + +check "type pdftohtml" type pdftohtml + +check "type pdftoppm" type pdftoppm + +check "type pdftops" type pdftops + +check "type pdftotext" type pdftotext + +check "type pdfunite" type pdfunite + +reportResults