Browse Source

added esh to base debian container

feature/startup-from-labels
Mario Alegre 4 years ago
parent
commit
e13eff1386
  1. 6
      debian/Containerfile
  2. 366
      gitea/assets/bin/esh

6
debian/Containerfile

@ -34,3 +34,9 @@ COPY assets/bash.bashrc /etc/bash.bashrc
# copy custom scripts # copy custom scripts
COPY assets/bin/ /usr/local/bin/ COPY assets/bin/ /usr/local/bin/
# Install templating engine
RUN wget https://raw.githubusercontent.com/jirutka/esh/master/esh && \
chmod +x esh && \
mv esh /usr/local/bin/ && \
mkdir /etc/templates

366
gitea/assets/bin/esh

@ -1,366 +0,0 @@
#!/bin/sh
# vim: set ts=4:
#---help---
# USAGE:
# esh [options] [--] <input> [<variable>...]
# esh <-h | -V>
#
# Process and evaluate an ESH template.
#
# ARGUMENTS:
# <input> Path of the template file or "-" to read from STDIN.
# <variable> Variable(s) specified as <name>=<value> to pass into the
# template (the have higher priority than environment
# variables).
#
# OPTIONS:
# -d Don't evaluate template, just dump a shell script.
# -o <file> Output file or "-" for STDOUT. Defaults to "-".
# -s <shell> Command name or path of the shell to use for template
# evaluation. It must not contain spaces.
# Defaults to "/bin/sh".
# -h Show this help message and exit.
# -V Print version and exit.
#
# ENVIRONMENT:
# ESH_AWK Command name of path of the awk program to use.
# It must not contain spaces. Defaults to "awk".
# ESH_MAX_DEPTH Maximum include depth. Defaults to 3.
# ESH_SHELL Same as -s.
#
# EXIT STATUS:
# 0 Clean exit, no error has encountered.
# 1 Generic error.
# 10 Invalid usage.
# 11 ESH syntax error.
# 12 Include error: file not found.
# 13 Include error: exceeded max include depth (ESH_MAX_DEPTH).
#
# Please report bugs at <https://github.com/jirutka/esh/issues>.
#---help---
set -eu
readonly PROGNAME='esh'
readonly VERSION='0.3.0'
readonly SCRIPTPATH="$0"
AWK_CONVERTER=$(cat <<'AWK'
function fail(code, msg) {
state = "ERROR"
# FIXME: /dev/stderr is not portable
printf("%s: %s\n", line_info(), msg) > "/dev/stderr"
exit code
}
function line_info() {
return FILENAME ? (filenames[depth] ":" linenos[depth]) : "(init)" # (init) if inside BEGIN
}
# IMPORTANT: This is the only function that should print a newline.
function puts(str) {
print(line_info()) > MAP_FILE
print(str)
}
function fputs(str) {
printf("%s", str)
}
function trim(str) {
gsub(/^[ \t\r\n]+|[ \t\r\n]+$/, "", str)
return str
}
function read(len, _str) {
if (len == "") {
_str = buff
buff = ""
} else if (len > 0) {
_str = substr(buff, 1, len)
buff = substr(buff, len + 1, length(buff))
}
return _str
}
function skip(len) {
buff = substr(buff, len + 1, length(buff))
}
function flush(len, _str) {
_str = read(len)
if (state == "TEXT") {
gsub("'", "'\\''", _str)
}
if (state != "COMMENT") {
fputs(_str)
}
}
function file_exists(filename, _junk) {
if ((getline _junk < filename) >= 0) {
close(filename)
return 1
}
return 0
}
function dirname(path) {
return sub(/\/[^\/]+\/*$/, "/", path) ? path : ""
}
function include(filename) {
if (index(filename, "/") != 1) { # if does not start with "/"
filename = dirname(filenames[depth]) filename
}
if (!file_exists(filename)) {
fail(12, "cannot include " filename ": not a file or not readable")
}
if (depth > MAX_DEPTH) {
fail(13, "cannot include " filename ": exceeded maximum depth of " MAX_DEPTH)
}
buffs[depth] = buff
states[depth] = state
filenames[depth + 1] = filename
depth++
init()
while ((getline buff < filename) > 0) {
if (print_nl && state != "COMMENT") {
puts("")
}
process_line()
}
end_text()
close(filename)
depth--
buff = buffs[depth]
state = states[depth]
}
function init() {
buff = ""
linenos[depth] = 0
print_nl = 0
start_text()
}
function start_text() {
puts("")
fputs("printf '%s' '")
state = "TEXT"
}
function end_text() {
if (state != "TEXT") { return }
puts("' #< " line_info())
state = "UNDEF"
}
function process_line() {
linenos[depth]++
while (buff != "") {
print_nl = 1
if (state == "TEXT" && match(buff, /<%/)) {
flush(RSTART - 1) # print buff before "<%"
skip(2) # skip "<%"
flag = substr(buff, 1, 1)
if (flag != "%") {
end_text()
}
if (flag == "%") { # <%%
skip(1)
fputs("<%")
} else if (flag == "=") { # <%=
skip(1)
fputs("__print ")
state = "TAG"
} else if (flag == "+") { # <%+
if (!match(buff, /[^%]%>/)) {
fail(11, "syntax error: <%+ must be closed on the same line")
}
filename = trim(substr(buff, 2, match(buff, /.-?%>/) - 1))
skip(RSTART)
include(filename)
state = "TAG"
} else if (flag == "#") { # <%#
state = "COMMENT"
} else {
state = "TAG"
}
} else if (state != "TEXT" && match(buff, /%>/)) {
flag = RSTART > 1 ? substr(buff, RSTART - 1, 1) : ""
if (flag == "%") { # %%>
flush(RSTART - 2)
skip(1)
flush(2)
} else if (flag == "-") { # -%>
flush(RSTART - 2)
skip(3)
print_nl = 0
} else { # %>
flush(RSTART - 1)
skip(2)
}
if (flag != "%") {
start_text()
}
} else {
flush()
}
}
}
BEGIN {
FS = ""
depth = 0
puts("#!" (SHELL ~ /\// ? SHELL : "/usr/bin/env " SHELL))
puts("set -eu")
puts("if ( set -o pipefail 2>/dev/null ); then set -o pipefail; fi")
puts("__print() { printf '%s' \"$*\"; }")
split(VARS, _lines, /\n/)
for (_i in _lines) {
puts(_lines[_i])
}
init()
}
{
if (NR == 1) {
filenames[0] = FILENAME # this var is not defined in BEGIN so we must do it here
}
buff = $0
process_line()
if (print_nl && state != "COMMENT") {
puts("")
}
}
END {
end_text()
}
AWK
)
AWK_ERR_FILTER=$(cat <<'AWK'
function line_info(lno, _line, _i) {
while ((getline _line < MAPFILE) > 0 && _i++ < lno) { }
close(MAPFILE)
return _line
}
{
if (match($0, "^" SRCFILE ":( line)? ?[0-9]+:") && match(substr($0, 1, RLENGTH), /[0-9]+:$/)) {
lno = substr($0, RSTART, RLENGTH - 1) + 0
msg = substr($0, RSTART + RLENGTH + 1) # v-- some shells duplicate filename
msg = index(msg, SRCFILE ":") == 1 ? substr(msg, length(SRCFILE) + 3) : msg
print(line_info(lno) ": " msg)
} else if ($0 != "") {
print($0)
}
}
AWK
)
readonly AWK_CONVERTER AWK_ERR_FILTER
print_help() {
sed -En '/^#---help---/,/^#---help---/p' "$SCRIPTPATH" | sed -E 's/^# ?//; 1d;$d;'
}
filter_shell_stderr() {
$ESH_AWK \
-v SRCFILE="$1" \
-v MAPFILE="$2" \
-- "$AWK_ERR_FILTER"
}
evaluate() {
local srcfile="$1"
local mapfile="$2"
# This FD redirection magic is for swapping stdout/stderr back and forth.
exec 3>&1
{ set +e; $ESH_SHELL "$srcfile" 2>&1 1>&3; echo $? >>"$mapfile"; } \
| filter_shell_stderr "$srcfile" "$mapfile" >&2
exec 3>&-
return $(tail -n 1 "$mapfile")
}
convert() {
local input="$1"
local vars="$2"
local map_file="${3:-"/dev/null"}"
$ESH_AWK \
-v MAX_DEPTH="$ESH_MAX_DEPTH" \
-v SHELL="$ESH_SHELL" \
-v MAP_FILE="$map_file" \
-v VARS="$vars" \
-- "$AWK_CONVERTER" "$input"
}
process() {
local input="$1"
local vars="$2"
local evaluate="${3:-yes}"
local ret=0 tmpfile mapfile
if [ "$evaluate" = yes ]; then
tmpfile=$(mktemp)
mapfile=$(mktemp)
convert "$input" "$vars" "$mapfile" > "$tmpfile" || ret=$?
test $ret -ne 0 || evaluate "$tmpfile" "$mapfile" || ret=$?
rm -f "$tmpfile" "$mapfile"
else
convert "$input" "$vars" || ret=$?
fi
return $ret
}
: ${ESH_AWK:="awk"}
: ${ESH_MAX_DEPTH:=3}
: ${ESH_SHELL:="/bin/sh"}
EVALUATE='yes'
OUTPUT=''
while getopts ':dho:s:V' OPT; do
case "$OPT" in
d) EVALUATE=no;;
h) print_help; exit 0;;
o) OUTPUT="$OPTARG";;
s) ESH_SHELL="$OPTARG";;
V) echo "$PROGNAME $VERSION"; exit 0;;
'?') echo "$PROGNAME: unknown option: -$OPTARG" >&2; exit 10;;
esac
done
shift $(( OPTIND - 1 ))
if [ $# -eq 0 ]; then
printf "$PROGNAME: %s\n\n" 'missing argument <input>' >&2
print_help >&2
exit 10
fi
INPUT="$1"; shift
[ "$INPUT" != '-' ] || INPUT=''
if [ "$INPUT" ] && ! [ -f "$INPUT" -a -r "$INPUT" ]; then
echo "$PROGNAME: can't read $INPUT: not a file or not readable" >&2; exit 10
fi
# Validate arguments.
for arg in "$@"; do
case "$arg" in
*=*) ;;
*) echo "$PROGNAME: illegal argument: $arg" >&2; exit 10;;
esac
done
# Format variables into shell variable assignments.
vars=''; for item in "$@"; do
vars="$vars\n${item%%=*}='$(
printf %s "${item#*=}" | $ESH_AWK "{ gsub(/'/, \"'\\\\\\\''\"); print }"
)'"
done
export ESH="$0"
if [ "${OUTPUT#-}" ]; then
tmpfile="$(mktemp)"
trap "rm -f '$tmpfile'" EXIT HUP INT TERM
process "$INPUT" "$vars" "$EVALUATE" > "$tmpfile"
mv "$tmpfile" "$OUTPUT"
else
process "$INPUT" "$vars" "$EVALUATE"
fi
Loading…
Cancel
Save