mirror of
https://github.com/dredx/prole.git
synced 2026-09-23 11:03:59 +00:00
Refactor shell layout; add shellspec + authority
- Introduce lib/shell helpers and keep etc/* scripts thin via compatibility shims - Move Kerberos validation to scripts/validation/check_kerberos.sh and update callers - Add deterministic shellspec unit tests under tests/shellspec/ and wire Maven to run them - Add minimal Spring Boot authority module with startup + /health endpoint and Maven wiring - Document the new layout in docs/layout.md Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
parent
502f039c0b
commit
909e92109e
49
authority/pom.xml
Normal file
49
authority/pom.xml
Normal file
@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<groupId>org.prole</groupId>
|
||||
<artifactId>authority</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>prole-authority</name>
|
||||
<description>Minimal Authority service for Prole</description>
|
||||
|
||||
<properties>
|
||||
<java.version>21</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,11 @@
|
||||
package org.prole.authority;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class AuthorityApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AuthorityApplication.class, args);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package org.prole.authority;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class HealthController {
|
||||
|
||||
@GetMapping("/health")
|
||||
public String health() {
|
||||
return "ok";
|
||||
}
|
||||
}
|
||||
3
authority/src/main/resources/application.properties
Normal file
3
authority/src/main/resources/application.properties
Normal file
@ -0,0 +1,3 @@
|
||||
server.port=8080
|
||||
|
||||
management.endpoints.web.exposure.include=health,info
|
||||
@ -0,0 +1,12 @@
|
||||
package org.prole.authority;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class AuthorityApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
}
|
||||
21
docs/layout.md
Normal file
21
docs/layout.md
Normal file
@ -0,0 +1,21 @@
|
||||
# Repository layout (first-pass)
|
||||
|
||||
This repo is being refactored toward a clearer separation between runtime scripts, reusable shell libraries, operator validation scripts, and tests.
|
||||
|
||||
## Top-level conventions
|
||||
|
||||
- `etc/`
|
||||
- Runtime/bootstrap/config scripts only.
|
||||
- May contain thin compatibility shims that forward to new locations.
|
||||
- `lib/shell/`
|
||||
- Reusable shell helper libraries intended to be sourced by CLI/runtime scripts.
|
||||
- Prefer keeping logic here deterministic/testable; keep entrypoint scripts thin.
|
||||
- `scripts/validation/`
|
||||
- Operator-run validation/check scripts.
|
||||
- These may invoke cluster tooling (`kubectl`, etc.), but should source shared helpers from `lib/shell/`.
|
||||
- `tests/shellspec/`
|
||||
- Shellspec tests for deterministic helper behavior only (no cluster access).
|
||||
- Focus areas: config parsing, env fallback resolution, realm normalization, secret precedence, guardrails, command assembly.
|
||||
- `authority/`
|
||||
- Minimal Maven-backed Spring Boot service.
|
||||
- Provides application startup and a basic health endpoint.
|
||||
3
env.sh
3
env.sh
@ -3,8 +3,7 @@
|
||||
# This file is generated by the installer. Source it in new shells, or execute as a wrapper:
|
||||
# "$PROLE_HOME/env.sh" <command> [args…]
|
||||
# shellcheck shell=bash
|
||||
PROLE_HOME="${PROLE_HOME:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
|
||||
export PROLE_HOME
|
||||
export PROLE_HOME="$HOME/dev/prole"
|
||||
export PROLE_CONF="${PROLE_CONF:-$PROLE_HOME/conf}"
|
||||
export PROLE_DATA="${PROLE_DATA:-$HOME/.prole/data}"
|
||||
export PROLE_LOGS="${PROLE_LOGS:-/opt/prole/logs/${USER}}"
|
||||
|
||||
@ -1,150 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# Shared helpers for common core init scripts (ArgoCD, OpenBao, OpenTofu, Garage).
|
||||
# Responsibilities:
|
||||
# - handle [-c|--config] early so prole_cfg.sh loads the right prole.cfg
|
||||
# - parse standard actions/options
|
||||
# - resolve and apply namespaces consistently
|
||||
# Compatibility shim: shared shell libraries live in `lib/shell/`.
|
||||
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
|
||||
# Actions supported by all common core scripts
|
||||
COMMON_CORE_ACTIONS="start|stop|status|restart|initialize|update|reload"
|
||||
|
||||
# Parse -c/--config before loading prole_cfg.sh so PROLE_CONF is set in time.
|
||||
# Sets:
|
||||
# COMMON_CORE_CONFIG_PATH - path to prole.cfg (if provided)
|
||||
# COMMON_CORE_ARGS - original arguments minus -c/--config
|
||||
common_core_preparse_config() {
|
||||
COMMON_CORE_CONFIG_PATH=""
|
||||
COMMON_CORE_ARGS=()
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-c|--config)
|
||||
shift
|
||||
if [[ -z "${1:-}" ]]; then
|
||||
echo "ERROR: -c/--config requires a file path" >&2
|
||||
exit 2
|
||||
fi
|
||||
COMMON_CORE_CONFIG_PATH="$1"
|
||||
;;
|
||||
-c=*|--config=*)
|
||||
COMMON_CORE_CONFIG_PATH="${1#*=}"
|
||||
;;
|
||||
*)
|
||||
COMMON_CORE_ARGS+=("$1")
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ -n "$COMMON_CORE_CONFIG_PATH" ]]; then
|
||||
if [[ ! -f "$COMMON_CORE_CONFIG_PATH" ]]; then
|
||||
echo "ERROR: config file not found: $COMMON_CORE_CONFIG_PATH" >&2
|
||||
exit 2
|
||||
fi
|
||||
local cfg_dir
|
||||
cfg_dir=$(cd "$(dirname "$COMMON_CORE_CONFIG_PATH")" && pwd)
|
||||
PROLE_CONF="$cfg_dir"
|
||||
export PROLE_CONF
|
||||
fi
|
||||
}
|
||||
|
||||
# Parse standard options and action.
|
||||
# Sets (always):
|
||||
# COMMON_CORE_ACTION
|
||||
# COMMON_CORE_NAMESPACE
|
||||
# COMMON_CORE_HELP (0/1)
|
||||
# COMMON_CORE_PARSE_ERROR (empty or message)
|
||||
common_core_parse_args() {
|
||||
COMMON_CORE_ACTION=""
|
||||
COMMON_CORE_NAMESPACE=""
|
||||
COMMON_CORE_HELP=0
|
||||
COMMON_CORE_PARSE_ERROR=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-m|--mode)
|
||||
shift
|
||||
prole_set_mode "${1:-}"
|
||||
;;
|
||||
-m=*|--mode=*)
|
||||
prole_set_mode "${1#*=}"
|
||||
;;
|
||||
-n|--namespace)
|
||||
shift
|
||||
if [[ -z "${1:-}" ]]; then
|
||||
COMMON_CORE_PARSE_ERROR="--namespace requires a value"
|
||||
break
|
||||
fi
|
||||
COMMON_CORE_NAMESPACE="$1"
|
||||
;;
|
||||
-n=*|--namespace=*)
|
||||
COMMON_CORE_NAMESPACE="${1#*=}"
|
||||
;;
|
||||
start|stop|status|restart|initialize|update|reload)
|
||||
COMMON_CORE_ACTION="$1"
|
||||
;;
|
||||
-h|--help)
|
||||
COMMON_CORE_HELP=1
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
if [[ -z "$COMMON_CORE_ACTION" && "$1" != -* ]]; then
|
||||
COMMON_CORE_ACTION="$1"
|
||||
else
|
||||
COMMON_CORE_PARSE_ERROR="Unknown argument: $1"
|
||||
break
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ -z "$COMMON_CORE_ACTION" && "$COMMON_CORE_HELP" -eq 0 && -z "$COMMON_CORE_PARSE_ERROR" ]]; then
|
||||
COMMON_CORE_PARSE_ERROR="Action is required (${COMMON_CORE_ACTIONS//|/, })"
|
||||
fi
|
||||
}
|
||||
|
||||
common_core_usage() {
|
||||
local prog="${1:-$0}"
|
||||
echo "Usage: ${prog##*/} [${COMMON_CORE_ACTIONS//|/|}] [-n namespace] [--mode k3d|k3s|k8s] [-c conf/prole.cfg]" >&2
|
||||
}
|
||||
|
||||
# Resolve namespace with precedence: CLI override -> SERVICE_NAMESPACE -> NAMESPACE -> provided default
|
||||
common_core_resolve_namespace() {
|
||||
local default_ns="${1:-default}"
|
||||
local ns="${COMMON_CORE_NAMESPACE:-}"
|
||||
[[ -z "$ns" && -n "${SERVICE_NAMESPACE:-}" ]] && ns="$SERVICE_NAMESPACE"
|
||||
[[ -z "$ns" && -n "${NAMESPACE:-}" ]] && ns="$NAMESPACE"
|
||||
[[ -z "$ns" ]] && ns="$default_ns"
|
||||
|
||||
# In k3s mode, common core services must not default into the `default` namespace.
|
||||
# If the caller didn't supply an explicit namespace, normalize `default` -> SERVICE_NAMESPACE
|
||||
# from prole.cfg (Explicit `-n default` is treated as a legacy/mistake and will be corrected).
|
||||
local mode="${PROLE_MODE:-}"
|
||||
if declare -F prole_normalize_mode >/dev/null 2>&1; then
|
||||
mode="$(prole_normalize_mode "$mode")"
|
||||
fi
|
||||
if [[ "$mode" == "k3s" && "$ns" == "default" ]]; then
|
||||
if [[ -n "${SERVICE_NAMESPACE:-}" && "${SERVICE_NAMESPACE}" != "default" ]]; then
|
||||
ns="$SERVICE_NAMESPACE"
|
||||
elif [[ -n "${PROLE_NAMESPACE:-}" && "${PROLE_NAMESPACE}" != "default" ]]; then
|
||||
ns="$PROLE_NAMESPACE"
|
||||
else
|
||||
echo "ERROR: k3s mode requires a non-default service namespace. Set SERVICE_NAMESPACE in prole.cfg or pass -n." >&2
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
echo "$ns"
|
||||
}
|
||||
|
||||
# Apply a resolved namespace to both NAMESPACE and SERVICE_NAMESPACE for consistency
|
||||
common_core_apply_namespace() {
|
||||
local ns="$1"
|
||||
if [[ -n "$ns" ]]; then
|
||||
NAMESPACE="$ns"
|
||||
SERVICE_NAMESPACE="$ns"
|
||||
export NAMESPACE SERVICE_NAMESPACE
|
||||
fi
|
||||
}
|
||||
# shellcheck disable=SC1091
|
||||
source "$SCRIPT_DIR/../lib/shell/common_core_lib.sh"
|
||||
|
||||
@ -1034,7 +1034,12 @@ run_test() {
|
||||
ensure_krb5_conf_configmap
|
||||
apply_krb5_conf_to_test_pod
|
||||
|
||||
if [[ -x "$SCRIPT_DIR/init_kerberos_test.sh" ]]; then
|
||||
local kerberos_check_script="$SCRIPT_DIR/../scripts/validation/check_kerberos.sh"
|
||||
if [[ ! -x "$kerberos_check_script" ]]; then
|
||||
kerberos_check_script="$SCRIPT_DIR/init_kerberos_test.sh"
|
||||
fi
|
||||
|
||||
if [[ -x "$kerberos_check_script" ]]; then
|
||||
local test_samba_dns="${SAMBA_DNS_SERVER:-}"
|
||||
if [[ "${KRB5_AD_PORT_FORWARD}" == "1" ]]; then
|
||||
test_samba_dns="$effective_kdc"
|
||||
@ -1050,7 +1055,7 @@ run_test() {
|
||||
KRB5_USER="${KERBEROS_TEST_ADMIN_USER:-administrator}" KRB5_PASSWORD="$KRB5_PASSWORD" \
|
||||
SAMBA_ADMIN_USER="${KERBEROS_TEST_ADMIN_USER:-administrator}" SAMBA_ADMIN_PASSWORD="$KRB5_PASSWORD" \
|
||||
SAMBA_DNS_SERVER="$test_samba_dns" \
|
||||
"$SCRIPT_DIR/init_kerberos_test.sh" test; then
|
||||
"$kerberos_check_script" test; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
@ -1085,7 +1090,7 @@ run_test() {
|
||||
exit 1
|
||||
done
|
||||
else
|
||||
err "init_kerberos_test.sh not found."
|
||||
err "Kerberos validation script not found (expected $SCRIPT_DIR/../scripts/validation/check_kerberos.sh)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@ -2,570 +2,13 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# init_kerberos_test.sh
|
||||
# Purpose:
|
||||
# - Run Kerberos authentication checks inside the in-cluster KDC pod
|
||||
|
||||
# Initialize SCRIPT_DIR
|
||||
# Compatibility shim: Kerberos validation scripts live under `scripts/validation/`.
|
||||
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
|
||||
ORIG_ARGS=("$@")
|
||||
|
||||
# Load env
|
||||
if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then
|
||||
set --
|
||||
# shellcheck disable=SC1090
|
||||
source "$PROLE_HOME/env.sh"
|
||||
set -- "${ORIG_ARGS[@]}"
|
||||
elif [[ -f "$HOME/.prole/env.sh" ]]; then
|
||||
set --
|
||||
# shellcheck disable=SC1090
|
||||
source "$HOME/.prole/env.sh"
|
||||
set -- "${ORIG_ARGS[@]}"
|
||||
check_script="$SCRIPT_DIR/../scripts/validation/check_kerberos.sh"
|
||||
if [[ -x "$check_script" ]]; then
|
||||
exec "$check_script" "$@"
|
||||
fi
|
||||
|
||||
# Load config values from prole.cfg before applying defaults/CLI overrides.
|
||||
# shellcheck disable=SC1090
|
||||
source "$SCRIPT_DIR/prole_cfg.sh"
|
||||
|
||||
if [[ "${1:-}" == "--mode" || "${1:-}" == "-m" ]]; then
|
||||
prole_set_mode "${2:-}"
|
||||
shift 2
|
||||
elif [[ "${1:-}" == --mode=* || "${1:-}" == -m=* ]]; then
|
||||
prole_set_mode "${1#*=}"
|
||||
shift
|
||||
fi
|
||||
|
||||
ACTION=${1:-test}
|
||||
|
||||
NAMESPACE="${PROLE_NAMESPACE}"
|
||||
SERVICE_NAMESPACE=${SERVICE_NAMESPACE:-${NAMESPACE}}
|
||||
KRB5_REALM=${KRB5_REALM:-${REALM:-}}
|
||||
KRB5_KDC=${KRB5_KDC:-}
|
||||
KRB5_USER=${KRB5_USER:-${KRB5_USERNAME:-}}
|
||||
KRB5_PASSWORD=${KRB5_PASSWORD:-}
|
||||
PROLE_KDC_NAME=${PROLE_KDC_NAME:-auth}
|
||||
PROLE_KDC_SERVICE=${PROLE_KDC_SERVICE:-auth}
|
||||
SAMBA_ADMIN_USER=${SAMBA_ADMIN_USER:-}
|
||||
SAMBA_ADMIN_PASSWORD=${SAMBA_ADMIN_PASSWORD:-}
|
||||
SAMBA_DNS_SERVER=${SAMBA_DNS_SERVER:-}
|
||||
KDC_POD_READY_TIMEOUT=${KDC_POD_READY_TIMEOUT:-60}
|
||||
KDC_POD_READY_RETRIES=${KDC_POD_READY_RETRIES:-5}
|
||||
PROLE_KDC_PRECHECK_TIMEOUT=${PROLE_KDC_PRECHECK_TIMEOUT:-5}
|
||||
|
||||
ensure_tools() {
|
||||
for t in kubectl curl jq; do
|
||||
command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; }
|
||||
done
|
||||
}
|
||||
|
||||
ensure_namespace() {
|
||||
if ! kubectl get namespace "$NAMESPACE" >/dev/null 2>&1; then
|
||||
echo "Creating namespace '$NAMESPACE' ..."
|
||||
kubectl create namespace "$NAMESPACE" >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
write_krb5_conf_to_pod() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
if [[ -z "$kdc_ns" || -z "$pod_name" ]]; then
|
||||
return 0
|
||||
fi
|
||||
if [[ -z "$KRB5_REALM" || -z "$KRB5_KDC" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
local admin_val domain_val tmp
|
||||
admin_val="${KRB5_ADMIN:-$KRB5_KDC}"
|
||||
domain_val=$(printf '%s' "$KRB5_REALM" | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
tmp=$(mktemp)
|
||||
cat >"$tmp" <<EOF
|
||||
[libdefaults]
|
||||
default_realm = $KRB5_REALM
|
||||
dns_lookup_realm = false
|
||||
dns_lookup_kdc = false
|
||||
udp_preference_limit = 1
|
||||
|
||||
[realms]
|
||||
$KRB5_REALM = {
|
||||
kdc = $KRB5_KDC
|
||||
admin_server = $admin_val
|
||||
}
|
||||
|
||||
[domain_realm]
|
||||
.$domain_val = $KRB5_REALM
|
||||
$domain_val = $KRB5_REALM
|
||||
EOF
|
||||
|
||||
echo "Updating /etc/krb5.conf in test pod ${pod_name} for realm ${KRB5_REALM} ..."
|
||||
if ! kubectl -n "$kdc_ns" exec -i "$pod_name" -- sh -c 'cat > /etc/krb5.conf' <"$tmp"; then
|
||||
echo "WARN: Unable to write /etc/krb5.conf in ${pod_name}." >&2
|
||||
fi
|
||||
rm -f "$tmp"
|
||||
}
|
||||
|
||||
get_ready_kdc_pod() {
|
||||
local kdc_ns="$1"
|
||||
kubectl -n "$kdc_ns" wait --for=condition=Ready pod -l "app=${PROLE_KDC_NAME}" --timeout="${KDC_POD_READY_TIMEOUT}s" >/dev/null 2>&1 || true
|
||||
kubectl -n "$kdc_ns" get pod -l "app=${PROLE_KDC_NAME}" --field-selector=status.phase=Running -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true
|
||||
}
|
||||
|
||||
wait_for_kdc_pod() {
|
||||
local kdc_ns="$1"
|
||||
local attempt pod
|
||||
attempt=1
|
||||
while [[ $attempt -le $KDC_POD_READY_RETRIES ]]; do
|
||||
pod=$(get_ready_kdc_pod "$kdc_ns")
|
||||
if [[ -n "$pod" ]]; then
|
||||
printf '%s' "$pod"
|
||||
return 0
|
||||
fi
|
||||
echo "Waiting for KDC pod '${PROLE_KDC_NAME}' to be ready... (${attempt}/${KDC_POD_READY_RETRIES})" >&2
|
||||
sleep 2
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Return 0 if pod is in CrashLoopBackOff (any container), else 1
|
||||
is_pod_crashloop() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
if [[ -z "$pod_name" ]]; then
|
||||
return 1
|
||||
fi
|
||||
local reason
|
||||
reason=$(kubectl -n "$kdc_ns" get pod "$pod_name" -o jsonpath='{range .status.containerStatuses[*]}{.state.waiting.reason}{"\n"}{end}' 2>/dev/null | tr -d '\r' | tr -s '\n' ' ' || true)
|
||||
if echo "${reason}" | grep -q "CrashLoopBackOff"; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
debug_kdc_pod() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
if [[ -z "$pod_name" ]]; then
|
||||
return 0
|
||||
fi
|
||||
echo "--- describe pod ${pod_name} ---" >&2
|
||||
kubectl -n "$kdc_ns" describe pod "$pod_name" 1>&2 || true
|
||||
echo "--- last 200 log lines from ${pod_name} ---" >&2
|
||||
kubectl -n "$kdc_ns" logs "$pod_name" --tail=200 1>&2 || true
|
||||
}
|
||||
|
||||
kdc_exec() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
shift 2
|
||||
local output=""
|
||||
if output=$(kubectl -n "$kdc_ns" exec "$pod_name" -- "$@" 2>&1); then
|
||||
printf '%s' "$output"
|
||||
return 0
|
||||
fi
|
||||
if echo "$output" | grep -qi "completed pod"; then
|
||||
return 2
|
||||
fi
|
||||
if echo "$output" | grep -qi "not found"; then
|
||||
return 2
|
||||
fi
|
||||
echo "$output" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
run_samba_join() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
local domain="$3"
|
||||
local output=""
|
||||
if output=$(kubectl -n "$kdc_ns" exec "$pod_name" -- \
|
||||
env SAMBA_ADMIN_USER="$SAMBA_ADMIN_USER" SAMBA_ADMIN_PASSWORD="$SAMBA_ADMIN_PASSWORD" \
|
||||
SAMBA_DNS_SERVER="$SAMBA_DNS_SERVER" SAMBA_REALM="${KRB5_REALM:-}" \
|
||||
/bin/sh -c 'realm_flag=""; [ -n "${SAMBA_REALM}" ] && realm_flag="--realm=${SAMBA_REALM}"; samba-tool domain join "'"$domain"'" MEMBER -U"${SAMBA_ADMIN_USER}%${SAMBA_ADMIN_PASSWORD}" --server="${SAMBA_DNS_SERVER}" ${realm_flag}' 2>&1); then
|
||||
printf '%s' "$output"
|
||||
return 0
|
||||
fi
|
||||
if echo "$output" | grep -qi "completed pod"; then
|
||||
return 2
|
||||
fi
|
||||
if echo "$output" | grep -qi "not found"; then
|
||||
return 2
|
||||
fi
|
||||
if [[ -n "$output" ]]; then
|
||||
echo "$output" >&2
|
||||
else
|
||||
echo "samba-tool produced no output." >&2
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
run_kinit() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
local output=""
|
||||
|
||||
# Prefer /etc/krb5.conf if it exists, otherwise fallback to /opt/prole-kdc/krb5.conf
|
||||
local krb5_config="/etc/krb5.conf"
|
||||
if ! kubectl -n "$kdc_ns" exec "$pod_name" -- ls /etc/krb5.conf >/dev/null 2>&1; then
|
||||
krb5_config="/opt/prole-kdc/krb5.conf"
|
||||
fi
|
||||
|
||||
echo "Running kinit for ${KRB5_USER}@${KRB5_REALM} inside ${PROLE_KDC_NAME} (${pod_name}) using ${krb5_config} ..."
|
||||
if output=$(printf '%s\n' "$KRB5_PASSWORD" | kubectl -n "$kdc_ns" exec -i "$pod_name" -- \
|
||||
env KRB5_CONFIG="$krb5_config" kinit "${KRB5_USER}@${KRB5_REALM}" 2>&1); then
|
||||
printf '%s' "$output"
|
||||
return 0
|
||||
fi
|
||||
if echo "$output" | grep -qi "completed pod"; then
|
||||
return 2
|
||||
fi
|
||||
if echo "$output" | grep -qi "not found"; then
|
||||
return 2
|
||||
fi
|
||||
if [[ -n "$output" ]]; then
|
||||
echo "$output" >&2
|
||||
else
|
||||
echo "kinit produced no output." >&2
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
check_samba_connectivity() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
if [[ -z "$SAMBA_DNS_SERVER" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Checking connectivity from ${PROLE_KDC_NAME} to ${SAMBA_DNS_SERVER} ..."
|
||||
local ports="88 389 445 464"
|
||||
local port
|
||||
for port in $ports; do
|
||||
local out=""
|
||||
out=$(kubectl -n "$kdc_ns" exec "$pod_name" -- /bin/sh -c "timeout 3 bash -c '</dev/tcp/${SAMBA_DNS_SERVER}/${port}'" 2>&1) || true
|
||||
if [[ -z "$out" ]]; then
|
||||
echo "OK: ${SAMBA_DNS_SERVER}:${port}"
|
||||
else
|
||||
echo "WARN: ${SAMBA_DNS_SERVER}:${port} unreachable: ${out}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check_kdc_direct_connectivity() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
local kdc_ip="${AD_DC_IP:-${KDC_ANSIBLE_DETECTED:-${KDC_AUTO_DETECTED:-}}}"
|
||||
if [[ -z "$kdc_ip" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Checking connectivity from ${PROLE_KDC_NAME} to KDC IP ${kdc_ip} ..."
|
||||
local ports="88 389 445 464"
|
||||
local port
|
||||
for port in $ports; do
|
||||
local out=""
|
||||
out=$(kubectl -n "$kdc_ns" exec "$pod_name" -- /bin/sh -c "timeout 3 bash -c '</dev/tcp/${kdc_ip}/${port}'" 2>&1) || true
|
||||
if [[ -z "$out" ]]; then
|
||||
echo "OK: ${kdc_ip}:${port}"
|
||||
else
|
||||
echo "WARN: ${kdc_ip}:${port} unreachable: ${out}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
openbao_url() {
|
||||
if [[ -n "${PROLE_OPENBAO_URL:-}" ]]; then
|
||||
echo "$PROLE_OPENBAO_URL"
|
||||
return 0
|
||||
fi
|
||||
if prole_is_in_cluster; then
|
||||
echo "http://openbao.${SERVICE_NAMESPACE:-${NAMESPACE:-default}}.svc.cluster.local:8200"
|
||||
return 0
|
||||
fi
|
||||
if curl -sS "http://127.0.0.1:8200/v1/sys/health" >/dev/null 2>&1; then
|
||||
echo "http://127.0.0.1:8200"
|
||||
return 0
|
||||
elif curl -sS "http://127.0.0.1:8200/v1/sys/health" >/dev/null 2>&1; then
|
||||
echo "http://127.0.0.1:8200"
|
||||
return 0
|
||||
else
|
||||
echo ""
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
openbao_token() {
|
||||
if [[ -f "$PROLE_SERVICE/secrets/openbao-root-token" ]]; then
|
||||
cat "$PROLE_SERVICE/secrets/openbao-root-token"
|
||||
else
|
||||
echo "${OPENBAO_ROOT_TOKEN:-}"
|
||||
fi
|
||||
}
|
||||
|
||||
fetch_openbao_secret() {
|
||||
local path="$1"
|
||||
local key="$2"
|
||||
local token url
|
||||
token=$(openbao_token)
|
||||
url=$(openbao_url)
|
||||
if [[ -z "$token" || -z "$url" ]]; then
|
||||
echo ""
|
||||
return 0
|
||||
fi
|
||||
curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/$path" | jq -r ".data.data.\"$key\"" || echo ""
|
||||
}
|
||||
|
||||
resolve_krb5_password() {
|
||||
if [[ -z "${KRB5_PASSWORD}" || "${KRB5_PASSWORD}" == '${OPENBAO:'* || "${KRB5_PASSWORD}" == '${PROLE_SECRET:'* ]]; then
|
||||
local path="prole/${NAMESPACE:-default}/kerberos"
|
||||
local fetched
|
||||
fetched=$(fetch_openbao_secret "$path" "password")
|
||||
if [[ -n "$fetched" && "$fetched" != "null" ]]; then
|
||||
KRB5_PASSWORD="$fetched"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
resolve_samba_vars() {
|
||||
if [[ -n "${SAMBA_ADMIN_USER}" && -n "${SAMBA_ADMIN_PASSWORD}" && -n "${SAMBA_DNS_SERVER}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 1. Fallback for DNS server from prole.cfg env (AD_DC_HOST)
|
||||
if [[ -z "$SAMBA_DNS_SERVER" && -n "${AD_DC_HOST:-}" ]]; then
|
||||
SAMBA_DNS_SERVER="$AD_DC_HOST"
|
||||
echo "Using SAMBA_DNS_SERVER=${SAMBA_DNS_SERVER} from AD_DC_HOST"
|
||||
fi
|
||||
|
||||
# 2. Try to resolve from Ansible inventory if possible
|
||||
local root
|
||||
if [[ -n "${PROLE_HOME:-}" && -d "${PROLE_HOME}" ]]; then
|
||||
root="${PROLE_HOME}"
|
||||
else
|
||||
root="${SCRIPT_DIR}/.."
|
||||
fi
|
||||
|
||||
local vars_file="${root}/infrastructure/inventory/group_vars/ad_dc/vars.yml"
|
||||
if [[ -f "$vars_file" ]]; then
|
||||
if [[ -z "$SAMBA_DNS_SERVER" ]]; then
|
||||
SAMBA_DNS_SERVER=$(awk -F: '/^[[:space:]]*samba_dns_server[[:space:]]*:/ {sub(/^[^:]+:[[:space:]]*/, "", $0); gsub(/"/, "", $0); print $0; exit}' "$vars_file")
|
||||
fi
|
||||
if [[ -z "$SAMBA_ADMIN_USER" ]]; then
|
||||
SAMBA_ADMIN_USER=$(awk -F: '/^[[:space:]]*samba_dns_admin_user[[:space:]]*:/ {sub(/^[^:]+:[[:space:]]*/, "", $0); gsub(/"/, "", $0); print $0; exit}' "$vars_file")
|
||||
fi
|
||||
fi
|
||||
|
||||
# 3. Fallback for Admin User
|
||||
if [[ -z "$SAMBA_ADMIN_USER" ]]; then
|
||||
if [[ -n "${AD_DC_USER:-}" ]]; then
|
||||
SAMBA_ADMIN_USER="$AD_DC_USER"
|
||||
echo "Using SAMBA_ADMIN_USER=${SAMBA_ADMIN_USER} from AD_DC_USER"
|
||||
else
|
||||
SAMBA_ADMIN_USER="administrator"
|
||||
echo "Defaulting SAMBA_ADMIN_USER to administrator"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 4. Try to resolve password from Ansible Vault
|
||||
if [[ -z "$SAMBA_ADMIN_PASSWORD" ]]; then
|
||||
local vault_file="${root}/infrastructure/inventory/group_vars/ad_dc/vault.yml"
|
||||
local vault_pass_file=""
|
||||
if [[ -n "${ANSIBLE_VAULT_PASSWORD_FILE:-}" && -f "${ANSIBLE_VAULT_PASSWORD_FILE}" ]]; then
|
||||
vault_pass_file="${ANSIBLE_VAULT_PASSWORD_FILE}"
|
||||
elif [[ -n "${PROLE_HOME:-}" && -f "${PROLE_HOME}/.vault_pass" ]]; then
|
||||
vault_pass_file="${PROLE_HOME}/.vault_pass"
|
||||
elif [[ -f "${root}/.vault_pass" ]]; then
|
||||
vault_pass_file="${root}/.vault_pass"
|
||||
fi
|
||||
|
||||
if [[ -f "$vault_file" && -n "$vault_pass_file" && -x "$(command -v ansible-vault)" ]]; then
|
||||
local vault_out
|
||||
vault_out=$(ansible-vault view "$vault_file" --vault-password-file "$vault_pass_file" 2>/dev/null || true)
|
||||
if [[ -n "$vault_out" ]]; then
|
||||
SAMBA_ADMIN_PASSWORD=$(printf '%s\n' "$vault_out" | awk -F: '/^[[:space:]]*vault_samba_dns_admin_pass[[:space:]]*:/ {sub(/^[^:]+:[[:space:]]*/, "", $0); gsub(/"/, "", $0); print $0; exit}')
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# 5. Fallback for Password from OpenBao
|
||||
if [[ -z "$SAMBA_ADMIN_PASSWORD" ]]; then
|
||||
local path="prole/${NAMESPACE:-default}/ad_dc"
|
||||
local fetched
|
||||
fetched=$(fetch_openbao_secret "$path" "password")
|
||||
if [[ -n "$fetched" && "$fetched" != "null" ]]; then
|
||||
SAMBA_ADMIN_PASSWORD="$fetched"
|
||||
echo "Fetched SAMBA_ADMIN_PASSWORD from OpenBao (${path})"
|
||||
else
|
||||
# Try kerberos path as fallback
|
||||
path="prole/${NAMESPACE:-default}/kerberos"
|
||||
fetched=$(fetch_openbao_secret "$path" "samba_password")
|
||||
if [[ -n "$fetched" && "$fetched" != "null" ]]; then
|
||||
SAMBA_ADMIN_PASSWORD="$fetched"
|
||||
echo "Fetched SAMBA_ADMIN_PASSWORD from OpenBao (${path}#samba_password)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
join_samba_realm_if_needed() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
local domain=""
|
||||
|
||||
resolve_samba_vars
|
||||
|
||||
if [[ -z "$SAMBA_ADMIN_USER" || -z "$SAMBA_ADMIN_PASSWORD" || -z "$SAMBA_DNS_SERVER" ]]; then
|
||||
echo "WARN: Missing Samba join info; skipping samba-tool realm join."
|
||||
return 0
|
||||
fi
|
||||
|
||||
check_samba_connectivity "$kdc_ns" "$pod_name"
|
||||
|
||||
if [[ -n "$KRB5_REALM" ]]; then
|
||||
domain=$(printf '%s' "$KRB5_REALM" | tr '[:upper:]' '[:lower:]')
|
||||
fi
|
||||
if [[ -z "$domain" ]]; then
|
||||
domain="$SAMBA_DNS_SERVER"
|
||||
fi
|
||||
|
||||
if kubectl -n "$kdc_ns" exec "$pod_name" -- test -f /var/lib/samba/private/secrets.tdb >/dev/null 2>&1; then
|
||||
echo "Samba already joined; skipping join."
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Joining Samba realm '${domain}' (server ${SAMBA_DNS_SERVER}) ..."
|
||||
local attempt=1
|
||||
while true; do
|
||||
if run_samba_join "$kdc_ns" "$pod_name" "$domain"; then
|
||||
return 0
|
||||
fi
|
||||
if [[ $? -eq 2 ]]; then
|
||||
if [[ $attempt -ge $KDC_POD_READY_RETRIES ]]; then
|
||||
echo "WARN: KDC pod completed before join could run; skipping samba-tool join." >&2
|
||||
return 0
|
||||
fi
|
||||
pod_name=$(wait_for_kdc_pod "$kdc_ns" || true)
|
||||
if [[ -z "$pod_name" ]]; then
|
||||
echo "WARN: KDC pod unavailable for samba-tool join." >&2
|
||||
return 0
|
||||
fi
|
||||
attempt=$((attempt + 1))
|
||||
continue
|
||||
fi
|
||||
echo "WARN: samba-tool domain join failed; continuing to Kerberos test." >&2
|
||||
return 0
|
||||
done
|
||||
}
|
||||
|
||||
run_test() {
|
||||
ensure_tools
|
||||
ensure_namespace
|
||||
resolve_krb5_password
|
||||
|
||||
# Support both names for the toggle from prole.cfg
|
||||
local enabled="${KERBEROS_ENABLED:-${ENABLED:-false}}"
|
||||
if [[ "$enabled" == "false" || "$enabled" == "0" || "$enabled" == "False" ]]; then
|
||||
echo "Kerberos is disabled (KERBEROS_ENABLED=$enabled). Skipping test."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ -z "$KRB5_REALM" || -z "$KRB5_USER" || -z "$KRB5_PASSWORD" || -z "$KRB5_KDC" ]]; then
|
||||
echo "ERROR: Missing Kerberos configuration. Ensure KRB5_REALM, KRB5_KDC, KRB5_USER, KRB5_PASSWORD are set." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Quick pre-check: if an existing 'auth' deployment is present but not Available, remove it
|
||||
# to avoid starting a rollout that is likely to time out on a stale/broken replica set.
|
||||
local kdc_ns
|
||||
kdc_ns="${SERVICE_NAMESPACE:-${NAMESPACE:-default}}"
|
||||
if kubectl -n "$kdc_ns" get deploy "$PROLE_KDC_NAME" >/dev/null 2>&1; then
|
||||
# Try a fast availability wait; if it fails, treat as unhealthy and clean up before proceeding.
|
||||
if ! kubectl -n "$kdc_ns" wait --for=condition=Available deploy/"$PROLE_KDC_NAME" --timeout="${PROLE_KDC_PRECHECK_TIMEOUT}s" >/dev/null 2>&1; then
|
||||
echo "Detected unhealthy '$PROLE_KDC_NAME' deployment in namespace '$kdc_ns'; removing before Kerberos test rollout to avoid timeout..." >&2
|
||||
if [[ -x "$SCRIPT_DIR/init_kdc.sh" ]]; then
|
||||
SERVICE_NAMESPACE="$SERVICE_NAMESPACE" "$SCRIPT_DIR/init_kdc.sh" cleanup || true
|
||||
else
|
||||
kubectl -n "$kdc_ns" delete deploy "$PROLE_KDC_NAME" --ignore-not-found || true
|
||||
kubectl -n "$kdc_ns" delete svc "$PROLE_KDC_SERVICE" --ignore-not-found || true
|
||||
kubectl -n "$kdc_ns" delete configmap prole-kdc-config --ignore-not-found || true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -x "$SCRIPT_DIR/init_kdc.sh" ]]; then
|
||||
SERVICE_NAMESPACE="$SERVICE_NAMESPACE" KRB5_REALM="$KRB5_REALM" KRB5_KDC="$KRB5_KDC" \
|
||||
KRB5_ADMIN="$KRB5_KDC" KRB5_USER="$KRB5_USER" KRB5_PASSWORD="$KRB5_PASSWORD" \
|
||||
"$SCRIPT_DIR/init_kdc.sh" update || true
|
||||
fi
|
||||
|
||||
local pod_name
|
||||
pod_name=$(wait_for_kdc_pod "$kdc_ns" || true)
|
||||
if [[ -z "$pod_name" ]]; then
|
||||
echo "ERROR: KDC pod '${PROLE_KDC_NAME}' not found in namespace '$kdc_ns'. Run init_kdc.sh update first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If the pod is crashlooping, dump logs and fail fast
|
||||
if is_pod_crashloop "$kdc_ns" "$pod_name"; then
|
||||
echo "ERROR: KDC pod '${pod_name}' is in CrashLoopBackOff. Dumping diagnostics..." >&2
|
||||
debug_kdc_pod "$kdc_ns" "$pod_name"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
write_krb5_conf_to_pod "$kdc_ns" "$pod_name"
|
||||
|
||||
check_kdc_direct_connectivity "$kdc_ns" "$pod_name"
|
||||
|
||||
join_samba_realm_if_needed "$kdc_ns" "$pod_name"
|
||||
|
||||
echo "Running kinit for ${KRB5_USER}@${KRB5_REALM} inside ${PROLE_KDC_NAME} (${pod_name}) ..."
|
||||
local attempt=1
|
||||
while true; do
|
||||
if run_kinit "$kdc_ns" "$pod_name"; then
|
||||
break
|
||||
fi
|
||||
if [[ $? -eq 2 ]] || kubectl -n "$kdc_ns" get pod "$pod_name" -o jsonpath='{.status.phase}' 2>/dev/null | grep -qi "Succeeded"; then
|
||||
if [[ $attempt -ge $KDC_POD_READY_RETRIES ]]; then
|
||||
echo "ERROR: KDC pod completed before kinit could run." >&2
|
||||
exit 1
|
||||
fi
|
||||
pod_name=$(wait_for_kdc_pod "$kdc_ns" || true)
|
||||
if [[ -z "$pod_name" ]]; then
|
||||
echo "ERROR: KDC pod unavailable for kinit." >&2
|
||||
exit 1
|
||||
fi
|
||||
attempt=$((attempt + 1))
|
||||
continue
|
||||
fi
|
||||
# If the pod is crashlooping, show logs to aid troubleshooting
|
||||
if is_pod_crashloop "$kdc_ns" "$pod_name"; then
|
||||
echo "ERROR: KDC pod '${pod_name}' entered CrashLoopBackOff during kinit. Dumping diagnostics..." >&2
|
||||
debug_kdc_pod "$kdc_ns" "$pod_name"
|
||||
fi
|
||||
echo "ERROR: kinit failed for ${KRB5_USER}@${KRB5_REALM}." >&2
|
||||
exit 1
|
||||
done
|
||||
|
||||
echo "Kerberos ticket cache:"
|
||||
# Determine krb5 config path in the pod similar to run_kinit()
|
||||
local krb5_config_in_pod="/etc/krb5.conf"
|
||||
if ! kubectl -n "$kdc_ns" exec "$pod_name" -- ls /etc/krb5.conf >/dev/null 2>&1; then
|
||||
krb5_config_in_pod="/opt/prole-kdc/krb5.conf"
|
||||
fi
|
||||
kubectl -n "$kdc_ns" exec "$pod_name" -- env KRB5_CONFIG="$krb5_config_in_pod" klist || true
|
||||
}
|
||||
|
||||
case "$ACTION" in
|
||||
test)
|
||||
run_test
|
||||
;;
|
||||
cleanup)
|
||||
echo "No test pods to cleanup (KDC-based test)."
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {test|cleanup}" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
echo "ERROR: validation script not found or not executable: $check_script" >&2
|
||||
exit 1
|
||||
|
||||
@ -4,6 +4,11 @@ k3s_state: present
|
||||
k3s_version: ""
|
||||
k3s_guard_token_drift: true
|
||||
|
||||
# k3s service startup can be slow on first boot (image pulls, containerd unpacking, etc.).
|
||||
# The service task is best-effort and then Ansible polls `systemctl is-active` using these knobs.
|
||||
k3s_service_start_retries: 60
|
||||
k3s_service_start_delay: 5
|
||||
|
||||
# Destructive repair/refresh workflow (server only)
|
||||
# A refresh wipes the k3s installation/state to a blank slate but preserves the
|
||||
# join token and CA material so existing agents can rejoin without changing the token.
|
||||
|
||||
@ -1,13 +1,20 @@
|
||||
---
|
||||
|
||||
- name: Check if controller has conf/prole.cfg (optional)
|
||||
ansible.builtin.stat:
|
||||
path: "{{ role_path }}/../../../conf/prole.cfg"
|
||||
register: _k3s_prole_cfg_stat
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Load CNPG version from prole.cfg (pinned)
|
||||
ansible.builtin.set_fact:
|
||||
cnpg_version_raw: >-
|
||||
{{ lookup(
|
||||
'ansible.builtin.ini',
|
||||
'CNPG_VERSION section=Global file=' + playbook_dir + '/../../conf/prole.cfg',
|
||||
default=(k3s_cnpg_version_default | default('1.28.1'))
|
||||
) }}
|
||||
'CNPG_VERSION section=Global file=' ~ (role_path ~ '/../../../conf/prole.cfg'),
|
||||
default=(k3s_cnpg_version_default | default('1.28.1')),
|
||||
errors='ignore'
|
||||
) if _k3s_prole_cfg_stat.stat.exists else (k3s_cnpg_version_default | default('1.28.1')) }}
|
||||
|
||||
- name: Normalize CNPG version
|
||||
ansible.builtin.set_fact:
|
||||
@ -23,7 +30,13 @@
|
||||
|
||||
- name: Load k3s server URL from prole.cfg
|
||||
ansible.builtin.set_fact:
|
||||
cnpg_prole_k3s_server_cfg: "{{ lookup('ansible.builtin.ini', 'PROLE_K3S_SERVER section=Global file=' + playbook_dir + '/../../conf/prole.cfg', default='') }}"
|
||||
cnpg_prole_k3s_server_cfg: >-
|
||||
{{ lookup(
|
||||
'ansible.builtin.ini',
|
||||
'PROLE_K3S_SERVER section=Global file=' ~ (role_path ~ '/../../../conf/prole.cfg'),
|
||||
default='',
|
||||
errors='ignore'
|
||||
) if _k3s_prole_cfg_stat.stat.exists else '' }}
|
||||
|
||||
- name: Resolve k3s API URL for kubectl
|
||||
ansible.builtin.set_fact:
|
||||
|
||||
@ -12,9 +12,21 @@
|
||||
ansible.builtin.set_fact:
|
||||
k3s_service_name: "{{ 'k3s' if k3s_role == 'server' else 'k3s-agent' }}"
|
||||
|
||||
- name: Check if controller has conf/prole.cfg (optional)
|
||||
ansible.builtin.stat:
|
||||
path: "{{ role_path }}/../../../conf/prole.cfg"
|
||||
register: _k3s_prole_cfg_stat
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Load service namespace from prole.cfg (controller)
|
||||
ansible.builtin.set_fact:
|
||||
k3s_prole_service_namespace_cfg: "{{ lookup('ansible.builtin.ini', 'SERVICE_NAMESPACE section=Global file=' + playbook_dir + '/../../conf/prole.cfg', default='') }}"
|
||||
k3s_prole_service_namespace_cfg: >-
|
||||
{{ lookup(
|
||||
'ansible.builtin.ini',
|
||||
'SERVICE_NAMESPACE section=Global file=' ~ (role_path ~ '/../../../conf/prole.cfg'),
|
||||
default='',
|
||||
errors='ignore'
|
||||
) if _k3s_prole_cfg_stat.stat.exists else '' }}
|
||||
changed_when: false
|
||||
|
||||
- name: Resolve Kong namespaces from prole.cfg (avoid implicit default namespace)
|
||||
|
||||
@ -510,10 +510,23 @@
|
||||
register: k3s_bin
|
||||
|
||||
- name: Ensure k3s service state
|
||||
ansible.builtin.service:
|
||||
name: "{{ k3s_service_name }}"
|
||||
state: "{{ 'started' if k3s_state == 'present' else 'stopped' }}"
|
||||
enabled: "{{ k3s_state == 'present' }}"
|
||||
block:
|
||||
- name: Start/stop k3s service (best-effort)
|
||||
ansible.builtin.service:
|
||||
name: "{{ k3s_service_name }}"
|
||||
state: "{{ 'started' if k3s_state == 'present' else 'stopped' }}"
|
||||
enabled: "{{ k3s_state == 'present' }}"
|
||||
register: _k3s_service_manage
|
||||
failed_when: false
|
||||
|
||||
- name: Wait for k3s service to become active
|
||||
ansible.builtin.command: "systemctl is-active --quiet {{ k3s_service_name }}"
|
||||
register: _k3s_service_active
|
||||
until: _k3s_service_active.rc == 0
|
||||
retries: "{{ k3s_service_start_retries | default(60) }}"
|
||||
delay: "{{ k3s_service_start_delay | default(5) }}"
|
||||
changed_when: false
|
||||
when: k3s_state == 'present'
|
||||
when: k3s_service.stat.exists or k3s_bin.stat.exists
|
||||
|
||||
- name: Flush k3s restart handler before Kubernetes operations
|
||||
|
||||
@ -1,132 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# Shared helpers for common core init scripts (ArgoCD, OpenBao, OpenTofu, Garage).
|
||||
# Responsibilities:
|
||||
# - handle [-c|--config] early so prole_cfg.sh loads the right prole.cfg
|
||||
# - parse standard actions/options
|
||||
# - resolve and apply namespaces consistently
|
||||
# Compatibility shim: shared shell libraries live in `lib/shell/`.
|
||||
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
|
||||
# Actions supported by all common core scripts
|
||||
COMMON_CORE_ACTIONS="start|stop|status|restart|initialize|update|reload"
|
||||
|
||||
# Parse -c/--config before loading prole_cfg.sh so PROLE_CONF is set in time.
|
||||
# Sets:
|
||||
# COMMON_CORE_CONFIG_PATH - path to prole.cfg (if provided)
|
||||
# COMMON_CORE_ARGS - original arguments minus -c/--config
|
||||
common_core_preparse_config() {
|
||||
COMMON_CORE_CONFIG_PATH=""
|
||||
COMMON_CORE_ARGS=()
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-c|--config)
|
||||
shift
|
||||
if [[ -z "${1:-}" ]]; then
|
||||
echo "ERROR: -c/--config requires a file path" >&2
|
||||
exit 2
|
||||
fi
|
||||
COMMON_CORE_CONFIG_PATH="$1"
|
||||
;;
|
||||
-c=*|--config=*)
|
||||
COMMON_CORE_CONFIG_PATH="${1#*=}"
|
||||
;;
|
||||
*)
|
||||
COMMON_CORE_ARGS+=("$1")
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ -n "$COMMON_CORE_CONFIG_PATH" ]]; then
|
||||
if [[ ! -f "$COMMON_CORE_CONFIG_PATH" ]]; then
|
||||
echo "ERROR: config file not found: $COMMON_CORE_CONFIG_PATH" >&2
|
||||
exit 2
|
||||
fi
|
||||
local cfg_dir
|
||||
cfg_dir=$(cd "$(dirname "$COMMON_CORE_CONFIG_PATH")" && pwd)
|
||||
PROLE_CONF="$cfg_dir"
|
||||
export PROLE_CONF
|
||||
fi
|
||||
}
|
||||
|
||||
# Parse standard options and action.
|
||||
# Sets (always):
|
||||
# COMMON_CORE_ACTION
|
||||
# COMMON_CORE_NAMESPACE
|
||||
# COMMON_CORE_HELP (0/1)
|
||||
# COMMON_CORE_PARSE_ERROR (empty or message)
|
||||
common_core_parse_args() {
|
||||
COMMON_CORE_ACTION=""
|
||||
COMMON_CORE_NAMESPACE=""
|
||||
COMMON_CORE_HELP=0
|
||||
COMMON_CORE_PARSE_ERROR=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-m|--mode)
|
||||
shift
|
||||
prole_set_mode "${1:-}"
|
||||
;;
|
||||
-m=*|--mode=*)
|
||||
prole_set_mode "${1#*=}"
|
||||
;;
|
||||
-n|--namespace)
|
||||
shift
|
||||
if [[ -z "${1:-}" ]]; then
|
||||
COMMON_CORE_PARSE_ERROR="--namespace requires a value"
|
||||
break
|
||||
fi
|
||||
COMMON_CORE_NAMESPACE="$1"
|
||||
;;
|
||||
-n=*|--namespace=*)
|
||||
COMMON_CORE_NAMESPACE="${1#*=}"
|
||||
;;
|
||||
start|stop|status|restart|initialize|update|reload)
|
||||
COMMON_CORE_ACTION="$1"
|
||||
;;
|
||||
-h|--help)
|
||||
COMMON_CORE_HELP=1
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
if [[ -z "$COMMON_CORE_ACTION" && "$1" != -* ]]; then
|
||||
COMMON_CORE_ACTION="$1"
|
||||
else
|
||||
COMMON_CORE_PARSE_ERROR="Unknown argument: $1"
|
||||
break
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ -z "$COMMON_CORE_ACTION" && "$COMMON_CORE_HELP" -eq 0 && -z "$COMMON_CORE_PARSE_ERROR" ]]; then
|
||||
COMMON_CORE_PARSE_ERROR="Action is required (${COMMON_CORE_ACTIONS//|/, })"
|
||||
fi
|
||||
}
|
||||
|
||||
common_core_usage() {
|
||||
local prog="${1:-$0}"
|
||||
echo "Usage: ${prog##*/} [${COMMON_CORE_ACTIONS//|/|}] [-n namespace] [--mode k3d|k3s|k8s] [-c conf/prole.cfg]" >&2
|
||||
}
|
||||
|
||||
# Resolve namespace with precedence: CLI override -> SERVICE_NAMESPACE -> NAMESPACE -> provided default
|
||||
common_core_resolve_namespace() {
|
||||
local default_ns="${1:-default}"
|
||||
local ns="${COMMON_CORE_NAMESPACE:-}"
|
||||
[[ -z "$ns" && -n "${SERVICE_NAMESPACE:-}" ]] && ns="$SERVICE_NAMESPACE"
|
||||
[[ -z "$ns" && -n "${NAMESPACE:-}" ]] && ns="$NAMESPACE"
|
||||
[[ -z "$ns" ]] && ns="$default_ns"
|
||||
echo "$ns"
|
||||
}
|
||||
|
||||
# Apply a resolved namespace to both NAMESPACE and SERVICE_NAMESPACE for consistency
|
||||
common_core_apply_namespace() {
|
||||
local ns="$1"
|
||||
if [[ -n "$ns" ]]; then
|
||||
NAMESPACE="$ns"
|
||||
SERVICE_NAMESPACE="$ns"
|
||||
export NAMESPACE SERVICE_NAMESPACE
|
||||
fi
|
||||
}
|
||||
# shellcheck disable=SC1091
|
||||
source "$SCRIPT_DIR/../lib/shell/common_core_lib.sh"
|
||||
|
||||
@ -1011,7 +1011,12 @@ run_test() {
|
||||
ensure_krb5_conf_configmap
|
||||
apply_krb5_conf_to_test_pod
|
||||
|
||||
if [[ -x "$SCRIPT_DIR/init_kerberos_test.sh" ]]; then
|
||||
local kerberos_check_script="$SCRIPT_DIR/../scripts/validation/check_kerberos.sh"
|
||||
if [[ ! -x "$kerberos_check_script" ]]; then
|
||||
kerberos_check_script="$SCRIPT_DIR/init_kerberos_test.sh"
|
||||
fi
|
||||
|
||||
if [[ -x "$kerberos_check_script" ]]; then
|
||||
local test_samba_dns="${SAMBA_DNS_SERVER:-}"
|
||||
if [[ "${KRB5_AD_PORT_FORWARD}" == "1" ]]; then
|
||||
test_samba_dns="$effective_kdc"
|
||||
@ -1027,7 +1032,7 @@ run_test() {
|
||||
KRB5_USER="${KERBEROS_TEST_ADMIN_USER:-administrator}" KRB5_PASSWORD="$KRB5_PASSWORD" \
|
||||
SAMBA_ADMIN_USER="${KERBEROS_TEST_ADMIN_USER:-administrator}" SAMBA_ADMIN_PASSWORD="$KRB5_PASSWORD" \
|
||||
SAMBA_DNS_SERVER="$test_samba_dns" \
|
||||
"$SCRIPT_DIR/init_kerberos_test.sh" test; then
|
||||
"$kerberos_check_script" test; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
@ -1062,7 +1067,7 @@ run_test() {
|
||||
exit 1
|
||||
done
|
||||
else
|
||||
err "init_kerberos_test.sh not found."
|
||||
err "Kerberos validation script not found (expected $SCRIPT_DIR/../scripts/validation/check_kerberos.sh)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
44
pom.xml
44
pom.xml
@ -19,6 +19,8 @@
|
||||
<properties>
|
||||
<java.version>24</java.version>
|
||||
<spring-modulith.version>1.0.0</spring-modulith.version>
|
||||
<skip.shellspec>false</skip.shellspec>
|
||||
<skip.authority>false</skip.authority>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
@ -196,6 +198,48 @@
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>3.5.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>shellspec</id>
|
||||
<phase>test</phase>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<skip>${skip.shellspec}</skip>
|
||||
<executable>bash</executable>
|
||||
<arguments>
|
||||
<argument>${project.basedir}/tests/shellspec/run.sh</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>authority</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<skip>${skip.authority}</skip>
|
||||
<executable>mvn</executable>
|
||||
<arguments>
|
||||
<argument>-f</argument>
|
||||
<argument>${project.basedir}/authority/pom.xml</argument>
|
||||
<argument>clean</argument>
|
||||
<argument>test</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@ -1 +1 @@
|
||||
107
|
||||
108
|
||||
582
scripts/validation/check_kerberos.sh
Executable file
582
scripts/validation/check_kerberos.sh
Executable file
@ -0,0 +1,582 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# check_kerberos.sh
|
||||
# Purpose:
|
||||
# - Run Kerberos authentication checks inside the in-cluster KDC pod
|
||||
|
||||
# Initialize SCRIPT_DIR
|
||||
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
ETC_DIR=$(cd "$SCRIPT_DIR/../../etc" && pwd)
|
||||
LIB_SHELL_DIR=$(cd "$SCRIPT_DIR/../../lib/shell" && pwd)
|
||||
|
||||
ORIG_ARGS=("$@")
|
||||
|
||||
# Load env
|
||||
if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then
|
||||
set --
|
||||
# shellcheck disable=SC1090
|
||||
source "$PROLE_HOME/env.sh"
|
||||
set -- "${ORIG_ARGS[@]}"
|
||||
elif [[ -f "$HOME/.prole/env.sh" ]]; then
|
||||
set --
|
||||
# shellcheck disable=SC1090
|
||||
source "$HOME/.prole/env.sh"
|
||||
set -- "${ORIG_ARGS[@]}"
|
||||
fi
|
||||
|
||||
# Load config values from prole.cfg before applying defaults/CLI overrides.
|
||||
# shellcheck disable=SC1090
|
||||
source "$ETC_DIR/prole_cfg.sh"
|
||||
|
||||
# shellcheck disable=SC1090
|
||||
source "$LIB_SHELL_DIR/prole_env.sh"
|
||||
# shellcheck disable=SC1090
|
||||
source "$LIB_SHELL_DIR/prole_secrets.sh"
|
||||
# shellcheck disable=SC1090
|
||||
source "$LIB_SHELL_DIR/prole_string.sh"
|
||||
# shellcheck disable=SC1090
|
||||
source "$LIB_SHELL_DIR/prole_yaml.sh"
|
||||
|
||||
if [[ "${1:-}" == "--mode" || "${1:-}" == "-m" ]]; then
|
||||
prole_set_mode "${2:-}"
|
||||
shift 2
|
||||
elif [[ "${1:-}" == --mode=* || "${1:-}" == -m=* ]]; then
|
||||
prole_set_mode "${1#*=}"
|
||||
shift
|
||||
fi
|
||||
|
||||
ACTION=${1:-test}
|
||||
|
||||
NAMESPACE="${PROLE_NAMESPACE}"
|
||||
SERVICE_NAMESPACE=${SERVICE_NAMESPACE:-${NAMESPACE}}
|
||||
KRB5_REALM=${KRB5_REALM:-${REALM:-}}
|
||||
KRB5_KDC=${KRB5_KDC:-}
|
||||
KRB5_USER=${KRB5_USER:-${KRB5_USERNAME:-}}
|
||||
KRB5_PASSWORD=${KRB5_PASSWORD:-}
|
||||
PROLE_KDC_NAME=${PROLE_KDC_NAME:-auth}
|
||||
PROLE_KDC_SERVICE=${PROLE_KDC_SERVICE:-auth}
|
||||
SAMBA_ADMIN_USER=${SAMBA_ADMIN_USER:-}
|
||||
SAMBA_ADMIN_PASSWORD=${SAMBA_ADMIN_PASSWORD:-}
|
||||
SAMBA_DNS_SERVER=${SAMBA_DNS_SERVER:-}
|
||||
KDC_POD_READY_TIMEOUT=${KDC_POD_READY_TIMEOUT:-60}
|
||||
KDC_POD_READY_RETRIES=${KDC_POD_READY_RETRIES:-5}
|
||||
PROLE_KDC_PRECHECK_TIMEOUT=${PROLE_KDC_PRECHECK_TIMEOUT:-5}
|
||||
|
||||
KRB5_REALM=$(prole_normalize_realm "${KRB5_REALM:-}")
|
||||
|
||||
ensure_tools() {
|
||||
for t in kubectl curl jq; do
|
||||
command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; }
|
||||
done
|
||||
}
|
||||
|
||||
ensure_namespace() {
|
||||
if ! kubectl get namespace "$NAMESPACE" >/dev/null 2>&1; then
|
||||
echo "Creating namespace '$NAMESPACE' ..."
|
||||
kubectl create namespace "$NAMESPACE" >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
write_krb5_conf_to_pod() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
if [[ -z "$kdc_ns" || -z "$pod_name" ]]; then
|
||||
return 0
|
||||
fi
|
||||
if [[ -z "$KRB5_REALM" || -z "$KRB5_KDC" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
local admin_val domain_val tmp
|
||||
admin_val="${KRB5_ADMIN:-$KRB5_KDC}"
|
||||
domain_val=$(printf '%s' "$KRB5_REALM" | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
tmp=$(mktemp)
|
||||
cat >"$tmp" <<EOF
|
||||
[libdefaults]
|
||||
default_realm = $KRB5_REALM
|
||||
dns_lookup_realm = false
|
||||
dns_lookup_kdc = false
|
||||
udp_preference_limit = 1
|
||||
|
||||
[realms]
|
||||
$KRB5_REALM = {
|
||||
kdc = $KRB5_KDC
|
||||
admin_server = $admin_val
|
||||
}
|
||||
|
||||
[domain_realm]
|
||||
.$domain_val = $KRB5_REALM
|
||||
$domain_val = $KRB5_REALM
|
||||
EOF
|
||||
|
||||
echo "Updating /etc/krb5.conf in test pod ${pod_name} for realm ${KRB5_REALM} ..."
|
||||
if ! kubectl -n "$kdc_ns" exec -i "$pod_name" -- sh -c 'cat > /etc/krb5.conf' <"$tmp"; then
|
||||
echo "WARN: Unable to write /etc/krb5.conf in ${pod_name}." >&2
|
||||
fi
|
||||
rm -f "$tmp"
|
||||
}
|
||||
|
||||
get_ready_kdc_pod() {
|
||||
local kdc_ns="$1"
|
||||
kubectl -n "$kdc_ns" wait --for=condition=Ready pod -l "app=${PROLE_KDC_NAME}" --timeout="${KDC_POD_READY_TIMEOUT}s" >/dev/null 2>&1 || true
|
||||
kubectl -n "$kdc_ns" get pod -l "app=${PROLE_KDC_NAME}" --field-selector=status.phase=Running -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true
|
||||
}
|
||||
|
||||
wait_for_kdc_pod() {
|
||||
local kdc_ns="$1"
|
||||
local attempt pod
|
||||
attempt=1
|
||||
while [[ $attempt -le $KDC_POD_READY_RETRIES ]]; do
|
||||
pod=$(get_ready_kdc_pod "$kdc_ns")
|
||||
if [[ -n "$pod" ]]; then
|
||||
printf '%s' "$pod"
|
||||
return 0
|
||||
fi
|
||||
echo "Waiting for KDC pod '${PROLE_KDC_NAME}' to be ready... (${attempt}/${KDC_POD_READY_RETRIES})" >&2
|
||||
sleep 2
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Return 0 if pod is in CrashLoopBackOff (any container), else 1
|
||||
is_pod_crashloop() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
if [[ -z "$pod_name" ]]; then
|
||||
return 1
|
||||
fi
|
||||
local reason
|
||||
reason=$(kubectl -n "$kdc_ns" get pod "$pod_name" -o jsonpath='{range .status.containerStatuses[*]}{.state.waiting.reason}{"\n"}{end}' 2>/dev/null | tr -d '\r' | tr -s '\n' ' ' || true)
|
||||
if echo "${reason}" | grep -q "CrashLoopBackOff"; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
debug_kdc_pod() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
if [[ -z "$pod_name" ]]; then
|
||||
return 0
|
||||
fi
|
||||
echo "--- describe pod ${pod_name} ---" >&2
|
||||
kubectl -n "$kdc_ns" describe pod "$pod_name" 1>&2 || true
|
||||
echo "--- last 200 log lines from ${pod_name} ---" >&2
|
||||
kubectl -n "$kdc_ns" logs "$pod_name" --tail=200 1>&2 || true
|
||||
}
|
||||
|
||||
kdc_exec() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
shift 2
|
||||
local output=""
|
||||
if output=$(kubectl -n "$kdc_ns" exec "$pod_name" -- "$@" 2>&1); then
|
||||
printf '%s' "$output"
|
||||
return 0
|
||||
fi
|
||||
if echo "$output" | grep -qi "completed pod"; then
|
||||
return 2
|
||||
fi
|
||||
if echo "$output" | grep -qi "not found"; then
|
||||
return 2
|
||||
fi
|
||||
echo "$output" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
run_samba_join() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
local domain="$3"
|
||||
local output=""
|
||||
if output=$(kubectl -n "$kdc_ns" exec "$pod_name" -- \
|
||||
env SAMBA_ADMIN_USER="$SAMBA_ADMIN_USER" SAMBA_ADMIN_PASSWORD="$SAMBA_ADMIN_PASSWORD" \
|
||||
SAMBA_DNS_SERVER="$SAMBA_DNS_SERVER" SAMBA_REALM="${KRB5_REALM:-}" \
|
||||
/bin/sh -c 'realm_flag=""; [ -n "${SAMBA_REALM}" ] && realm_flag="--realm=${SAMBA_REALM}"; samba-tool domain join "'"$domain"'" MEMBER -U"${SAMBA_ADMIN_USER}%${SAMBA_ADMIN_PASSWORD}" --server="${SAMBA_DNS_SERVER}" ${realm_flag}' 2>&1); then
|
||||
printf '%s' "$output"
|
||||
return 0
|
||||
fi
|
||||
if echo "$output" | grep -qi "completed pod"; then
|
||||
return 2
|
||||
fi
|
||||
if echo "$output" | grep -qi "not found"; then
|
||||
return 2
|
||||
fi
|
||||
if [[ -n "$output" ]]; then
|
||||
echo "$output" >&2
|
||||
else
|
||||
echo "samba-tool produced no output." >&2
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
run_kinit() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
local output=""
|
||||
|
||||
# Prefer /etc/krb5.conf if it exists, otherwise fallback to /opt/prole-kdc/krb5.conf
|
||||
local krb5_config="/etc/krb5.conf"
|
||||
if ! kubectl -n "$kdc_ns" exec "$pod_name" -- ls /etc/krb5.conf >/dev/null 2>&1; then
|
||||
krb5_config="/opt/prole-kdc/krb5.conf"
|
||||
fi
|
||||
|
||||
echo "Running kinit for ${KRB5_USER}@${KRB5_REALM} inside ${PROLE_KDC_NAME} (${pod_name}) using ${krb5_config} ..."
|
||||
if output=$(printf '%s\n' "$KRB5_PASSWORD" | kubectl -n "$kdc_ns" exec -i "$pod_name" -- \
|
||||
env KRB5_CONFIG="$krb5_config" kinit "${KRB5_USER}@${KRB5_REALM}" 2>&1); then
|
||||
printf '%s' "$output"
|
||||
return 0
|
||||
fi
|
||||
if echo "$output" | grep -qi "completed pod"; then
|
||||
return 2
|
||||
fi
|
||||
if echo "$output" | grep -qi "not found"; then
|
||||
return 2
|
||||
fi
|
||||
if [[ -n "$output" ]]; then
|
||||
echo "$output" >&2
|
||||
else
|
||||
echo "kinit produced no output." >&2
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
check_samba_connectivity() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
if [[ -z "$SAMBA_DNS_SERVER" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Checking connectivity from ${PROLE_KDC_NAME} to ${SAMBA_DNS_SERVER} ..."
|
||||
local ports="88 389 445 464"
|
||||
local port
|
||||
for port in $ports; do
|
||||
local out=""
|
||||
out=$(kubectl -n "$kdc_ns" exec "$pod_name" -- /bin/sh -c "timeout 3 bash -c '</dev/tcp/${SAMBA_DNS_SERVER}/${port}'" 2>&1) || true
|
||||
if [[ -z "$out" ]]; then
|
||||
echo "OK: ${SAMBA_DNS_SERVER}:${port}"
|
||||
else
|
||||
echo "WARN: ${SAMBA_DNS_SERVER}:${port} unreachable: ${out}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check_kdc_direct_connectivity() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
local kdc_ip="${AD_DC_IP:-${KDC_ANSIBLE_DETECTED:-${KDC_AUTO_DETECTED:-}}}"
|
||||
if [[ -z "$kdc_ip" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Checking connectivity from ${PROLE_KDC_NAME} to KDC IP ${kdc_ip} ..."
|
||||
local ports="88 389 445 464"
|
||||
local port
|
||||
for port in $ports; do
|
||||
local out=""
|
||||
out=$(kubectl -n "$kdc_ns" exec "$pod_name" -- /bin/sh -c "timeout 3 bash -c '</dev/tcp/${kdc_ip}/${port}'" 2>&1) || true
|
||||
if [[ -z "$out" ]]; then
|
||||
echo "OK: ${kdc_ip}:${port}"
|
||||
else
|
||||
echo "WARN: ${kdc_ip}:${port} unreachable: ${out}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
openbao_url() {
|
||||
if [[ -n "${PROLE_OPENBAO_URL:-}" ]]; then
|
||||
echo "$PROLE_OPENBAO_URL"
|
||||
return 0
|
||||
fi
|
||||
if prole_is_in_cluster; then
|
||||
echo "http://openbao.${SERVICE_NAMESPACE:-${NAMESPACE:-default}}.svc.cluster.local:8200"
|
||||
return 0
|
||||
fi
|
||||
if curl -sS "http://127.0.0.1:8200/v1/sys/health" >/dev/null 2>&1; then
|
||||
echo "http://127.0.0.1:8200"
|
||||
return 0
|
||||
elif curl -sS "http://127.0.0.1:8200/v1/sys/health" >/dev/null 2>&1; then
|
||||
echo "http://127.0.0.1:8200"
|
||||
return 0
|
||||
else
|
||||
echo ""
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
openbao_token() {
|
||||
if [[ -f "$PROLE_SERVICE/secrets/openbao-root-token" ]]; then
|
||||
cat "$PROLE_SERVICE/secrets/openbao-root-token"
|
||||
else
|
||||
echo "${OPENBAO_ROOT_TOKEN:-}"
|
||||
fi
|
||||
}
|
||||
|
||||
fetch_openbao_secret() {
|
||||
local path="$1"
|
||||
local key="$2"
|
||||
local token url
|
||||
token=$(openbao_token)
|
||||
url=$(openbao_url)
|
||||
if [[ -z "$token" || -z "$url" ]]; then
|
||||
echo ""
|
||||
return 0
|
||||
fi
|
||||
curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/$path" | jq -r ".data.data.\"$key\"" || echo ""
|
||||
}
|
||||
|
||||
resolve_krb5_password() {
|
||||
if prole_secret_needs_resolution "${KRB5_PASSWORD:-}"; then
|
||||
local path="prole/${NAMESPACE:-default}/kerberos"
|
||||
local fetched
|
||||
fetched=$(fetch_openbao_secret "$path" "password")
|
||||
KRB5_PASSWORD=$(prole_secret_choose_value "${KRB5_PASSWORD:-}" "$fetched")
|
||||
fi
|
||||
}
|
||||
|
||||
resolve_samba_vars() {
|
||||
if [[ -n "${SAMBA_ADMIN_USER}" && -n "${SAMBA_ADMIN_PASSWORD}" && -n "${SAMBA_DNS_SERVER}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 1. Fallback for DNS server from prole.cfg env (AD_DC_HOST)
|
||||
if [[ -z "$SAMBA_DNS_SERVER" && -n "${AD_DC_HOST:-}" ]]; then
|
||||
SAMBA_DNS_SERVER="$AD_DC_HOST"
|
||||
echo "Using SAMBA_DNS_SERVER=${SAMBA_DNS_SERVER} from AD_DC_HOST"
|
||||
fi
|
||||
|
||||
# 2. Try to resolve from Ansible inventory if possible
|
||||
local root
|
||||
if [[ -n "${PROLE_HOME:-}" && -d "${PROLE_HOME}" ]]; then
|
||||
root="${PROLE_HOME}"
|
||||
else
|
||||
root="${SCRIPT_DIR}/.."
|
||||
fi
|
||||
|
||||
local vars_file="${root}/infrastructure/inventory/group_vars/ad_dc/vars.yml"
|
||||
if [[ -f "$vars_file" ]]; then
|
||||
if [[ -z "$SAMBA_DNS_SERVER" ]]; then
|
||||
SAMBA_DNS_SERVER=$(prole_yaml_get_scalar "$vars_file" "samba_dns_server")
|
||||
fi
|
||||
if [[ -z "$SAMBA_ADMIN_USER" ]]; then
|
||||
SAMBA_ADMIN_USER=$(prole_yaml_get_scalar "$vars_file" "samba_dns_admin_user")
|
||||
fi
|
||||
fi
|
||||
|
||||
# 3. Fallback for Admin User
|
||||
if [[ -z "$SAMBA_ADMIN_USER" ]]; then
|
||||
if [[ -n "${AD_DC_USER:-}" ]]; then
|
||||
SAMBA_ADMIN_USER="$AD_DC_USER"
|
||||
echo "Using SAMBA_ADMIN_USER=${SAMBA_ADMIN_USER} from AD_DC_USER"
|
||||
else
|
||||
SAMBA_ADMIN_USER="administrator"
|
||||
echo "Defaulting SAMBA_ADMIN_USER to administrator"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 4. Try to resolve password from Ansible Vault
|
||||
if [[ -z "$SAMBA_ADMIN_PASSWORD" ]]; then
|
||||
local vault_file="${root}/infrastructure/inventory/group_vars/ad_dc/vault.yml"
|
||||
local vault_pass_file=""
|
||||
if [[ -n "${ANSIBLE_VAULT_PASSWORD_FILE:-}" && -f "${ANSIBLE_VAULT_PASSWORD_FILE}" ]]; then
|
||||
vault_pass_file="${ANSIBLE_VAULT_PASSWORD_FILE}"
|
||||
elif [[ -n "${PROLE_HOME:-}" && -f "${PROLE_HOME}/.vault_pass" ]]; then
|
||||
vault_pass_file="${PROLE_HOME}/.vault_pass"
|
||||
elif [[ -f "${root}/.vault_pass" ]]; then
|
||||
vault_pass_file="${root}/.vault_pass"
|
||||
fi
|
||||
|
||||
if [[ -f "$vault_file" && -n "$vault_pass_file" && -x "$(command -v ansible-vault)" ]]; then
|
||||
local vault_out
|
||||
vault_out=$(ansible-vault view "$vault_file" --vault-password-file "$vault_pass_file" 2>/dev/null || true)
|
||||
if [[ -n "$vault_out" ]]; then
|
||||
SAMBA_ADMIN_PASSWORD=$(printf '%s\n' "$vault_out" | awk -F: '/^[[:space:]]*vault_samba_dns_admin_pass[[:space:]]*:/ {sub(/^[^:]+:[[:space:]]*/, "", $0); gsub(/"/, "", $0); print $0; exit}')
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# 5. Fallback for Password from OpenBao
|
||||
if [[ -z "$SAMBA_ADMIN_PASSWORD" ]]; then
|
||||
local path="prole/${NAMESPACE:-default}/ad_dc"
|
||||
local fetched
|
||||
fetched=$(fetch_openbao_secret "$path" "password")
|
||||
if [[ -n "$fetched" && "$fetched" != "null" ]]; then
|
||||
SAMBA_ADMIN_PASSWORD="$fetched"
|
||||
echo "Fetched SAMBA_ADMIN_PASSWORD from OpenBao (${path})"
|
||||
else
|
||||
# Try kerberos path as fallback
|
||||
path="prole/${NAMESPACE:-default}/kerberos"
|
||||
fetched=$(fetch_openbao_secret "$path" "samba_password")
|
||||
if [[ -n "$fetched" && "$fetched" != "null" ]]; then
|
||||
SAMBA_ADMIN_PASSWORD="$fetched"
|
||||
echo "Fetched SAMBA_ADMIN_PASSWORD from OpenBao (${path}#samba_password)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
join_samba_realm_if_needed() {
|
||||
local kdc_ns="$1"
|
||||
local pod_name="$2"
|
||||
local domain=""
|
||||
|
||||
resolve_samba_vars
|
||||
|
||||
if [[ -z "$SAMBA_ADMIN_USER" || -z "$SAMBA_ADMIN_PASSWORD" || -z "$SAMBA_DNS_SERVER" ]]; then
|
||||
echo "WARN: Missing Samba join info; skipping samba-tool realm join."
|
||||
return 0
|
||||
fi
|
||||
|
||||
check_samba_connectivity "$kdc_ns" "$pod_name"
|
||||
|
||||
if [[ -n "$KRB5_REALM" ]]; then
|
||||
domain=$(printf '%s' "$KRB5_REALM" | tr '[:upper:]' '[:lower:]')
|
||||
fi
|
||||
if [[ -z "$domain" ]]; then
|
||||
domain="$SAMBA_DNS_SERVER"
|
||||
fi
|
||||
|
||||
if kubectl -n "$kdc_ns" exec "$pod_name" -- test -f /var/lib/samba/private/secrets.tdb >/dev/null 2>&1; then
|
||||
echo "Samba already joined; skipping join."
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Joining Samba realm '${domain}' (server ${SAMBA_DNS_SERVER}) ..."
|
||||
local attempt=1
|
||||
while true; do
|
||||
if run_samba_join "$kdc_ns" "$pod_name" "$domain"; then
|
||||
return 0
|
||||
fi
|
||||
if [[ $? -eq 2 ]]; then
|
||||
if [[ $attempt -ge $KDC_POD_READY_RETRIES ]]; then
|
||||
echo "WARN: KDC pod completed before join could run; skipping samba-tool join." >&2
|
||||
return 0
|
||||
fi
|
||||
pod_name=$(wait_for_kdc_pod "$kdc_ns" || true)
|
||||
if [[ -z "$pod_name" ]]; then
|
||||
echo "WARN: KDC pod unavailable for samba-tool join." >&2
|
||||
return 0
|
||||
fi
|
||||
attempt=$((attempt + 1))
|
||||
continue
|
||||
fi
|
||||
echo "WARN: samba-tool domain join failed; continuing to Kerberos test." >&2
|
||||
return 0
|
||||
done
|
||||
}
|
||||
|
||||
run_test() {
|
||||
ensure_tools
|
||||
ensure_namespace
|
||||
resolve_krb5_password
|
||||
|
||||
# Support both names for the toggle from prole.cfg
|
||||
local enabled="${KERBEROS_ENABLED:-${ENABLED:-false}}"
|
||||
if [[ "$enabled" == "false" || "$enabled" == "0" || "$enabled" == "False" ]]; then
|
||||
echo "Kerberos is disabled (KERBEROS_ENABLED=$enabled). Skipping test."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ -z "$KRB5_REALM" || -z "$KRB5_USER" || -z "$KRB5_PASSWORD" || -z "$KRB5_KDC" ]]; then
|
||||
echo "ERROR: Missing Kerberos configuration. Ensure KRB5_REALM, KRB5_KDC, KRB5_USER, KRB5_PASSWORD are set." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Quick pre-check: if an existing 'auth' deployment is present but not Available, remove it
|
||||
# to avoid starting a rollout that is likely to time out on a stale/broken replica set.
|
||||
local kdc_ns
|
||||
kdc_ns="${SERVICE_NAMESPACE:-${NAMESPACE:-default}}"
|
||||
if kubectl -n "$kdc_ns" get deploy "$PROLE_KDC_NAME" >/dev/null 2>&1; then
|
||||
# Try a fast availability wait; if it fails, treat as unhealthy and clean up before proceeding.
|
||||
if ! kubectl -n "$kdc_ns" wait --for=condition=Available deploy/"$PROLE_KDC_NAME" --timeout="${PROLE_KDC_PRECHECK_TIMEOUT}s" >/dev/null 2>&1; then
|
||||
echo "Detected unhealthy '$PROLE_KDC_NAME' deployment in namespace '$kdc_ns'; removing before Kerberos test rollout to avoid timeout..." >&2
|
||||
if [[ -x "$SCRIPT_DIR/init_kdc.sh" ]]; then
|
||||
SERVICE_NAMESPACE="$SERVICE_NAMESPACE" "$SCRIPT_DIR/init_kdc.sh" cleanup || true
|
||||
else
|
||||
kubectl -n "$kdc_ns" delete deploy "$PROLE_KDC_NAME" --ignore-not-found || true
|
||||
kubectl -n "$kdc_ns" delete svc "$PROLE_KDC_SERVICE" --ignore-not-found || true
|
||||
kubectl -n "$kdc_ns" delete configmap prole-kdc-config --ignore-not-found || true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -x "$SCRIPT_DIR/init_kdc.sh" ]]; then
|
||||
SERVICE_NAMESPACE="$SERVICE_NAMESPACE" KRB5_REALM="$KRB5_REALM" KRB5_KDC="$KRB5_KDC" \
|
||||
KRB5_ADMIN="$KRB5_KDC" KRB5_USER="$KRB5_USER" KRB5_PASSWORD="$KRB5_PASSWORD" \
|
||||
"$SCRIPT_DIR/init_kdc.sh" update || true
|
||||
fi
|
||||
|
||||
local pod_name
|
||||
pod_name=$(wait_for_kdc_pod "$kdc_ns" || true)
|
||||
if [[ -z "$pod_name" ]]; then
|
||||
echo "ERROR: KDC pod '${PROLE_KDC_NAME}' not found in namespace '$kdc_ns'. Run init_kdc.sh update first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If the pod is crashlooping, dump logs and fail fast
|
||||
if is_pod_crashloop "$kdc_ns" "$pod_name"; then
|
||||
echo "ERROR: KDC pod '${pod_name}' is in CrashLoopBackOff. Dumping diagnostics..." >&2
|
||||
debug_kdc_pod "$kdc_ns" "$pod_name"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
write_krb5_conf_to_pod "$kdc_ns" "$pod_name"
|
||||
|
||||
check_kdc_direct_connectivity "$kdc_ns" "$pod_name"
|
||||
|
||||
join_samba_realm_if_needed "$kdc_ns" "$pod_name"
|
||||
|
||||
echo "Running kinit for ${KRB5_USER}@${KRB5_REALM} inside ${PROLE_KDC_NAME} (${pod_name}) ..."
|
||||
local attempt=1
|
||||
while true; do
|
||||
if run_kinit "$kdc_ns" "$pod_name"; then
|
||||
break
|
||||
fi
|
||||
if [[ $? -eq 2 ]] || kubectl -n "$kdc_ns" get pod "$pod_name" -o jsonpath='{.status.phase}' 2>/dev/null | grep -qi "Succeeded"; then
|
||||
if [[ $attempt -ge $KDC_POD_READY_RETRIES ]]; then
|
||||
echo "ERROR: KDC pod completed before kinit could run." >&2
|
||||
exit 1
|
||||
fi
|
||||
pod_name=$(wait_for_kdc_pod "$kdc_ns" || true)
|
||||
if [[ -z "$pod_name" ]]; then
|
||||
echo "ERROR: KDC pod unavailable for kinit." >&2
|
||||
exit 1
|
||||
fi
|
||||
attempt=$((attempt + 1))
|
||||
continue
|
||||
fi
|
||||
# If the pod is crashlooping, show logs to aid troubleshooting
|
||||
if is_pod_crashloop "$kdc_ns" "$pod_name"; then
|
||||
echo "ERROR: KDC pod '${pod_name}' entered CrashLoopBackOff during kinit. Dumping diagnostics..." >&2
|
||||
debug_kdc_pod "$kdc_ns" "$pod_name"
|
||||
fi
|
||||
echo "ERROR: kinit failed for ${KRB5_USER}@${KRB5_REALM}." >&2
|
||||
exit 1
|
||||
done
|
||||
|
||||
echo "Kerberos ticket cache:"
|
||||
# Determine krb5 config path in the pod similar to run_kinit()
|
||||
local krb5_config_in_pod="/etc/krb5.conf"
|
||||
if ! kubectl -n "$kdc_ns" exec "$pod_name" -- ls /etc/krb5.conf >/dev/null 2>&1; then
|
||||
krb5_config_in_pod="/opt/prole-kdc/krb5.conf"
|
||||
fi
|
||||
kubectl -n "$kdc_ns" exec "$pod_name" -- env KRB5_CONFIG="$krb5_config_in_pod" klist || true
|
||||
}
|
||||
|
||||
case "$ACTION" in
|
||||
test)
|
||||
run_test
|
||||
;;
|
||||
cleanup)
|
||||
echo "No test pods to cleanup (KDC-based test)."
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {test|cleanup}" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
@ -7,16 +7,18 @@ set -euo pipefail
|
||||
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
PROLE_HOME=$(cd "$SCRIPT_DIR/../.." && pwd)
|
||||
SOURCE_ETC_DIR="$PROLE_HOME/etc"
|
||||
SOURCE_LIB_SHELL_DIR="$PROLE_HOME/lib/shell"
|
||||
|
||||
TMP_DIR=$(mktemp -d)
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
WORK_DIR="$TMP_DIR/work"
|
||||
BIN_DIR="$TMP_DIR/bin"
|
||||
mkdir -p "$WORK_DIR/etc" "$WORK_DIR/conf" "$WORK_DIR/k8s/prole" "$BIN_DIR"
|
||||
mkdir -p "$WORK_DIR/etc" "$WORK_DIR/conf" "$WORK_DIR/k8s/prole" "$WORK_DIR/lib/shell" "$BIN_DIR"
|
||||
|
||||
cp "$SOURCE_ETC_DIR/init_garage_store.sh" "$WORK_DIR/etc/init_garage_store.sh"
|
||||
cp "$SOURCE_ETC_DIR/common_core_lib.sh" "$WORK_DIR/etc/common_core_lib.sh"
|
||||
cp "$SOURCE_LIB_SHELL_DIR/common_core_lib.sh" "$WORK_DIR/lib/shell/common_core_lib.sh"
|
||||
cp "$SOURCE_ETC_DIR/prole_cfg.sh" "$WORK_DIR/etc/prole_cfg.sh"
|
||||
chmod +x "$WORK_DIR/etc/init_garage_store.sh"
|
||||
|
||||
|
||||
@ -7,16 +7,18 @@ set -euo pipefail
|
||||
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
PROLE_HOME=$(cd "$SCRIPT_DIR/../.." && pwd)
|
||||
SOURCE_ETC_DIR="$PROLE_HOME/etc"
|
||||
SOURCE_LIB_SHELL_DIR="$PROLE_HOME/lib/shell"
|
||||
|
||||
TMP_DIR=$(mktemp -d)
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
WORK_DIR="$TMP_DIR/work"
|
||||
BIN_DIR="$TMP_DIR/bin"
|
||||
mkdir -p "$WORK_DIR/etc" "$WORK_DIR/conf" "$BIN_DIR"
|
||||
mkdir -p "$WORK_DIR/etc" "$WORK_DIR/conf" "$WORK_DIR/lib/shell" "$BIN_DIR"
|
||||
|
||||
cp "$SOURCE_ETC_DIR/init_kong.sh" "$WORK_DIR/etc/init_kong.sh"
|
||||
cp "$SOURCE_ETC_DIR/common_core_lib.sh" "$WORK_DIR/etc/common_core_lib.sh"
|
||||
cp "$SOURCE_LIB_SHELL_DIR/common_core_lib.sh" "$WORK_DIR/lib/shell/common_core_lib.sh"
|
||||
cp "$SOURCE_ETC_DIR/prole_cfg.sh" "$WORK_DIR/etc/prole_cfg.sh"
|
||||
chmod +x "$WORK_DIR/etc/init_kong.sh"
|
||||
|
||||
|
||||
@ -7,16 +7,18 @@ set -euo pipefail
|
||||
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
PROLE_HOME=$(cd "$SCRIPT_DIR/../.." && pwd)
|
||||
SOURCE_ETC_DIR="$PROLE_HOME/etc"
|
||||
SOURCE_LIB_SHELL_DIR="$PROLE_HOME/lib/shell"
|
||||
|
||||
TMP_DIR=$(mktemp -d)
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
WORK_DIR="$TMP_DIR/work"
|
||||
BIN_DIR="$TMP_DIR/bin"
|
||||
mkdir -p "$WORK_DIR/etc" "$WORK_DIR/conf" "$BIN_DIR"
|
||||
mkdir -p "$WORK_DIR/etc" "$WORK_DIR/conf" "$WORK_DIR/lib/shell" "$BIN_DIR"
|
||||
|
||||
cp "$SOURCE_ETC_DIR/init_openbao.sh" "$WORK_DIR/etc/init_openbao.sh"
|
||||
cp "$SOURCE_ETC_DIR/common_core_lib.sh" "$WORK_DIR/etc/common_core_lib.sh"
|
||||
cp "$SOURCE_LIB_SHELL_DIR/common_core_lib.sh" "$WORK_DIR/lib/shell/common_core_lib.sh"
|
||||
cp "$SOURCE_ETC_DIR/prole_cfg.sh" "$WORK_DIR/etc/prole_cfg.sh"
|
||||
chmod +x "$WORK_DIR/etc/init_openbao.sh"
|
||||
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
version: 2
|
||||
jobs:
|
||||
lint:
|
||||
docker:
|
||||
- image: koalaman/shellcheck-alpine:v0.7.1
|
||||
steps:
|
||||
- checkout
|
||||
- run: shellcheck shellspec $(find lib libexec spec examples -name '*.sh')
|
||||
test:
|
||||
working_directory: ~/shellspec
|
||||
docker:
|
||||
- image: alpine
|
||||
steps:
|
||||
- run: apk add --no-progress --no-cache ca-certificates
|
||||
- checkout
|
||||
- run: ./shellspec --task fixture:stat:prepare
|
||||
- run: ./shellspec -o tap -o junit
|
||||
- run:
|
||||
command: |
|
||||
mkdir -p ~/report/shellspec
|
||||
cp report/results_junit.xml ~/report/shellspec/
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: ~/report
|
||||
- store_artifacts:
|
||||
path: report
|
||||
coverage:
|
||||
working_directory: ~/shellspec
|
||||
docker:
|
||||
- image: shellspec/kcov
|
||||
steps:
|
||||
- checkout
|
||||
- run: ./shellspec --task fixture:stat:prepare
|
||||
- run: ./shellspec --kcov
|
||||
- store_artifacts:
|
||||
path: coverage
|
||||
workflows:
|
||||
version: 2
|
||||
lint_test_and_coverage:
|
||||
jobs:
|
||||
- lint
|
||||
- test
|
||||
- coverage:
|
||||
requires:
|
||||
- lint
|
||||
- test
|
||||
daily_update_schedule:
|
||||
jobs:
|
||||
- lint
|
||||
- coverage:
|
||||
requires:
|
||||
- lint
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "0 0 * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
80
tests/shellspec/.vendor/shellspec-0.28.1/.cirrus.yml
Normal file
80
tests/shellspec/.vendor/shellspec-0.28.1/.cirrus.yml
Normal file
@ -0,0 +1,80 @@
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
||||
freebsd_task:
|
||||
freebsd_instance:
|
||||
matrix:
|
||||
- image: freebsd-10-4-release-amd64
|
||||
- image_family: freebsd-11-4
|
||||
- image_family: freebsd-12-2
|
||||
# - image_family: freebsd-13-0-snap
|
||||
install_script: pkg install -y dash bash zsh ksh93 mksh oksh
|
||||
prepare_script:
|
||||
- ./shellspec --task fixture:stat:prepare
|
||||
script:
|
||||
- contrib/all.sh contrib/various_test.sh
|
||||
|
||||
# gitbash_task:
|
||||
# timeout_in: 120m
|
||||
# windows_container:
|
||||
# image: cirrusci/windowsservercore:2019
|
||||
# os_version: 2019
|
||||
# env:
|
||||
# PATH: $ProgramFiles\Git\bin;$PATH
|
||||
# install_script:
|
||||
# - git --version
|
||||
# prepare_script:
|
||||
# - bash -c "env | grep -E '^(LC_|LANG|CYGWIN|MSYS)'"
|
||||
# - bash -c "mount"
|
||||
# - bash -c "./shellspec --task fixture:stat:prepare"
|
||||
# script:
|
||||
# - bash -c "contrib/all.sh shellspec"
|
||||
|
||||
# msys_task:
|
||||
# timeout_in: 120m
|
||||
# windows_container:
|
||||
# image: cirrusci/windowsservercore:2019
|
||||
# os_version: 2019
|
||||
# env:
|
||||
# PATH: C:\tools\msys64\usr\bin;$PATH
|
||||
# install_script:
|
||||
# - choco install -y --no-progress msys2
|
||||
# - pacman.exe -Syu --noprogressbar --noconfirm
|
||||
# - pacman.exe -S --noprogressbar --noconfirm dash bash busybox mksh zsh
|
||||
# - pacman.exe -Q
|
||||
# prepare_script:
|
||||
# - bash -c "env | grep -E '^(LC_|LANG|CYGWIN|MSYS)'"
|
||||
# - bash -c "mount"
|
||||
# - bash -c "./shellspec --task fixture:stat:prepare"
|
||||
# script:
|
||||
# - bash -c "contrib/all.sh shellspec"
|
||||
|
||||
# cygwin_task:
|
||||
# timeout_in: 120m
|
||||
# windows_container:
|
||||
# image: cirrusci/windowsservercore:2019
|
||||
# os_version: 2019
|
||||
# env:
|
||||
# PATH: C:\tools\cygwin\bin;$PATH
|
||||
# install_script:
|
||||
# - choco install -y --no-progress cygwin cyg-get
|
||||
# - cyg-get nc dash bash busybox mksh posh zsh
|
||||
# - cygcheck -c
|
||||
# prepare_script:
|
||||
# - bash -c "env | grep -E '^(LC_|LANG|CYGWIN|MSYS)'"
|
||||
# - bash -c "mount"
|
||||
# - bash -c "./shellspec --task fixture:stat:prepare"
|
||||
# # I don't know why but tests using below files fail in cirrus ci environment.
|
||||
# - bash -c "rm -f ./spec/fixture/stat/{readable,writable}"
|
||||
# script:
|
||||
# - bash -c 'contrib/all.sh shellspec'
|
||||
|
||||
# busybox_task:
|
||||
# timeout_in: 120m
|
||||
# windows_container:
|
||||
# image: cirrusci/windowsservercore:2019
|
||||
# os_version: 2019
|
||||
# install_script:
|
||||
# - choco install -y --no-progress busybox
|
||||
# script:
|
||||
# - busybox ash -c "contrib/all.sh shellspec"
|
||||
6
tests/shellspec/.vendor/shellspec-0.28.1/.codecov.yml
Normal file
6
tests/shellspec/.vendor/shellspec-0.28.1/.codecov.yml
Normal file
@ -0,0 +1,6 @@
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
target: 30%
|
||||
patch: false
|
||||
@ -0,0 +1,82 @@
|
||||
# Build two images with Automated Builds using Docker Hub hooks.
|
||||
# See https://github.com/shellspec/shellspec/tree/master/.dockerhub/hooks
|
||||
|
||||
# ======================================================================
|
||||
# source code
|
||||
# ======================================================================
|
||||
FROM scratch as source
|
||||
COPY shellspec LICENSE /opt/shellspec/
|
||||
COPY lib /opt/shellspec/lib
|
||||
COPY libexec /opt/shellspec/libexec
|
||||
|
||||
# ======================================================================
|
||||
# Kcov builder
|
||||
# ======================================================================
|
||||
FROM alpine:3.12 as builder
|
||||
ENV KCOV=v38 CXXFLAGS=-D__ptrace_request=int
|
||||
WORKDIR /usr/local/src
|
||||
RUN apk add --no-cache build-base cmake ninja python3 \
|
||||
binutils-dev curl-dev elfutils-dev
|
||||
RUN wget -q https://github.com/SimonKagstrom/kcov/archive/$KCOV.tar.gz
|
||||
RUN tar xzf $KCOV.tar.gz -C ./ --strip-components 1
|
||||
RUN mkdir build && cd build \
|
||||
&& cmake -G Ninja .. && cmake --build . --target install
|
||||
|
||||
# ======================================================================
|
||||
# Kcov image
|
||||
# TAG: shellspec:kcov, shellspec:[VERSION]-kcov
|
||||
# ======================================================================
|
||||
FROM alpine:3.12 as kcov
|
||||
RUN apk add --no-cache bash binutils-dev curl-dev elfutils-libelf
|
||||
COPY --from=builder /usr/local/bin/kcov* /usr/local/bin/
|
||||
COPY --from=builder /usr/local/share/doc/kcov /usr/local/share/doc/kcov
|
||||
COPY --from=source /opt/shellspec /opt/shellspec
|
||||
COPY .dockerhub/shellspec-docker-entrypoint.sh /shellspec-docker
|
||||
ENV PATH /opt/shellspec/:$PATH
|
||||
WORKDIR /src
|
||||
ENTRYPOINT [ "shellspec" ]
|
||||
ARG CREATED
|
||||
ARG AUTHORS
|
||||
ARG VERSION
|
||||
ARG REVISION
|
||||
ARG REFNAME
|
||||
LABEL org.opencontainers.image.created=$CREATED \
|
||||
org.opencontainers.image.authors=$AUTHORS \
|
||||
org.opencontainers.image.url="https://shellspec.info/" \
|
||||
org.opencontainers.image.documentation="https://github.com/shellspec/shellspec" \
|
||||
org.opencontainers.image.source="https://github.com/shellspec/shellspec.git" \
|
||||
org.opencontainers.image.version=$VERSION \
|
||||
org.opencontainers.image.revision=$REVISION \
|
||||
org.opencontainers.image.vendor="shellspec" \
|
||||
org.opencontainers.image.licenses="MIT" \
|
||||
org.opencontainers.image.ref.name=$REFNAME \
|
||||
org.opencontainers.image.title="shellspec+kcov" \
|
||||
org.opencontainers.image.description="Shellspec (Alpine based with Kcov)"
|
||||
|
||||
# ======================================================================
|
||||
# Standard image (default)
|
||||
# TAG: shellspec:latest, shellspec:[VERSION]
|
||||
# ======================================================================
|
||||
FROM alpine:3.12 as standard
|
||||
COPY --from=source /opt/shellspec /opt/shellspec
|
||||
COPY .dockerhub/shellspec-docker-entrypoint.sh /shellspec-docker
|
||||
ENV PATH /opt/shellspec/:$PATH
|
||||
WORKDIR /src
|
||||
ENTRYPOINT [ "shellspec" ]
|
||||
ARG CREATED
|
||||
ARG AUTHORS
|
||||
ARG VERSION
|
||||
ARG REVISION
|
||||
ARG REFNAME
|
||||
LABEL org.opencontainers.image.created=$CREATED \
|
||||
org.opencontainers.image.authors=$AUTHORS \
|
||||
org.opencontainers.image.url="https://shellspec.info/" \
|
||||
org.opencontainers.image.documentation="https://github.com/shellspec/shellspec" \
|
||||
org.opencontainers.image.source="https://github.com/shellspec/shellspec.git" \
|
||||
org.opencontainers.image.version=$VERSION \
|
||||
org.opencontainers.image.revision=$REVISION \
|
||||
org.opencontainers.image.vendor="shellspec" \
|
||||
org.opencontainers.image.licenses="MIT" \
|
||||
org.opencontainers.image.ref.name=$REFNAME \
|
||||
org.opencontainers.image.title="shellspec" \
|
||||
org.opencontainers.image.description="Shellspec (Alpine based)"
|
||||
@ -0,0 +1,85 @@
|
||||
# Build two images with Automated Builds using Docker Hub hooks.
|
||||
# See https://github.com/shellspec/shellspec/tree/master/.dockerhub/hooks
|
||||
|
||||
# ======================================================================
|
||||
# source code
|
||||
# ======================================================================
|
||||
FROM scratch as source
|
||||
COPY shellspec LICENSE /opt/shellspec/
|
||||
COPY lib /opt/shellspec/lib
|
||||
COPY libexec /opt/shellspec/libexec
|
||||
|
||||
# ======================================================================
|
||||
# Kcov builder
|
||||
# ======================================================================
|
||||
FROM debian:10 AS builder
|
||||
ENV KCOV=v38 DEBIAN_FRONTEND=noninteractive DEBCONF_NOWARNINGS=yes
|
||||
WORKDIR /usr/local/src
|
||||
RUN apt-get update && apt-get install -y \
|
||||
build-essential cmake ninja-build python3 wget \
|
||||
binutils-dev libcurl4-openssl-dev zlib1g-dev libdw-dev libiberty-dev
|
||||
RUN wget -q https://github.com/SimonKagstrom/kcov/archive/$KCOV.tar.gz
|
||||
RUN tar xzf $KCOV.tar.gz -C ./ --strip-components 1
|
||||
RUN mkdir build && cd build \
|
||||
&& cmake -G Ninja .. && cmake --build . --target install
|
||||
|
||||
# ======================================================================
|
||||
# Kcov image
|
||||
# TAG: shellspec-debian:kcov, shellspec-debian:[VERSION]-kcov
|
||||
# ======================================================================
|
||||
FROM debian:10 as kcov
|
||||
RUN export DEBIAN_FRONTEND=noninteractive DEBCONF_NOWARNINGS=yes \
|
||||
&& apt-get update && apt-get install -y binutils libcurl4 zlib1g libdw1 \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
COPY --from=builder /usr/local/bin/kcov* /usr/local/bin/
|
||||
COPY --from=builder /usr/local/share/doc/kcov /usr/local/share/doc/kcov
|
||||
COPY --from=source /opt/shellspec /opt/shellspec
|
||||
COPY .dockerhub/shellspec-docker-entrypoint.sh /shellspec-docker
|
||||
ENV PATH /opt/shellspec/:$PATH
|
||||
WORKDIR /src
|
||||
ENTRYPOINT [ "shellspec" ]
|
||||
ARG CREATED
|
||||
ARG AUTHORS
|
||||
ARG VERSION
|
||||
ARG REVISION
|
||||
ARG REFNAME
|
||||
LABEL org.opencontainers.image.created=$CREATED \
|
||||
org.opencontainers.image.authors=$AUTHORS \
|
||||
org.opencontainers.image.url="https://shellspec.info/" \
|
||||
org.opencontainers.image.documentation="https://github.com/shellspec/shellspec" \
|
||||
org.opencontainers.image.source="https://github.com/shellspec/shellspec.git" \
|
||||
org.opencontainers.image.version=$VERSION \
|
||||
org.opencontainers.image.revision=$REVISION \
|
||||
org.opencontainers.image.vendor="shellspec" \
|
||||
org.opencontainers.image.licenses="MIT" \
|
||||
org.opencontainers.image.ref.name=$REFNAME \
|
||||
org.opencontainers.image.title="shellspec-debian+kcov" \
|
||||
org.opencontainers.image.description="Shellspec (Debian based with Kcov)"
|
||||
|
||||
# ======================================================================
|
||||
# Standard image (default)
|
||||
# TAG: shellspec-debian:latest, shellspec-debian:[VERSION]
|
||||
# ======================================================================
|
||||
FROM debian:10 as standard
|
||||
COPY --from=source /opt/shellspec /opt/shellspec
|
||||
COPY .dockerhub/shellspec-docker-entrypoint.sh /shellspec-docker
|
||||
ENV PATH /opt/shellspec/:$PATH
|
||||
WORKDIR /src
|
||||
ENTRYPOINT [ "shellspec" ]
|
||||
ARG CREATED
|
||||
ARG AUTHORS
|
||||
ARG VERSION
|
||||
ARG REVISION
|
||||
ARG REFNAME
|
||||
LABEL org.opencontainers.image.created=$CREATED \
|
||||
org.opencontainers.image.authors=$AUTHORS \
|
||||
org.opencontainers.image.url="https://shellspec.info/" \
|
||||
org.opencontainers.image.documentation="https://github.com/shellspec/shellspec" \
|
||||
org.opencontainers.image.source="https://github.com/shellspec/shellspec.git" \
|
||||
org.opencontainers.image.version=$VERSION \
|
||||
org.opencontainers.image.revision=$REVISION \
|
||||
org.opencontainers.image.vendor="shellspec" \
|
||||
org.opencontainers.image.licenses="MIT" \
|
||||
org.opencontainers.image.ref.name=$REFNAME \
|
||||
org.opencontainers.image.title="shellspec-debian" \
|
||||
org.opencontainers.image.description="Shellspec (Debian based)"
|
||||
@ -0,0 +1,44 @@
|
||||
# ======================================================================
|
||||
# source code
|
||||
# ======================================================================
|
||||
FROM scratch as source
|
||||
COPY shellspec LICENSE /opt/shellspec/
|
||||
COPY lib /opt/shellspec/lib
|
||||
COPY libexec /opt/shellspec/libexec
|
||||
|
||||
# ======================================================================
|
||||
# Fake kcov target to pass the test
|
||||
# ======================================================================
|
||||
FROM busybox as kcov
|
||||
RUN echo "#!/bin/true" > /bin/sh
|
||||
|
||||
# ======================================================================
|
||||
# Use standard target to test source code
|
||||
# ======================================================================
|
||||
FROM alpine as standard
|
||||
ENV PATH /opt/shellspec/:$PATH
|
||||
COPY --from=source /opt/shellspec /opt/shellspec
|
||||
|
||||
# ======================================================================
|
||||
# Source image (default)
|
||||
# TAG: shellspec-scratch:latest, shellspec-scratch:[VERSION]
|
||||
# ======================================================================
|
||||
FROM scratch
|
||||
COPY --from=source /opt/shellspec /opt/shellspec
|
||||
ARG CREATED
|
||||
ARG AUTHORS
|
||||
ARG VERSION
|
||||
ARG REVISION
|
||||
ARG REFNAME
|
||||
LABEL org.opencontainers.image.created=$CREATED \
|
||||
org.opencontainers.image.authors=$AUTHORS \
|
||||
org.opencontainers.image.url="https://shellspec.info/" \
|
||||
org.opencontainers.image.documentation="https://github.com/shellspec/shellspec" \
|
||||
org.opencontainers.image.source="https://github.com/shellspec/shellspec.git" \
|
||||
org.opencontainers.image.version=$VERSION \
|
||||
org.opencontainers.image.revision=$REVISION \
|
||||
org.opencontainers.image.vendor="shellspec" \
|
||||
org.opencontainers.image.licenses="MIT" \
|
||||
org.opencontainers.image.ref.name=$REFNAME \
|
||||
org.opencontainers.image.title="shellspec-scratch" \
|
||||
org.opencontainers.image.description="Shellspec (Scratch based)"
|
||||
@ -0,0 +1,55 @@
|
||||
# ShellSpec docker images
|
||||
|
||||
[ShellSpec](https://shellspec.info/) is a full-featured BDD unit testing framework for shell scripts.
|
||||
|
||||
These docker images are for running ShellSpec easily and suitable for incorporating into CI.
|
||||
|
||||
The tag with `kcov` means [Kcov](https://github.com/SimonKagstrom/kcov) is included. The tag `latest` is latest release version.
|
||||
|
||||
## Alpine based
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
https://hub.docker.com/r/shellspec/shellspec
|
||||
|
||||
Tags:
|
||||
|
||||
- shellspec/shellspec:latest
|
||||
- shellspec/shellspec:kcov
|
||||
- shellspec/shellspec:master
|
||||
- shellspec/shellspec:master-kcov
|
||||
- shellspec/shellspec:[VERSION]
|
||||
- shellspec/shellspec:[VERSION]-kcov
|
||||
|
||||
## Debian based
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
https://hub.docker.com/r/shellspec/shellspec-debian
|
||||
|
||||
Tags:
|
||||
|
||||
- shellspec/shellspec-debian:latest
|
||||
- shellspec/shellspec-debian:kcov
|
||||
- shellspec/shellspec-debian:master
|
||||
- shellspec/shellspec-debian:master-kcov
|
||||
- shellspec/shellspec-debian:[VERSION]
|
||||
- shellspec/shellspec-debian:[VERSION]-kcov
|
||||
|
||||
## Scratch based
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
https://hub.docker.com/r/shellspec/shellspec-scratch
|
||||
|
||||
Tags:
|
||||
|
||||
- shellspec/shellspec-scratch:latest
|
||||
- shellspec/shellspec-scratch:master
|
||||
- shellspec/shellspec-scratch:[VERSION]
|
||||
@ -0,0 +1,14 @@
|
||||
version: "3.4"
|
||||
services:
|
||||
sut:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: ${DOCKERFILE_BASE:-}${DOCKERFILE_PATH:-Dockerfile}
|
||||
target: kcov
|
||||
entrypoint: /bin/sh -eux -c
|
||||
command:
|
||||
- |
|
||||
shellspec --version
|
||||
shellspec --init spec
|
||||
shellspec -f tap
|
||||
kcov --version
|
||||
@ -0,0 +1,13 @@
|
||||
version: "3.4"
|
||||
services:
|
||||
sut:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: ${DOCKERFILE_BASE:-}${DOCKERFILE_PATH:-Dockerfile}
|
||||
target: standard
|
||||
entrypoint: /bin/sh -eux -c
|
||||
command:
|
||||
- |
|
||||
shellspec --version
|
||||
shellspec --init spec
|
||||
shellspec -f tap
|
||||
12
tests/shellspec/.vendor/shellspec-0.28.1/.dockerhub/hooks/build
Executable file
12
tests/shellspec/.vendor/shellspec-0.28.1/.dockerhub/hooks/build
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
CREATED=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
VERSION=$(../shellspec --version)
|
||||
REVISION=$(echo "$SOURCE_COMMIT" | cut -c-10)
|
||||
|
||||
docker build "$@" -f "$DOCKERFILE_PATH" -t "$IMAGE_NAME" .. \
|
||||
--build-arg CREATED="$CREATED" \
|
||||
--build-arg AUTHORS="$AUTHORS" \
|
||||
--build-arg VERSION="$VERSION" \
|
||||
--build-arg REVISION="$REVISION" \
|
||||
--build-arg REFNAME="$DOCKER_TAG"
|
||||
17
tests/shellspec/.vendor/shellspec-0.28.1/.dockerhub/hooks/post_build
Executable file
17
tests/shellspec/.vendor/shellspec-0.28.1/.dockerhub/hooks/post_build
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
# IMAGE_NAME ($DOCKER_REPO:$DOCKER_TAG)
|
||||
# shellspec/shellspec:<TAG>
|
||||
# shellspec/shellspec-<VARIANT>:<VERSION>
|
||||
|
||||
case $DOCKER_REPO in
|
||||
*-scratch) exit
|
||||
esac
|
||||
|
||||
# Build kcov image
|
||||
case $DOCKER_TAG in
|
||||
latest) IMAGE_NAME="$DOCKER_REPO:kcov" ;;
|
||||
* ) IMAGE_NAME="$IMAGE_NAME-kcov" ;;
|
||||
esac
|
||||
DOCKER_TAG=${IMAGE_NAME#*:}
|
||||
"$(dirname "$0")/build" --target kcov
|
||||
16
tests/shellspec/.vendor/shellspec-0.28.1/.dockerhub/hooks/post_push
Executable file
16
tests/shellspec/.vendor/shellspec-0.28.1/.dockerhub/hooks/post_push
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
# IMAGE_NAME ($DOCKER_REPO:$DOCKER_TAG)
|
||||
# shellspec/shellspec:<TAG>
|
||||
# shellspec/shellspec-<VARIANT>:<VERSION>
|
||||
|
||||
case $DOCKER_REPO in
|
||||
*-scratch) exit
|
||||
esac
|
||||
|
||||
# Push kcov image
|
||||
case $DOCKER_TAG in
|
||||
latest) IMAGE_NAME="$DOCKER_REPO:kcov" ;;
|
||||
* ) IMAGE_NAME="$IMAGE_NAME-kcov" ;;
|
||||
esac
|
||||
docker push "$IMAGE_NAME"
|
||||
@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
if [ "${1:-}" = "-" ] && shift; then
|
||||
[ $# -gt 0 ] && exec "$@"
|
||||
type bash >/dev/null 2>&1 && exec /bin/bash -l
|
||||
exec /bin/sh -l
|
||||
fi
|
||||
|
||||
if [ -e .shellspec-docker/pre-test ]; then
|
||||
.shellspec-docker/pre-test
|
||||
fi
|
||||
|
||||
shellspec "$@"
|
||||
|
||||
if [ -e .shellspec-docker/post-test ]; then
|
||||
.shellspec-docker/post-test
|
||||
fi
|
||||
19
tests/shellspec/.vendor/shellspec-0.28.1/.dockerignore
Normal file
19
tests/shellspec/.vendor/shellspec-0.28.1/.dockerignore
Normal file
@ -0,0 +1,19 @@
|
||||
*
|
||||
!.dockerhub/shellspec-docker-entrypoint.sh
|
||||
!bin
|
||||
!contrib/bugs.sh
|
||||
!lib
|
||||
!libexec
|
||||
!dockerfiles/.shellspec-entrypoint.sh
|
||||
!examples
|
||||
!helper
|
||||
!spec
|
||||
!stub
|
||||
helper/fixture/stat/*
|
||||
!.shellspec
|
||||
!shellspec
|
||||
!install.sh
|
||||
!LICENSE
|
||||
!Makefile
|
||||
!package.json
|
||||
!*.sh
|
||||
3
tests/shellspec/.vendor/shellspec-0.28.1/.gitattributes
vendored
Normal file
3
tests/shellspec/.vendor/shellspec-0.28.1/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
* text=auto eol=lf
|
||||
helper/fixture/** -text
|
||||
dockerfiles/* linguist-language=Dockerfile
|
||||
27
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/macos-brew.yml
vendored
Normal file
27
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/macos-brew.yml
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
name: macOS Homebrew
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
||||
jobs:
|
||||
macos-brew:
|
||||
runs-on: macos-latest
|
||||
if: "!contains(github.event.head_commit.message, 'ci skip')"
|
||||
strategy:
|
||||
matrix:
|
||||
shells:
|
||||
- {shell: dash, package: dash}
|
||||
- {shell: bash, package: bash}
|
||||
- {shell: ksh, package: ksh}
|
||||
- {shell: mksh, package: mksh}
|
||||
- {shell: yash, package: yash}
|
||||
- {shell: zsh, package: zsh}
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: brew upgrade
|
||||
- run: brew install ${{ matrix.shells.package }}
|
||||
- run: ${{ matrix.shells.shell }} ./shellspec --shell "${{ matrix.shells.shell }}" --task fixture:stat:prepare
|
||||
- run: SH="${{ matrix.shells.shell }}" contrib/various_test.sh
|
||||
24
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/macos-catalina.yml
vendored
Normal file
24
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/macos-catalina.yml
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
name: macOS Catalina
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
||||
jobs:
|
||||
macos-catalina:
|
||||
runs-on: macos-10.15
|
||||
if: "!contains(github.event.head_commit.message, 'ci skip')"
|
||||
strategy:
|
||||
matrix:
|
||||
shells:
|
||||
- {shell: sh}
|
||||
- {shell: dash}
|
||||
- {shell: bash}
|
||||
- {shell: ksh}
|
||||
- {shell: zsh}
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: ${{ matrix.shells.shell }} ./shellspec --shell "${{ matrix.shells.shell }}" --task fixture:stat:prepare
|
||||
- run: SH="${{ matrix.shells.shell }}" contrib/various_test.sh
|
||||
33
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/release.yml
vendored
Normal file
33
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '[0-9]*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Make dist archive
|
||||
run: make dist
|
||||
- name: Create release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1.0.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: ${{ github.ref }}
|
||||
draft: false
|
||||
prerelease: ${{ contains(github.ref, '-') }}
|
||||
- name: Upload release asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: shellspec-dist.tar.gz
|
||||
asset_name: shellspec-dist.tar.gz
|
||||
asset_content_type: application/gzip
|
||||
28
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/ubuntu-bionic.yml
vendored
Normal file
28
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/ubuntu-bionic.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: Ubuntu Bionic Beaver
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
||||
jobs:
|
||||
ubuntu-bionic:
|
||||
runs-on: ubuntu-18.04
|
||||
if: "!contains(github.event.head_commit.message, 'ci skip')"
|
||||
strategy:
|
||||
matrix:
|
||||
shells:
|
||||
- {shell: dash, package: dash}
|
||||
- {shell: bash, package: bash}
|
||||
- {shell: busybox ash, package: busybox}
|
||||
- {shell: ksh, package: ksh}
|
||||
- {shell: mksh, package: mksh}
|
||||
- {shell: posh, package: posh}
|
||||
- {shell: yash, package: yash}
|
||||
- {shell: zsh, package: zsh}
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: sudo apt-get install -y ${{ matrix.shells.package }}
|
||||
- run: sudo ${{ matrix.shells.shell }} ./shellspec --task fixture:stat:prepare
|
||||
- run: SH="${{ matrix.shells.shell }}" contrib/various_test.sh
|
||||
28
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/ubuntu-focal.yml
vendored
Normal file
28
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/ubuntu-focal.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: Ubuntu Focal Fossa
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
||||
jobs:
|
||||
ubuntu-focal:
|
||||
runs-on: ubuntu-20.04
|
||||
if: "!contains(github.event.head_commit.message, 'ci skip')"
|
||||
strategy:
|
||||
matrix:
|
||||
shells:
|
||||
- {shell: dash, package: dash}
|
||||
- {shell: bash, package: bash}
|
||||
- {shell: busybox ash, package: busybox}
|
||||
- {shell: ksh, package: ksh}
|
||||
- {shell: mksh, package: mksh}
|
||||
- {shell: posh, package: posh}
|
||||
- {shell: yash, package: yash}
|
||||
- {shell: zsh, package: zsh}
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: sudo apt-get install -y ${{ matrix.shells.package }}
|
||||
- run: sudo ${{ matrix.shells.shell }} ./shellspec --task fixture:stat:prepare
|
||||
- run: SH="${{ matrix.shells.shell }}" contrib/various_test.sh
|
||||
28
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/ubuntu-xenial.yml
vendored
Normal file
28
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/ubuntu-xenial.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: Ubuntu Xenial Xerus
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
||||
jobs:
|
||||
ubuntu-xenial:
|
||||
runs-on: ubuntu-16.04
|
||||
if: "!contains(github.event.head_commit.message, 'ci skip')"
|
||||
strategy:
|
||||
matrix:
|
||||
shells:
|
||||
- {shell: dash, package: dash}
|
||||
- {shell: bash, package: bash}
|
||||
- {shell: busybox ash, package: busybox}
|
||||
- {shell: ksh, package: ksh}
|
||||
- {shell: mksh, package: mksh}
|
||||
- {shell: posh, package: posh}
|
||||
- {shell: yash, package: yash}
|
||||
- {shell: zsh, package: zsh}
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: sudo apt-get install -y ${{ matrix.shells.package }}
|
||||
- run: sudo ${{ matrix.shells.shell }} ./shellspec --task fixture:stat:prepare
|
||||
- run: SH="${{ matrix.shells.shell }}" contrib/various_test.sh
|
||||
28
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/windows-busybox.yml
vendored
Normal file
28
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/windows-busybox.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: Windows busybox
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
PATH: 'C:\Program Files\Git\bin;C:\Windows\System32;C:\Windows;C:\ProgramData\Chocolatey\bin'
|
||||
FORCE_COLOR: 1
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: cmd
|
||||
|
||||
jobs:
|
||||
windows-busybox:
|
||||
runs-on: windows-latest
|
||||
if: "!contains(github.event.head_commit.message, 'ci skip')"
|
||||
strategy:
|
||||
matrix:
|
||||
shells:
|
||||
- {shell: sh}
|
||||
- {shell: ash}
|
||||
- {shell: bash}
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: choco install -y --no-progress busybox
|
||||
- run: busybox ${{ matrix.shells.shell }} ./shellspec --task fixture:stat:prepare
|
||||
- run: busybox ${{ matrix.shells.shell }} ./shellspec
|
||||
35
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/windows-cygwin.yml
vendored
Normal file
35
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/windows-cygwin.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
name: Windows Cygwin
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
PATH: 'C:\tools\cygwin\bin;C:\Program Files\Git\bin;C:\Windows\System32;C:\Windows;C:\Windows\System32\WindowsPowerShell\v1.0;C:\ProgramData\Chocolatey\bin'
|
||||
FORCE_COLOR: 1
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: cmd
|
||||
|
||||
jobs:
|
||||
windows-cygwin:
|
||||
runs-on: windows-latest
|
||||
if: "!contains(github.event.head_commit.message, 'ci skip')"
|
||||
strategy:
|
||||
matrix:
|
||||
shells:
|
||||
- {shell: sh, package: sh}
|
||||
- {shell: dash, package: dash}
|
||||
- {shell: bash, package: bash}
|
||||
- {shell: ash, package: busybox}
|
||||
- {shell: mksh, package: mksh}
|
||||
- {shell: posh, package: posh}
|
||||
- {shell: zsh, package: zsh}
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: choco install -y --no-progress cygwin cyg-get
|
||||
- run: cyg-get nc ${{ matrix.shells.package }}
|
||||
- run: cygcheck -c
|
||||
- run: ${{ matrix.shells.shell }} ./shellspec --task fixture:stat:prepare
|
||||
- run: ${{ matrix.shells.shell }} -c "rm helper/fixture/stat/no-permission"
|
||||
- run: ${{ matrix.shells.shell }} ./shellspec
|
||||
27
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/windows-gitbash.yml
vendored
Normal file
27
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/windows-gitbash.yml
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
name: Windows GitBash
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
PATH: 'C:\Program Files\Git\bin;C:\windows\system32;C:\windows'
|
||||
FORCE_COLOR: 1
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
windows-gitbash:
|
||||
runs-on: windows-latest
|
||||
if: "!contains(github.event.head_commit.message, 'ci skip')"
|
||||
strategy:
|
||||
matrix:
|
||||
shells:
|
||||
- {shell: sh}
|
||||
- {shell: dash}
|
||||
- {shell: bash}
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: ${{ matrix.shells.shell }} ./shellspec --task fixture:stat:prepare
|
||||
- run: ${{ matrix.shells.shell }} ./shellspec
|
||||
32
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/windows-msys.yml
vendored
Normal file
32
tests/shellspec/.vendor/shellspec-0.28.1/.github/workflows/windows-msys.yml
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
name: Windows MSYS
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
PATH: 'C:\msys64\usr\bin;C:\Program Files\Git\bin;C:\windows\system32;C:\windows'
|
||||
FORCE_COLOR: 1
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: cmd
|
||||
|
||||
jobs:
|
||||
windows-msys:
|
||||
runs-on: windows-latest
|
||||
if: "!contains(github.event.head_commit.message, 'ci skip')"
|
||||
strategy:
|
||||
matrix:
|
||||
shells:
|
||||
- {shell: sh, package: sh}
|
||||
- {shell: dash, package: dash}
|
||||
- {shell: bash, package: bash}
|
||||
- {shell: busybox ash, package: busybox}
|
||||
- {shell: mksh, package: mksh}
|
||||
- {shell: zsh, package: zsh}
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: pacman.exe -Syu --noprogressbar --noconfirm
|
||||
- run: pacman.exe -S --noprogressbar --noconfirm ${{ matrix.shells.package }}
|
||||
- run: ${{ matrix.shells.shell }} ./shellspec --task fixture:stat:prepare
|
||||
- run: ${{ matrix.shells.shell }} ./shellspec
|
||||
7
tests/shellspec/.vendor/shellspec-0.28.1/.gitignore
vendored
Normal file
7
tests/shellspec/.vendor/shellspec-0.28.1/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
.env
|
||||
.shellspec-local
|
||||
.shellspec-quick.log
|
||||
/*.tar.gz
|
||||
report
|
||||
coverage*
|
||||
ttyrecord
|
||||
@ -0,0 +1 @@
|
||||
v0.7.1
|
||||
11
tests/shellspec/.vendor/shellspec-0.28.1/.shellspec
Normal file
11
tests/shellspec/.vendor/shellspec-0.28.1/.shellspec
Normal file
@ -0,0 +1,11 @@
|
||||
--require spec_helper
|
||||
--require ksh_workaround
|
||||
--helperdir helper
|
||||
--sandbox
|
||||
--skip-message moderate
|
||||
--fail-no-examples
|
||||
--env-from helper/env.sh
|
||||
--kcov-options "--include-pattern="
|
||||
--kcov-options "--include-path=./shellspec,./install.sh,./lib,./libexec"
|
||||
--kcov-options "--exclude-pattern=/.,_generated.sh"
|
||||
--hide-deprecations
|
||||
67
tests/shellspec/.vendor/shellspec-0.28.1/.travis.yml
Normal file
67
tests/shellspec/.vendor/shellspec-0.28.1/.travis.yml
Normal file
@ -0,0 +1,67 @@
|
||||
language: shell
|
||||
os: linux
|
||||
dist: bionic
|
||||
env:
|
||||
global:
|
||||
- PATH=${PATH}:${HOME}/kcov/bin
|
||||
- CC_TEST_REPORTER_URL=https://codeclimate.com/downloads/test-reporter/test-reporter-latest-darwin-amd64
|
||||
- CC_TEST_REPORTER_ID=67e0534ee993a6bbd10ae205ef4e807956c01564564ed64738932db123b1b87a
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
jobs:
|
||||
include:
|
||||
# - os: linux # Ubuntu 12.04
|
||||
# dist: precise
|
||||
# env: PACKAGES="dash bash zsh ksh mksh yash busybox"
|
||||
# - os: linux # Ubuntu 14.04
|
||||
# dist: trusty
|
||||
# env: PACKAGES="dash bash zsh ksh mksh yash posh busybox"
|
||||
# - os: linux # Ubuntu 16.04
|
||||
# dist: xenial
|
||||
# env: PACKAGES="dash bash zsh ksh mksh yash posh busybox"
|
||||
# - os: linux # Ubuntu 18.04
|
||||
# dist: bionic
|
||||
# env: PACKAGES="dash bash zsh ksh mksh yash posh busybox"
|
||||
# - os: linux # Ubuntu 20.04
|
||||
# dist: focal
|
||||
# env: PACKAGES="dash bash zsh ksh mksh yash posh busybox"
|
||||
# - os: osx # macOS Homebrew
|
||||
# osx_image: xcode11.5
|
||||
# env: FORMULAS="dash bash zsh ksh mksh yash"
|
||||
- os: osx # macOS 10.10 Yosemite 2014-06
|
||||
osx_image: xcode6.4
|
||||
env: SHELLS="sh bash zsh ksh"
|
||||
- os: osx # macOS 10.11 El Capitan 2015-06
|
||||
osx_image: xcode8
|
||||
env: SHELLS="sh bash zsh ksh"
|
||||
- os: osx # macOS 10.12 Sierra 2016-06
|
||||
osx_image: xcode9.2
|
||||
env: SHELLS="sh bash zsh ksh"
|
||||
- os: osx # macOS 10.13 High Sierra 2017-06
|
||||
osx_image: xcode10.1
|
||||
env: SHELLS="sh bash zsh ksh"
|
||||
- os: osx # macOS 10.14 Mojave 2018-06
|
||||
osx_image: xcode10.2
|
||||
env: SHELLS="sh bash zsh ksh"
|
||||
# - os: osx # macOS 10.15.4 Catalina 2020-03
|
||||
# osx_image: xcode11.5
|
||||
# env: SHELLS="sh bash zsh ksh"
|
||||
- os: osx # coverage
|
||||
osx_image: xcode12.2
|
||||
env: FORMULAS="bash kcov" COVERAGE=1 CODECOV=1 CC=1
|
||||
before_install:
|
||||
- if [ "$PACKAGES" ]; then sudo apt-get install -y $PACKAGES; fi
|
||||
- if [ "$FORMULAS" ]; then brew update; brew install $FORMULAS; fi
|
||||
- if [ "$CC" ]; then curl -sSL $CC_TEST_REPORTER_URL > ./cc-test-reporter; fi
|
||||
- if [ "$CC" ]; then chmod +x ./cc-test-reporter; fi
|
||||
- if [ "$CC" ]; then ./cc-test-reporter before-build; fi
|
||||
before_script:
|
||||
- ./shellspec --shell sh --task fixture:stat:prepare
|
||||
script:
|
||||
- if [ ! "$COVERAGE" ]; then contrib/all.sh contrib/various_test.sh; fi
|
||||
- if [ "$COVERAGE" ]; then ./shellspec --shell bash --kcov --kcov-options "--coveralls-id=${TRAVIS_JOB_ID}"; fi
|
||||
after_success:
|
||||
- if [ "$CODECOV" ]; then bash <(curl -s https://codecov.io/bash) -s coverage; fi
|
||||
- if [ "$CC" ]; then ./cc-test-reporter format-coverage coverage/cobertura.xml -t cobertura; fi
|
||||
- if [ "$CC" ]; then ./cc-test-reporter upload-coverage; fi
|
||||
576
tests/shellspec/.vendor/shellspec-0.28.1/CHANGELOG.md
Normal file
576
tests/shellspec/.vendor/shellspec-0.28.1/CHANGELOG.md
Normal file
@ -0,0 +1,576 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.28.1] - 2021-01-11
|
||||
|
||||
### Changed
|
||||
|
||||
- Improved documentation. Thanks to Yohei Kawahara (#173).
|
||||
|
||||
### Fixed
|
||||
|
||||
- bash: Fixed an unexpected error message in self-executable specfile.
|
||||
- Fixed a bug that test command cannot redefine when using "when run source"
|
||||
- Fixed a bug when specified relative tmp directory path.
|
||||
- Fixed option parsing
|
||||
|
||||
## [0.28.0] - 2021-01-05
|
||||
|
||||
### Added
|
||||
|
||||
- Added `BeforeEach` / `AfterEach` as synonym for `Before` / `After`.
|
||||
- Added `FORCE_COLOR` environment variable.
|
||||
- Added `--tmpdir` option.
|
||||
- Added `--execdir` option to specify the directory for specfile execution.
|
||||
- Added `-c` (`--chdir`) and `-C` (`--directory`) options to change directory at startup.
|
||||
- Added path syntax (`*/` and `**/`) and `-L` (`--dereference`) option to match recursive directories.
|
||||
- Added `--helperdir` to specify the location of `spec_helper` etc.
|
||||
- Added the environment variable `SHELLSPEC_HELPERDIR` to indicate the location of `spec_helper` etc.
|
||||
- Added `--reportdir` and `--covdir` options.
|
||||
- Added `-O` (`--option`) option.
|
||||
- Added `-I` (`--load-path`) option.
|
||||
- Added `<module>_precheck` callback and some helper functions to `spec_helper` for pre-checking.
|
||||
- Added `<module>_loaded` callback to be called after `spec_helper` loading.
|
||||
|
||||
### Changed
|
||||
|
||||
- Replaced with a new option parser [getoptions](https://github.com/ko1nksm/getoptions) which supports the standard option syntax.
|
||||
- Replaced `--keep-tempdir` with `--keep-tmpdir`.
|
||||
- Specifying a file in the shellspec's argument is now ignored if it does not match `--pattern`.
|
||||
- Filled in system-out and system-err in junit xml.
|
||||
- Allowed run the tests from any subdirectory.
|
||||
- The `-D` option has been deprecated (Replace with the `--default-path` option).
|
||||
- The environment variable `SHELLSPEC_SPECDIR` has been deprecated since there is not always a single directory for specfiles.
|
||||
- Rename `.shellspec-profiler.log` to `profiler.log` for profiler log.
|
||||
- Accept `banner.md` as a banner file
|
||||
- `Include` and `import` (`shellspec_import`) can now pass arguments.
|
||||
- The delimiter of the environment variable `SHELLSPEC_REQUIRES` has been changed from `:` to space.
|
||||
- Improved documentation. Thanks to ldicarlo (#117, #119), Antoni Marcinek (#120, #139), Stuart R. Jefferys (#155), Leon Stafford (#159).
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed `--kcov-common-options` option.
|
||||
|
||||
### Fixed
|
||||
|
||||
- bash 4.1 - 4.3: Fixed a bug that `run script` could not get the exit status.
|
||||
- zsh < 4.2.0: Fixed a bug when extendedglob is enabled.
|
||||
- Fixed possibility of I/O error in satisfy matcher (GitHub Actions only?).
|
||||
- Fixed a bug in which zsh on macOS occasionally exits with exit code 147 (SIGCONT).
|
||||
- Fixed several bugs related to the Windows path for busybox-w32.
|
||||
- Fixed a bug when using metacharacters for tags.
|
||||
|
||||
## [0.27.2] - 2020-10-28
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a bug that didn't cause an error if there are fixed examples.
|
||||
|
||||
## [0.27.1] - 2020-09-30
|
||||
|
||||
### Removed
|
||||
|
||||
- Drop support for posh 0.8.5 due to signal handling broken.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed gray color.
|
||||
- Fixed broken `--warning-as-failure`.
|
||||
- Fixed a bug that can not CTRL-C with posh.
|
||||
|
||||
## [0.27.0] - 2020-09-25
|
||||
|
||||
### Added
|
||||
|
||||
- **Added `be exported` and `be readonly` matchers.**
|
||||
- Added `%printf` and `%sleep` directives.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Improved TAP formatter.**
|
||||
- Supports `TODO` and `SKIP` directives.
|
||||
- Use `Bail out!` on error.
|
||||
- Added error details.
|
||||
- `BeforeAll` / `AfterAll`: Avoid crashes due to hook errors.
|
||||
- `Before` / `After`: Improved hook error handling.
|
||||
- `BeforeCall` / `AfterCall`, `BeforeRun` / `AfterRun`: Minor changes.
|
||||
|
||||
### Removed
|
||||
|
||||
- Drop support for dash 0.5.3 due to unstable bug.
|
||||
- Drop support for busybox < 1.20.0 due to unstable bug.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a bug that "Parameter is not set" error in word modifier.
|
||||
- Fixed a bug that satisfy matcher succeed even syntax error.
|
||||
- Fixed a bug that can not CTRL-C with parallel execution on zsh.
|
||||
- shellspec-syntax-check.sh: Some minor bug fixes.
|
||||
|
||||
## [0.26.1] - 2020-07-13
|
||||
|
||||
### Added
|
||||
|
||||
- **Added `--docker` option.** (EXPERIMENTAL)
|
||||
|
||||
## [0.26.0] - 2020-07-12
|
||||
|
||||
### Added
|
||||
|
||||
- **Added `Mock` helper (command-based mock).**
|
||||
- **Added `%preserve` directive.**
|
||||
- **Added `--sandbox`, `--sandbox-path` option.**
|
||||
- Added `--path` option.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Workaround when the Windows version of `sort.exe` is executed.
|
||||
|
||||
## [0.25.0] - 2020-06-21
|
||||
|
||||
### Added
|
||||
|
||||
- **Coverage support for zsh and ksh.** (#62)
|
||||
- Respect `NO_COLOR` environment variable.
|
||||
- Support [busybox-w32](https://frippery.org/busybox/) ash for windows.
|
||||
- **Added `Assert` expectation to assert side effects of system environment.**
|
||||
- Added `Dump` helper - dump stdout, stderr and status for debugging.
|
||||
- Added `line` and `word` subject. (`of stdout (output)` can be omitted now)
|
||||
- Added `--log-file` option to specify log file for `%logger` and trace.
|
||||
- **Implement `--xtrace` (`--xtrace-only`) feature.**
|
||||
|
||||
### Changed
|
||||
|
||||
- Upgrade to alpine 3.12 for docker image and officially release `shellspec/kcov` docker image.
|
||||
- Separate a file descriptor for reporting and stdout to able to use `echo` in specfile.
|
||||
- Minor specification change of `result` modifier and `satisfy` matcher.
|
||||
- `-r` option is now a short option for `--repair`, not `--require`.
|
||||
- Use [debian/eol(https://hub.docker.com/r/debian/eol/) docker images for old debian tests.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Before/After hooks should not consume stdin data (#82)
|
||||
|
||||
## [0.24.3] - 2020-06-06
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixes `BeforeAll` / `AfterAll` to share states
|
||||
|
||||
## [0.24.2] - 2020-05-27
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a bug "SHELLSPEC_GROUP_ID: unbound variable"
|
||||
- Fixes when ran by "bash shellcpec" and "ksh shellspec"
|
||||
|
||||
## [0.24.1] - 2020-05-22
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed broken `Todo`.
|
||||
- Fixed a bug that caused an error when "--kcov" was specified and /dev/tty no be writable. (#67 Alexander Reitzel)
|
||||
- Fixed a bug when enabled extendedglob for zsh.
|
||||
|
||||
## [0.24.0] - 2020-05-11
|
||||
|
||||
### Added
|
||||
|
||||
- Add `BeforeAll` and `AfterAll`. (#7)
|
||||
- Expand parameter within Data helper. (#57)
|
||||
- Add test for [GWSH shell](https://github.com/hvdijk/gwsh).
|
||||
- Add manual test for OpenBSD ksh on OpenBSD 6.6.
|
||||
- Add manual test for NetBSD sh on NetBSD 9.0.
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed `match` matcher. Use `match pattern` matcher instead.
|
||||
- Remove tests for unstable old shells (Bus Error, Bad address, Memory fault, etc).
|
||||
- CI test for pdksh 5.2.14 on FreeBSD.
|
||||
- Docker test for pdksh 5.2.14 on Debian 2.2r7.
|
||||
- Docker test for ksh 93q on Debian 3.1r8.
|
||||
- Remove tests for FreeBSD 13.0-current (Unstable due to work in progress).
|
||||
|
||||
## [0.23.0] - 2020-04-02
|
||||
|
||||
### Added
|
||||
|
||||
- New **quick execution** and related options (`--quick`, `--repair`, `--next`).
|
||||
- New **failures formatter**.
|
||||
- Support **self-executable specfile**. (#40)
|
||||
- Add `--pending-message` and `--quiet` option.
|
||||
- Add short options for focus and filters.
|
||||
- Add `-w` short options for `--warning-as-failure`.
|
||||
- Add `--boost` (joke) option.
|
||||
- Reporter: Displays comments of 'temporary skip' and 'temporary pending'.
|
||||
- Support windows line endings. (#45)
|
||||
- Syntax check for missing `End` of parameters.
|
||||
- shellspec --init: generate ignore file for cvs.
|
||||
|
||||
### Changed
|
||||
|
||||
- Run the specfile specified by arguments even not end with `_spec.sh`.
|
||||
- Formatter: Change fixed color.
|
||||
- Formatter: Change mark for fixed and pending of progress formatter.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed `--pattern` option to avoid syntax error.
|
||||
- Return exit status code on the specfile properly.
|
||||
- Fixed a bug that `start with` and `end with` match glob pattern.
|
||||
- Formatter: Fixed not display correctly of documentation formatter when description is empty.
|
||||
- Fixed an issue installer.sh fails in some environments. (#43)
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Use `--require` long option instead of `-r` short option.
|
||||
|
||||
## [0.22.0] - 2020-02-22
|
||||
|
||||
### Added
|
||||
|
||||
- Improve kcov version detection.
|
||||
- Colored TAP formatter. (#34 Kylie McClain)
|
||||
- Added `--show-deprecations` and `--hide-deprecations` options.
|
||||
|
||||
### Changed
|
||||
|
||||
- New **kcov integration**.
|
||||
- Do not create translated specfile in project directory.
|
||||
- Suppress unnecessary coverage measurement to improve testing speed.
|
||||
- Added `--coverage-report-info` to add extra information to coverage report.
|
||||
- make install compatible with BSD and macOS.
|
||||
- Suppress unnecessary before/after hooks of skipped examples.
|
||||
- install.sh: Install to under $HOME/.local by default
|
||||
- Use $HOME/.config if not defined XDG_CONFIG_HOME
|
||||
|
||||
### Deprecated
|
||||
|
||||
- `--kcov-common-options` is deprecated, merge into `--kcov-options`.
|
||||
- Deprecates the `match` matcher due to cause many syntax errors. Use `match pattern` matcher instead.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed broken test in docker on Linux.
|
||||
- Fixed `--example` option to avoid syntax error.
|
||||
- Append to LOGFILE instead of overwriting.
|
||||
|
||||
## [0.21.0] - 2020-01-30
|
||||
|
||||
### Added
|
||||
|
||||
- Provide **docker images**.
|
||||
- Provide **distribution archive**.
|
||||
- Available ArchLinux package. (#15 Damien Flament)
|
||||
|
||||
### Changed
|
||||
|
||||
- docs: Improve English quality. (#16 Damien Flament)
|
||||
|
||||
## [0.20.2] - 2019-08-24
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed wrong SHELLSPEC_TMPBASE
|
||||
- Fixed for bug that some shell can not call external command same name as builtin.
|
||||
|
||||
## [0.20.1] - 2019-08-19
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed for solaris.
|
||||
|
||||
## [0.20.0] - 2019-08-18
|
||||
|
||||
### Added
|
||||
|
||||
- Add **parameterized example**. (`Parameters` helper)
|
||||
- Add `Set` helper for set shell option
|
||||
- Add `BeforeCall` / `AfterCall` helper.
|
||||
- Add `BeforeRun` / `AfterRun` helper.
|
||||
- Use `hexdump` if `od` does not exist.
|
||||
|
||||
### Changed
|
||||
|
||||
- Redesign `run` evaluation. [**major breaking change**]
|
||||
- Change the behavior to close to the `run` of bats.
|
||||
- New `run` evaluation allows the execution of functions and commands.
|
||||
- Use `run command` to execute only the commands. (old `run` -> use `run command`)
|
||||
- Merge `invoke` evaluation to `run` evaluation. (old `invoke` -> use `run`)
|
||||
- Merge `execute` evaluation to `run` evaluation. (old `execute` -> use `run source`)
|
||||
- Export %const values to the translation process
|
||||
|
||||
### Removed
|
||||
|
||||
- Drop support for posh 0.10.2 and similar versions as the handling of the shell flag is broken.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed bug for related with tag.
|
||||
- Fixed bug where coverage might not work on macOS.
|
||||
|
||||
## [0.19.1] - 2019-07-23
|
||||
|
||||
### Added
|
||||
|
||||
- Support install via make, bpkg, basher
|
||||
|
||||
## [0.19.0] - 2019-07-22
|
||||
|
||||
### Added
|
||||
|
||||
- Add installer (It has not been officially released, but you can used it already).
|
||||
- Testing for **single script file** (Add `execute` evaluation, `Intercept` and `__SOURCED__` variable).
|
||||
- Add `--keep-tempdir` option.
|
||||
- Add `Data < <FILE>` syntax.
|
||||
|
||||
### Removed
|
||||
|
||||
- Drop support for busybox 1.1.3 and similar versions as it can not redefine builtin commands.
|
||||
- Drop support for ash 0.3.8 and similar versions as it can not use retrun in sourced script.
|
||||
- Remove `call`/`invoke` `<STRING>` syntax.
|
||||
|
||||
## [0.18.0] - 2019-07-09
|
||||
|
||||
### Added
|
||||
|
||||
- **Profiler feature** (`--profile`)
|
||||
- Time attribute for JUnit XML.
|
||||
|
||||
## [0.17.0] - 2019-07-06
|
||||
|
||||
### Added
|
||||
|
||||
- **Coverage reporting**.
|
||||
- Add `--fail-low-coverage` option.
|
||||
|
||||
## [0.16.0] - 2019-07-03
|
||||
|
||||
### Added
|
||||
|
||||
- **Coverage** support (kcov integration)
|
||||
- Add **JUnit formatter** and **report generator**.
|
||||
- Add `--warning-as-failure` option.
|
||||
- Support [Unofficial Bash Strict Mode](http://redsymbol.net/articles/unofficial-bash-strict-mode/).
|
||||
- Support for [Schily Bourne Shell](http://schilytools.sourceforge.net/bosh.html) (`bosh`, `pbosh`).
|
||||
|
||||
### Changed
|
||||
|
||||
- Change `--skip-message none` to `--skip-message verbose`.
|
||||
|
||||
### Removed
|
||||
|
||||
- Remove `--warnings` option.
|
||||
|
||||
## [0.15.0] - 2019-05-26
|
||||
|
||||
### Added
|
||||
|
||||
- Add `be empty directory` (alias: `be empty dir`) matcher.
|
||||
|
||||
### Changed
|
||||
|
||||
- Rename `be empty` matcher to `be empty file` matcher. [breaking change]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed bug that `be empty` (renamed to `be empty file`) matcher matches not exists file, etc.
|
||||
- Ensure call & invoke start with errno zero (#2 Rowan Thorpe)
|
||||
|
||||
## [0.14.0] - 2019-05-15
|
||||
|
||||
### Added
|
||||
|
||||
- Add `--random` option.
|
||||
|
||||
### Changed
|
||||
|
||||
- Improve `--example`, `--tag` option.
|
||||
|
||||
## [0.13.1] - 2019-05-13
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed bug when --dry-run mode.
|
||||
- Fixed documentation formatter.
|
||||
|
||||
## [0.13.0] - 2019-05-12
|
||||
|
||||
### Added
|
||||
|
||||
- Add `--list examples:id` option.
|
||||
- Add `*_spec.sh:@ID` syntax the specify id with the filename.
|
||||
- Add `--pattern`, `--example`, `--tag`, `--default-path` filter option.
|
||||
|
||||
### Changed
|
||||
|
||||
- Change `Logger` Helper to `%logger` directive.
|
||||
- Merge `--list-specfiles`, `--list-examples` options to `--list` option.
|
||||
- Redesign reporter to improve performance, maintainability.
|
||||
|
||||
## [0.12.0] - 2019-04-26
|
||||
|
||||
### Added
|
||||
|
||||
- Add `--list-specfiles`, `--list-examples` option.
|
||||
- Add `--env-from` option.
|
||||
- Add tests that for array if supported shells.
|
||||
|
||||
### Changed
|
||||
|
||||
- Change `--count` option output includes the number of specfiles.
|
||||
- Change to the banner show only on shellspec-runner.
|
||||
|
||||
## [0.11.3] - 2019-04-24
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed broken parallel executor.
|
||||
|
||||
## [0.11.2] - 2019-04-23
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed bug that does not work with zsh 5.4.2.
|
||||
|
||||
## [0.11.1] - 2019-04-21
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed ignored specified line number when parallel execution.
|
||||
- Fixed documentation formatter when supplied multiple specfiles.
|
||||
|
||||
## [0.11.0] - 2019-04-20
|
||||
|
||||
### Added
|
||||
|
||||
- Run **the example by line number**. (`*_spec.sh:#`)
|
||||
- Run **focused groups / examples**. (`fDescribe`, `fContext`, `fExample`, `fSpecify`, `fIt`)
|
||||
- Add `--count` option for count the number of examples without running.
|
||||
|
||||
## [0.10.0] - 2019-04-17
|
||||
|
||||
### Added
|
||||
|
||||
- Support **parallel execution**. (`--jobs` option)
|
||||
|
||||
### Changed
|
||||
|
||||
- Separete syntax checker into tools.
|
||||
- Improve syntax checker.
|
||||
- Improve error handling.
|
||||
- Improve ctrl-c handling.
|
||||
|
||||
### Removed
|
||||
|
||||
- Remove `Def` helper. (use `%putsn`, `%puts` directive instead)
|
||||
|
||||
## [0.9.0] - 2019-03-30
|
||||
|
||||
### Added
|
||||
|
||||
- Add `--syntax-check` option for syntax check of the specfile.
|
||||
|
||||
### Changed
|
||||
|
||||
- Change timing of loading external script by 'Include'. [breaking change]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix for translation speed slowdown.
|
||||
|
||||
### Removed
|
||||
|
||||
- Remove shorthand of the variable subject.
|
||||
|
||||
## [0.8.0] - 2019-03-26
|
||||
|
||||
### Added
|
||||
|
||||
- Add `Constant definition`.
|
||||
- Add `Data` helper, `Embedded text`.
|
||||
- Add `Def` helper.
|
||||
- Add `Logger` helper.
|
||||
- Add `result` modifier.
|
||||
- Add `Include` helper.
|
||||
- Add shorthand for `function` subject and `variable` subject.
|
||||
- Add failed message for `Before`/`After` each hook.
|
||||
|
||||
### Changed
|
||||
|
||||
- Change behavior of `line` and `lines` modifier to like "grep -c" not "wc -l".
|
||||
- Change `function` subject to alias for `value` subject.
|
||||
- Improve handling unexpected errors.
|
||||
- Improve examples.
|
||||
|
||||
### Removed
|
||||
|
||||
- Remove `It` statement and change `It` is alias of `Example` now.
|
||||
- Remove `Set` / `Unset` helper.
|
||||
- Remove `Debug` helper.
|
||||
- Remove `string` subject.
|
||||
- Remove `exit status` subject. (use `status` subject)
|
||||
|
||||
## [0.7.0] - 2019-03-08
|
||||
|
||||
### Added
|
||||
|
||||
- Added `lines` modifier.
|
||||
|
||||
## [0.6.0] - 2019-02-19
|
||||
|
||||
### Added
|
||||
|
||||
- Added `match` matcher.
|
||||
|
||||
## [0.5.0] - 2019-02-06
|
||||
|
||||
### Added
|
||||
|
||||
- Initial public release.
|
||||
|
||||
[Unreleased]: https://github.com/shellspec/shellspec/compare/0.28.1...HEAD
|
||||
[0.28.1]: https://github.com/shellspec/shellspec/compare/0.28.0...0.28.1
|
||||
[0.28.0]: https://github.com/shellspec/shellspec/compare/0.27.2...0.28.0
|
||||
[0.27.2]: https://github.com/shellspec/shellspec/compare/0.27.1...0.27.2
|
||||
[0.27.1]: https://github.com/shellspec/shellspec/compare/0.27.0...0.27.1
|
||||
[0.27.0]: https://github.com/shellspec/shellspec/compare/0.26.1...0.27.0
|
||||
[0.26.1]: https://github.com/shellspec/shellspec/compare/0.26.0...0.26.1
|
||||
[0.26.0]: https://github.com/shellspec/shellspec/compare/0.25.0...0.26.0
|
||||
[0.25.0]: https://github.com/shellspec/shellspec/compare/0.24.3...0.25.0
|
||||
[0.24.3]: https://github.com/shellspec/shellspec/compare/0.24.2...0.24.3
|
||||
[0.24.2]: https://github.com/shellspec/shellspec/compare/0.24.1...0.24.2
|
||||
[0.24.1]: https://github.com/shellspec/shellspec/compare/0.24.0...0.24.1
|
||||
[0.24.0]: https://github.com/shellspec/shellspec/compare/0.23.0...0.24.0
|
||||
[0.23.0]: https://github.com/shellspec/shellspec/compare/0.22.0...0.23.0
|
||||
[0.22.0]: https://github.com/shellspec/shellspec/compare/0.21.0...0.22.0
|
||||
[0.21.0]: https://github.com/shellspec/shellspec/compare/0.20.2...0.21.0
|
||||
[0.20.2]: https://github.com/shellspec/shellspec/compare/0.20.1...0.20.2
|
||||
[0.20.1]: https://github.com/shellspec/shellspec/compare/0.20.0...0.20.1
|
||||
[0.20.0]: https://github.com/shellspec/shellspec/compare/0.19.0...0.20.0
|
||||
[0.19.1]: https://github.com/shellspec/shellspec/compare/0.19.0...0.19.1
|
||||
[0.19.0]: https://github.com/shellspec/shellspec/compare/0.18.0...0.19.0
|
||||
[0.18.0]: https://github.com/shellspec/shellspec/compare/0.17.0...0.18.0
|
||||
[0.17.0]: https://github.com/shellspec/shellspec/compare/0.16.0...0.17.0
|
||||
[0.16.0]: https://github.com/shellspec/shellspec/compare/0.15.0...0.16.0
|
||||
[0.15.0]: https://github.com/shellspec/shellspec/compare/0.14.0...0.15.0
|
||||
[0.14.0]: https://github.com/shellspec/shellspec/compare/0.13.1...0.14.0
|
||||
[0.13.1]: https://github.com/shellspec/shellspec/compare/0.13.0...0.13.1
|
||||
[0.13.0]: https://github.com/shellspec/shellspec/compare/0.12.0...0.13.0
|
||||
[0.12.0]: https://github.com/shellspec/shellspec/compare/0.11.3...0.12.0
|
||||
[0.11.3]: https://github.com/shellspec/shellspec/compare/0.11.2...0.11.3
|
||||
[0.11.2]: https://github.com/shellspec/shellspec/compare/0.11.1...0.11.2
|
||||
[0.11.1]: https://github.com/shellspec/shellspec/compare/0.11.0...0.11.1
|
||||
[0.11.0]: https://github.com/shellspec/shellspec/compare/0.10.0...0.11.0
|
||||
[0.10.0]: https://github.com/shellspec/shellspec/compare/0.9.0...0.10.0
|
||||
[0.9.0]: https://github.com/shellspec/shellspec/compare/0.8.0...0.9.0
|
||||
[0.8.0]: https://github.com/shellspec/shellspec/compare/0.7.0...0.8.0
|
||||
[0.7.0]: https://github.com/shellspec/shellspec/compare/0.6.0...0.7.0
|
||||
[0.6.0]: https://github.com/shellspec/shellspec/compare/0.5.0...0.6.0
|
||||
[0.5.0]: https://github.com/shellspec/shellspec/commits/0.5.0
|
||||
16
tests/shellspec/.vendor/shellspec-0.28.1/CONTRIBUTING.md
Normal file
16
tests/shellspec/.vendor/shellspec-0.28.1/CONTRIBUTING.md
Normal file
@ -0,0 +1,16 @@
|
||||
# CONTRIBUTING
|
||||
|
||||
## For developer
|
||||
|
||||
1. To understand the [architecture](docs/architecture.md)
|
||||
2. About [reporter](docs/reporter.md)
|
||||
3. About various [shells](docs/shells.md)
|
||||
4. How to [test](docs/test.md)
|
||||
|
||||
### About specfile translation process
|
||||
|
||||
The specfile is a valid shell script, but a translation process is performed to implement the scope,
|
||||
line number etc. Each example group block and example block is translated to commands in a subshell.
|
||||
Therefore changes inside those blocks do not affect the outside of the block. In other words it realizes
|
||||
local variables and local functions in the specfile. This is very useful for describing a structured spec.
|
||||
If you are interested in how to translate, use the `--translate` option.
|
||||
21
tests/shellspec/.vendor/shellspec-0.28.1/LICENSE
Normal file
21
tests/shellspec/.vendor/shellspec-0.28.1/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Koichi Nakashima
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
66
tests/shellspec/.vendor/shellspec-0.28.1/Makefile
Normal file
66
tests/shellspec/.vendor/shellspec-0.28.1/Makefile
Normal file
@ -0,0 +1,66 @@
|
||||
PREFIX ?= /usr/local
|
||||
BINDIR := $(PREFIX)/bin
|
||||
LIBDIR := $(PREFIX)/lib
|
||||
|
||||
GETOPTIONSCLI := getoptions-cli --indent=2 --shellcheck
|
||||
OPTPARSERDIR := lib/libexec/optparser
|
||||
|
||||
.PHONY: coverage test dist build release
|
||||
|
||||
all: test check
|
||||
|
||||
dist: LICENSE shellspec lib libexec
|
||||
tar -czf shellspec-dist.tar.gz $^ --transform 's,^,shellspec/,'
|
||||
|
||||
install:
|
||||
install -d "$(BINDIR)" "$(LIBDIR)"
|
||||
install stub/shellspec "$(BINDIR)/shellspec"
|
||||
find lib libexec -type d -exec install -d "$(LIBDIR)/shellspec/{}" \;
|
||||
find LICENSE lib -type f -exec install -m 644 {} "$(LIBDIR)/shellspec/{}" \;
|
||||
find shellspec libexec -type f -exec install {} "$(LIBDIR)/shellspec/{}" \;
|
||||
|
||||
uninstall:
|
||||
rm -rf "$(BINDIR)/shellspec" "$(LIBDIR)/shellspec"
|
||||
|
||||
package:
|
||||
contrib/make_package_json.sh > package.json
|
||||
|
||||
optparser:
|
||||
@printf "getoptions: "
|
||||
@$(GETOPTIONSCLI) --version
|
||||
$(GETOPTIONSCLI) $(OPTPARSERDIR)/parser_definition.sh \
|
||||
optparser_parse SHELLSPEC optparser_error \
|
||||
> $(OPTPARSERDIR)/parser_definition_generated.sh
|
||||
|
||||
demo:
|
||||
ttyrec -e "ghostplay contrib/demo.sh"
|
||||
seq2gif -l 5000 -h 32 -w 139 -p win -i ttyrecord -o docs/demo.gif
|
||||
gifsicle -i docs/demo.gif -O3 -o docs/demo.gif
|
||||
|
||||
coverage:
|
||||
contrib/coverage.sh --pull
|
||||
|
||||
check:
|
||||
contrib/check.sh --pull
|
||||
|
||||
metrics:
|
||||
contrib/metrics.sh
|
||||
|
||||
build:
|
||||
contrib/build.sh .dockerhub/Dockerfile shellspec
|
||||
contrib/build.sh .dockerhub/Dockerfile shellspec kcov
|
||||
contrib/build.sh .dockerhub/Dockerfile.debian shellspec-debian
|
||||
contrib/build.sh .dockerhub/Dockerfile.debian shellspec-debian kcov
|
||||
contrib/build.sh .dockerhub/Dockerfile.scratch shellspec-scratch
|
||||
|
||||
test:
|
||||
./shellspec
|
||||
|
||||
test_all:
|
||||
contrib/all.sh shellspec
|
||||
|
||||
test_in_docker:
|
||||
contrib/test_in_docker.sh --pull dockerfiles/* -- shellspec -j 2
|
||||
|
||||
release:
|
||||
contrib/release.sh
|
||||
2122
tests/shellspec/.vendor/shellspec-0.28.1/README.md
Normal file
2122
tests/shellspec/.vendor/shellspec-0.28.1/README.md
Normal file
File diff suppressed because it is too large
Load Diff
1
tests/shellspec/.vendor/shellspec-0.28.1/bin/shellspec
Symbolic link
1
tests/shellspec/.vendor/shellspec-0.28.1/bin/shellspec
Symbolic link
@ -0,0 +1 @@
|
||||
../shellspec
|
||||
67
tests/shellspec/.vendor/shellspec-0.28.1/contrib/all.sh
Executable file
67
tests/shellspec/.vendor/shellspec-0.28.1/contrib/all.sh
Executable file
@ -0,0 +1,67 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Run in all shells
|
||||
|
||||
# This script is for development purposes.
|
||||
# It provide as is, do not any support.
|
||||
# It may change without notice.
|
||||
|
||||
# Example of use
|
||||
# contrib/all.sh
|
||||
# contrib/all.sh shellspec example/addition_spec.sh
|
||||
# contrib/all.sh -c 'echo ok'
|
||||
|
||||
set -eu
|
||||
|
||||
: "${TARGET:=sh,ash,dash,bash,zsh,pdksh,ksh,ksh93,mksh,oksh,yash,posh,busybox ash}"
|
||||
|
||||
readlinkf() {
|
||||
[ ${1:+x} ] || return 1; p=$1; until [ "${p%/}" = "$p" ]; do p=${p%/}; done
|
||||
[ -e "$p" ] && p=$1; [ -d "$1" ] && p=$p/; set 10 "$PWD" "${OLDPWD:-}"
|
||||
CDPATH="" cd -L "$2" && while [ "$1" -gt 0 ]; do set "$1" "$2" "$3" "${p%/*}"
|
||||
[ "$p" = "$4" ] || { CDPATH="" cd -L "${4:-/}" || break; p=${p##*/}; }
|
||||
[ ! -L "$p" ] && p=${PWD%/}${p:+/}$p && set "$@" "${p:-/}" && break
|
||||
set $(($1-1)) "$2" "$3" "$p"; p=$(ls -dl "$p") || break; p=${p#*" $4 -> "}
|
||||
done 2>/dev/null; cd -L "$2" && OLDPWD=$3 && [ ${5+x} ] && printf '%s\n' "$5"
|
||||
}
|
||||
|
||||
each_shells() {
|
||||
callback=$1 IFS=,
|
||||
shift
|
||||
for shell in $TARGET; do
|
||||
shell_path='' real_path=''
|
||||
# shellcheck disable=SC2230
|
||||
shell_path=$(which "${shell%% *}" 2>/dev/null) || shell_path=''
|
||||
[ -L "${shell_path%% *}" ] && real_path=$(readlinkf "${shell_path%% *}")
|
||||
$callback "$@"
|
||||
done
|
||||
}
|
||||
|
||||
info() {
|
||||
info=$shell_path
|
||||
[ "$info" ] && info="$info${real_path:+ -> }$real_path"
|
||||
printf '%8s : %s\n' "${shell%% *}" "${info:-----}"
|
||||
}
|
||||
|
||||
run() {
|
||||
if [ "$shell_path" ]; then
|
||||
echo "--------------------------------------------------"
|
||||
echo "$shell : $shell_path${real_path:+ -> }$real_path"
|
||||
echo "$shell" "$@"
|
||||
echo "--------------------------------------------------"
|
||||
eval "SH=\$shell $shell \"\$@\""
|
||||
else
|
||||
echo "--------------------------------------------------"
|
||||
echo "$shell : Skip, shell not found"
|
||||
echo "--------------------------------------------------"
|
||||
echo
|
||||
fi
|
||||
}
|
||||
|
||||
uname -a
|
||||
echo "=================================================="
|
||||
( each_shells info )
|
||||
echo "=================================================="
|
||||
if [ $# -gt 0 ]; then
|
||||
( each_shells run "$@" )
|
||||
fi
|
||||
409
tests/shellspec/.vendor/shellspec-0.28.1/contrib/bugs.sh
Executable file
409
tests/shellspec/.vendor/shellspec-0.28.1/contrib/bugs.sh
Executable file
@ -0,0 +1,409 @@
|
||||
#!/bin/sh
|
||||
# shellcheck disable=SC2004,SC2015,SC2016,SC2034,SC2086,SC2091,SC2123,SC2181,SC2194
|
||||
|
||||
# Bugs and compatibility check for shell
|
||||
|
||||
# This script is for development purposes.
|
||||
# It provide as is, do not any support.
|
||||
# It may change without notice.
|
||||
|
||||
# Example of use
|
||||
# contrib/bugs.sh
|
||||
# bash contrib/bugs.sh
|
||||
# contrib/test_in_docker.sh [Dockerfile] -- bash contrib/bugs.sh
|
||||
|
||||
affect() { echo "[affect] $title"; }
|
||||
no_problem() { echo "[------] $title"; }
|
||||
skip() { echo "[skip ] $title [skip reason: $1]"; }
|
||||
|
||||
if { file=$(mktemp -t tmp.XXXXXX); } 2>/dev/null; then
|
||||
maketemp() { mktemp -t tmp.XXXXXX; }
|
||||
rm "$file"
|
||||
else
|
||||
maketemp() { mktemp tmp.XXXXXX; }
|
||||
fi
|
||||
|
||||
(
|
||||
title="01: set -e option is reset (posh)"
|
||||
set -eu
|
||||
foo() { eval 'return 0'; }
|
||||
foo
|
||||
case $- in
|
||||
*e*) no_problem ;;
|
||||
*) affect ;;
|
||||
esac
|
||||
)
|
||||
|
||||
(
|
||||
title="02: double quoted string treated as a pattern (posh)"
|
||||
string="abc[d]"
|
||||
pattern="c[d]"
|
||||
case $string in
|
||||
*"$pattern"*) no_problem ;;
|
||||
*) affect ;;
|
||||
esac
|
||||
)
|
||||
|
||||
(
|
||||
title="03: @: parameter not set (posh, ksh <= around 93s)"
|
||||
if (set -u; : "$@") 2>/dev/null; then no_problem; else affect; fi
|
||||
)
|
||||
|
||||
return_true() { false; }
|
||||
(
|
||||
title="04: function not overrite (ksh)"
|
||||
return_true() { true; }
|
||||
if return_true; then no_problem; else affect; fi
|
||||
)
|
||||
|
||||
(
|
||||
title="05: exit not return exit code (zsh <= around 4.2.5)"
|
||||
foo() { (exit 123) &&:; }; foo
|
||||
if [ $? -eq 123 ]; then no_problem; else affect; fi
|
||||
)
|
||||
|
||||
(
|
||||
title="06: abort if unset not the defined variable (bash <= around 2.05a, zsh <= around 4.2.5, ksh <= around 93s)"
|
||||
ok=$(
|
||||
set -e
|
||||
unset not_defined_variable
|
||||
echo 1
|
||||
)
|
||||
if [ "$ok" ]; then no_problem; else affect; fi
|
||||
)
|
||||
|
||||
(
|
||||
title="07: limited arithmetic expansion (dash <= around 0.5.4, old ash)"
|
||||
i=0
|
||||
ok=$(eval 'i=$((i+1))' 2>/dev/null; echo 1)
|
||||
if [ "$ok" ]; then no_problem; else affect; fi
|
||||
)
|
||||
|
||||
(
|
||||
title="08: Unsupported trap (posh: around 0.8.5)"
|
||||
if (trap '' INT) 2>/dev/null; then no_problem; else affect; fi
|
||||
)
|
||||
|
||||
(
|
||||
title="09: different split by IFS (zsh, posh <= around 0.6.13)"
|
||||
[ "${ZSH_VERSION:-}" ] && emulate -R sh
|
||||
string="1,2,"
|
||||
IFS=','
|
||||
set -- $string
|
||||
if [ $# -eq 2 ]; then no_problem; else affect; fi
|
||||
)
|
||||
|
||||
(
|
||||
title="10: variable reference in the same line (dash <= around 0.5.5)"
|
||||
i=1
|
||||
i=$(($i+1)) j=$i
|
||||
if [ "$j" -eq 2 ]; then no_problem; else affect; fi
|
||||
)
|
||||
|
||||
(
|
||||
title="11: command time -p output LF at first (solaris)"
|
||||
if (command time echo) >/dev/null 2>/dev/null; then
|
||||
command time -p printf '' 2>&1 | {
|
||||
IFS= read -r line
|
||||
if [ "$line" ]; then no_problem; else affect; fi
|
||||
}
|
||||
else
|
||||
skip 'time command not found'
|
||||
fi
|
||||
)
|
||||
|
||||
(
|
||||
title="12: cat not ignore set -e (zsh = around 5.4.2)"
|
||||
(
|
||||
set -e
|
||||
nagative() { false; }
|
||||
if false; then :; else nagative && : || :; fi
|
||||
)
|
||||
[ $? -eq 0 ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title="13: many unset cause a Segmentation fault (mksh = around 39)"
|
||||
(
|
||||
i=0
|
||||
while [ $i -lt 30000 ]; do
|
||||
unset v ||:
|
||||
i=$(($i+1))
|
||||
done
|
||||
) 2>/dev/null
|
||||
[ $? -eq 0 ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title="14: here document does not expand parameters (ash = around 0.3.8)"
|
||||
set -- value
|
||||
foo() { cat; }
|
||||
result=$(foo<<HERE
|
||||
$1
|
||||
HERE
|
||||
)
|
||||
[ "$result" = value ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title="15: glob not working (posh <= around 0.12.6)"
|
||||
files=$(echo "/"*)
|
||||
[ "$files" != "/*" ] && no_problem || affect
|
||||
)
|
||||
(
|
||||
title="16: 'command' can not prevent error (bash = 2.03)"
|
||||
foo() {
|
||||
set -e
|
||||
command false &&:
|
||||
echo ok
|
||||
}
|
||||
ret=$(foo)
|
||||
[ "$ret" = "ok" ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title="17: can not return within eval (posh = around 2.36)"
|
||||
foo() {
|
||||
eval 'return 0'
|
||||
return 1
|
||||
}
|
||||
foo &&:
|
||||
[ $? -eq 0 ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title="18: do not glob with set -u (posh = around 0.10.2)"
|
||||
set -u
|
||||
[ "$(echo /*)" != "/*" ]
|
||||
[ $? -eq 0 ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='19: can not get $POSH_VERSION (posh = around 0.8.5)'
|
||||
if [ "${POSH_VERSION:-}" ]; then
|
||||
[ "$POSH_VERSION" != "POSH_VERSION" ]
|
||||
[ $? -eq 0 ] && no_problem || affect
|
||||
else
|
||||
skip 'this shell is not posh'
|
||||
fi
|
||||
)
|
||||
|
||||
(
|
||||
title='20: do not remove leading space when read with one arguments (yash = around 2.36)'
|
||||
IFS=' '
|
||||
read -r line<<HERE
|
||||
line
|
||||
HERE
|
||||
[ "$line" = "line" ]
|
||||
[ $? -eq 0 ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='21: cat not ignore set -e with eval (pdksh = around 5.2.14 on debian 3.0)'
|
||||
foo() {
|
||||
set -e
|
||||
bar() {
|
||||
eval "false"
|
||||
echo ok
|
||||
}
|
||||
bar ||:
|
||||
}
|
||||
ret=$(foo)
|
||||
[ "$ret" = "ok" ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='22: internal error: j_async: bad nzombie (0) (posh = around 0.6.13)'
|
||||
file=$(maketemp)
|
||||
(
|
||||
sleep 0 &
|
||||
wait $!
|
||||
) 2>"$file"
|
||||
ret=$(cat "$file")
|
||||
rm "$file"
|
||||
|
||||
case $ret in
|
||||
*bad\ nzombie*) affect ;;
|
||||
*) no_problem ;;
|
||||
esac
|
||||
)
|
||||
|
||||
(
|
||||
title='23: can not read after reading null character (yash = around 2.46)'
|
||||
file=$(maketemp)
|
||||
printf 'foo\0bar' > "$file"
|
||||
IFS= read -r ret < "$file"
|
||||
IFS= read -r ret <<HERE
|
||||
AAA
|
||||
HERE
|
||||
rm "$file"
|
||||
[ "$ret" ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='24: variable expansion not working with the positional parameter (posh, pdksh)'
|
||||
set -- 'foobar' 'bar'
|
||||
[ "${1%$2}" = "foo" ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='25: printf can not handle octal numbers correctly (old pdksh, zsh <= around 4.0.4)'
|
||||
# zsh 4.2.5: ch=\101
|
||||
# pdksh on debian 3.0: \1: invalid escape
|
||||
ch=$(printf "\101" 2>/dev/null) ||:
|
||||
[ "$ch" = "A" ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='26: Segmentation fault in eval (ksh 93q, 93r)'
|
||||
(
|
||||
(
|
||||
str="" i=0
|
||||
step1() {
|
||||
if (eval ':' 2>/dev/null); then :; fi
|
||||
return 0
|
||||
}
|
||||
step2() { set --; eval "$(:)"; }
|
||||
step3() { eval "str=\${str#}"; }
|
||||
step1
|
||||
step2
|
||||
while [ $i -lt 100 ]; do
|
||||
step3 # 10 Segmentation fault "$@
|
||||
i=$(($i+1))
|
||||
done
|
||||
) &
|
||||
wait $! # wait is not related this bug, it just prevent fail.
|
||||
) 2>/dev/null
|
||||
[ $? = 0 ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='27: set -C not working (posh = around 0.10.2)'
|
||||
file=$(maketemp)
|
||||
(set -C; : > "$file") 2>/dev/null &&:
|
||||
ret=$?
|
||||
rm "$file"
|
||||
[ $ret -ne 0 ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='28: variable expansion not working within the double qoute (posh >= 0.8.5)'
|
||||
a='foobar' b='bar'
|
||||
[ "${a%"$b"*}" = "foo" ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='29: case will be aborted when exit status is error (mksh <= 35.2, pdksh 5.2.14 on debian 2.2)'
|
||||
foo() { set -e; case 1 in (*) false &&: ;; esac; echo ok; }
|
||||
ret=$(foo)
|
||||
[ "$ret" = "ok" ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='30: eval interpret invalid -- option (posh = around 0.3.14)'
|
||||
ret=$(eval echo -- foo)
|
||||
[ "$ret" = "-- foo" ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='31: ${v%%=*} not working (zsh <= around 4.3.17)'
|
||||
kv="key=value"
|
||||
(ret="${kv%%=*}"; [ "$ret" = "key" ]) 2>/dev/null &&:
|
||||
[ $? = 0 ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='32: last readonly always display "is read only" in subshell (ksh 93q, 93r)'
|
||||
(
|
||||
# readonly A # => not display
|
||||
# readonly B # => display "B is read only"
|
||||
readonly A; (readonly B) 2>/dev/null
|
||||
[ $? = 0 ] && no_problem || affect
|
||||
) &&:
|
||||
) 2>/dev/null
|
||||
|
||||
(
|
||||
title='33: fails when use readonly with value (pdksh 5.2.14 on debian 2.2)'
|
||||
message=$( ( readonly value=123 ) 2>&1 )
|
||||
[ "$message" ] && affect || no_problem
|
||||
)
|
||||
|
||||
(
|
||||
title='34: built-in commands can not redefine (busybox = around 1.1.3)'
|
||||
whoami() { echo nobody; }
|
||||
[ "$(whoami)" = nobody ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='35: exit status is not 127 when command not found (zsh <= around 4.0.4)'
|
||||
no-such-command 2>/dev/null &&:
|
||||
[ $? = 127 ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='36: exit status is not 127 when command not found and PATH='' (bash <= 4.3)'
|
||||
no-such-command 2>/dev/null &&:
|
||||
if [ $? = 1 ]; then
|
||||
skip 'affected #35'
|
||||
else
|
||||
set -e
|
||||
PATH=''
|
||||
no-such-command 2>/dev/null &&:
|
||||
[ $? = 127 ] && no_problem || affect
|
||||
fi
|
||||
)
|
||||
|
||||
(
|
||||
title='37: wrong parse command substitution (bosh/posh = 20181030,20190311)'
|
||||
$(
|
||||
cat << HERE
|
||||
HERE
|
||||
)
|
||||
ret=$( printf a; printf b )
|
||||
[ "$ret" = "ab" ] && no_problem || affect
|
||||
)
|
||||
|
||||
(
|
||||
title='38: Freeze in pipe processing (bosh/posh = 20181030,20190311)'
|
||||
|
||||
printf '1\n2\n' | cat | while read -r line; do
|
||||
# /usr/bin/printf '%s' "$line" # freeze
|
||||
printf '%s' "$line" # not freeze
|
||||
done > /dev/null
|
||||
|
||||
[ -e /usr/bin/printf ] && printf=/usr/bin/printf || printf=/bin/printf
|
||||
|
||||
file=$(maketemp)
|
||||
# Code for detection. Output one line only.
|
||||
{ echo 1; echo 2; } | {
|
||||
while IFS= read -r line; do
|
||||
echo "$line"
|
||||
done | cat | while read -r line; do
|
||||
$printf '%s' "$line"
|
||||
done
|
||||
} > $file
|
||||
ret=$(cat "$file")
|
||||
rm "$file"
|
||||
[ "$ret" = "1" ] && affect || no_problem
|
||||
)
|
||||
|
||||
(
|
||||
title='39: can not set -e options with eval (pdksh, mksh, posh)'
|
||||
set -e
|
||||
eval "set +e"
|
||||
case $- in
|
||||
*e*) affect ;;
|
||||
*) no_problem ;;
|
||||
esac
|
||||
)
|
||||
|
||||
(
|
||||
title='40: can not return exit status from subshell (bash 4.1.5, 4.2)'
|
||||
ret() { return $1; }
|
||||
foo() { set -e; ret 123; }
|
||||
set +e
|
||||
(foo)
|
||||
[ $? = 123 ] && no_problem || affect
|
||||
)
|
||||
|
||||
echo Done
|
||||
66
tests/shellspec/.vendor/shellspec-0.28.1/contrib/build.sh
Executable file
66
tests/shellspec/.vendor/shellspec-0.28.1/contrib/build.sh
Executable file
@ -0,0 +1,66 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
info() {
|
||||
printf '\033[32m%s\033[0m\n' "$*"
|
||||
}
|
||||
|
||||
if [ -e .env ]; then
|
||||
default_compose_project_name=shellspec
|
||||
while read -r line; do
|
||||
case $line in (COMPOSE_PROJECT_NAME=*)
|
||||
default_compose_project_name=''
|
||||
esac
|
||||
done < .env
|
||||
if [ "$default_compose_project_name" ]; then
|
||||
: "${COMPOSE_PROJECT_NAME:=$default_compose_project_name}"
|
||||
export COMPOSE_PROJECT_NAME
|
||||
fi
|
||||
fi
|
||||
|
||||
target=${3:-}
|
||||
|
||||
export DOCKERFILE_BASE AUTHORS
|
||||
DOCKERFILE_BASE="$(dirname "$1")/"
|
||||
AUTHORS="$(git config user.name) <$(git config user.email)>"
|
||||
|
||||
# Emulate Docker Hub environment variables
|
||||
export DOCKERFILE_PATH DOCKER_TAG IMAGE_NAME SOURCE_COMMIT
|
||||
DOCKERFILE_PATH=$(basename "$1")
|
||||
DOCKER_TAG=${3:-latest}
|
||||
IMAGE_NAME=$2:$DOCKER_TAG
|
||||
SOURCE_COMMIT=$(git rev-parse HEAD)
|
||||
|
||||
test="docker-compose${target:+.}$target.test.yml"
|
||||
docker-compose -f ".dockerhub/$test" up --build --abort-on-container-exit
|
||||
|
||||
case $1 in
|
||||
/*) DOCKERFILE_PATH=$1 ;;
|
||||
*) DOCKERFILE_PATH=$PWD/$1 ;;
|
||||
esac
|
||||
|
||||
cd .dockerhub
|
||||
if [ "$target" ]; then
|
||||
hooks/build --target "$target"
|
||||
else
|
||||
hooks/build
|
||||
fi
|
||||
size=$(docker inspect -f "{{.Size}}" "$IMAGE_NAME")
|
||||
if [ "$size" -le $((1024 * 1024)) ]; then
|
||||
size="$(echo "scale=2; $size / 1024" | bc) KB"
|
||||
else
|
||||
size="$(echo "scale=2; $size / 1024 / 1024" | bc) MB"
|
||||
fi
|
||||
labels=$(
|
||||
#shellcheck disable=SC2016
|
||||
format='{{range $k, $v := .Config.Labels}}{{printf "%s: %s\n" $k $v}}{{end}}'
|
||||
#shellcheck disable=SC2005
|
||||
echo "$(docker inspect -f "$format" "$IMAGE_NAME")"
|
||||
)
|
||||
|
||||
info "============================================================"
|
||||
info "Build succeeded: $IMAGE_NAME (size: $size)"
|
||||
info "------------------------------------------------------------"
|
||||
echo "$labels"
|
||||
info "============================================================"
|
||||
165
tests/shellspec/.vendor/shellspec-0.28.1/contrib/builtins.sh
Executable file
165
tests/shellspec/.vendor/shellspec-0.28.1/contrib/builtins.sh
Executable file
@ -0,0 +1,165 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Detect builtin commands
|
||||
|
||||
# This script is for development purposes.
|
||||
# It provide as is, do not any support.
|
||||
# It may change without notice.
|
||||
|
||||
set -eu
|
||||
|
||||
PATH=":"
|
||||
|
||||
check() {
|
||||
while read -r cmd && cmd=${cmd%% *}; do
|
||||
if type "$cmd" >/dev/null 2>&1; then
|
||||
if [ -x /usr/bin/printf ]; then
|
||||
/usr/bin/printf "%s " "$cmd"
|
||||
else
|
||||
/bin/printf "%s " "$cmd"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo
|
||||
}
|
||||
|
||||
if ! type : >/dev/null 2>&1; then
|
||||
# not implements type (posh)
|
||||
type() {
|
||||
case $1 in (. | exit | type) return 0; esac
|
||||
$1
|
||||
}
|
||||
fi
|
||||
|
||||
check<<COMMANDS
|
||||
. | Special Built-In
|
||||
: | Special Built-In
|
||||
[ | All Shell Built-In
|
||||
alias | Almost Shell Built-In (not built-in: posh)
|
||||
array |
|
||||
autoload |
|
||||
bg | Almost Shell Built-In (not built-in: posh)
|
||||
bind |
|
||||
bindkey |
|
||||
break | Special Built-In
|
||||
builtin |
|
||||
bye |
|
||||
caller |
|
||||
cap |
|
||||
cat | Include Posix Utilities
|
||||
cd | All Shell Built-In
|
||||
chdir |
|
||||
clone |
|
||||
command | All Shell Built-In
|
||||
comparguments |
|
||||
compcall |
|
||||
compctl |
|
||||
compdescribe |
|
||||
compfiles |
|
||||
compgroups |
|
||||
compquote |
|
||||
comptags |
|
||||
comptry |
|
||||
compvalues |
|
||||
compgen |
|
||||
complete |
|
||||
compopt |
|
||||
continue | Special Built-In
|
||||
declare |
|
||||
dirs |
|
||||
disable |
|
||||
disown |
|
||||
echo | All Shell Built-In
|
||||
echotc |
|
||||
echoti |
|
||||
emulate |
|
||||
enable |
|
||||
enum |
|
||||
eval | Special Built-In
|
||||
exec | Special Built-In
|
||||
exit | Special Built-In
|
||||
export | Special Built-In
|
||||
false | All Shell Built-In
|
||||
fc | Include Posix Utilities
|
||||
fg | Almost Shell Built-In (not built-in: posh)
|
||||
float |
|
||||
functions |
|
||||
getcap |
|
||||
getconf | Include Posix Utilities
|
||||
getln |
|
||||
getops | Almost Shell Built-In (not built-in: busybox)
|
||||
global |
|
||||
hash | Include Posix Utilities
|
||||
help |
|
||||
hist |
|
||||
history |
|
||||
integer |
|
||||
jobs | Almost Shell Built-In (not built-in: posh)
|
||||
kill | Almost Shell Built-In (not built-in: old posh)
|
||||
let |
|
||||
limit |
|
||||
local |
|
||||
log |
|
||||
logout |
|
||||
mapfile |
|
||||
mknod |
|
||||
newgrp | Include Posix Utilities
|
||||
noglob |
|
||||
popd |
|
||||
print |
|
||||
printf | Almost Shell Built-In (not built-in: mksh, posh)
|
||||
pushed |
|
||||
pushln |
|
||||
pwd | All Shell Built-In
|
||||
r |
|
||||
read | All Shell Built-In
|
||||
readarray |
|
||||
readonly | Special Built-In
|
||||
realpath |
|
||||
rehash |
|
||||
rename |
|
||||
return | Special Built-In
|
||||
sched |
|
||||
set | Special Built-In
|
||||
setcap |
|
||||
setopt |
|
||||
shift | Special Built-In
|
||||
shopt |
|
||||
sleep | Include Posix Utilities
|
||||
source |
|
||||
stat |
|
||||
suspend |
|
||||
test | All Shell Built-In
|
||||
time | Include Posix Utilities
|
||||
times | Special Built-In
|
||||
trap | Special Built-In
|
||||
true | All Shell Built-In
|
||||
ttyctl |
|
||||
type | Almost Shell Built-In (not built-in: posh)
|
||||
typeset |
|
||||
ulimit | Almost Shell Built-In (not built-in: posh)
|
||||
umask | All Shell Built-In
|
||||
unalias | Almost Shell Built-In (not built-in: posh)
|
||||
unfunction |
|
||||
unhash |
|
||||
unlimit |
|
||||
unset | Special Built-In
|
||||
unsetopt |
|
||||
vared |
|
||||
wait | All Shell Built-In
|
||||
whence |
|
||||
where |
|
||||
which |
|
||||
zcompile |
|
||||
zformat |
|
||||
zftp |
|
||||
zle |
|
||||
zmodload |
|
||||
zparseopts |
|
||||
zprof |
|
||||
zpty |
|
||||
zregexparse |
|
||||
zsocket |
|
||||
zstyle |
|
||||
ztcp |
|
||||
COMMANDS
|
||||
83
tests/shellspec/.vendor/shellspec-0.28.1/contrib/check.sh
Executable file
83
tests/shellspec/.vendor/shellspec-0.28.1/contrib/check.sh
Executable file
@ -0,0 +1,83 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Check shell script files
|
||||
|
||||
# This script is for development purposes.
|
||||
# It provide as is, do not any support.
|
||||
# It may change without notice.
|
||||
|
||||
# Example of use
|
||||
# contrib/check.sh
|
||||
|
||||
set -eu
|
||||
|
||||
[ "${1:-}" = "--pull" ] && PULL=1 || PULL=""
|
||||
|
||||
sources() {
|
||||
echo shellspec
|
||||
echo install.sh
|
||||
find lib libexec -name '*.sh'
|
||||
}
|
||||
|
||||
helpers() {
|
||||
find helper -name '*.sh'
|
||||
}
|
||||
|
||||
specs() {
|
||||
find spec -name '*.sh'
|
||||
}
|
||||
|
||||
examples() {
|
||||
find examples -name '*.sh'
|
||||
}
|
||||
|
||||
count() {
|
||||
printf '%7s: ' "$1"
|
||||
shift
|
||||
cat "$@" | wc -lc | {
|
||||
read -r lines bytes
|
||||
printf '%3s files, %5s lines, %3s KiB\n' $# "$lines" $((bytes / 1024))
|
||||
}
|
||||
}
|
||||
|
||||
echo ' # lines bytes name'
|
||||
wc -lc $(sources; helpers; specs; examples) | nl | sed '$d'
|
||||
echo
|
||||
|
||||
count source $(sources)
|
||||
count helper $(helpers)
|
||||
count spec $(specs)
|
||||
count example $(examples)
|
||||
count total $(sources; helpers; specs; examples)
|
||||
echo
|
||||
|
||||
echo "Checking package.json..."
|
||||
|
||||
contrib/make_package_json.sh | diff -u package.json - &&:
|
||||
package_json_status=$?
|
||||
[ "$package_json_status" -eq 0 ] && echo "ok"
|
||||
echo
|
||||
|
||||
if ! docker --version >/dev/null 2>&1; then
|
||||
echo "You need docker to run shellcheck" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Checking scripts by shellcheck..."
|
||||
|
||||
tag="shellspec:shellcheck"
|
||||
|
||||
trap 'exit 1' INT
|
||||
trap 'docker rmi "$tag" >/dev/null 2>&1' EXIT
|
||||
|
||||
# Do not use volume because can not be used on VolFs(lxfs) of WSL.
|
||||
shellcheck_version=$(cat .shellcheck-version)
|
||||
set -- -t "$tag" --build-arg "VERSION=$shellcheck_version"
|
||||
[ "$PULL" ] && set -- "$@" --pull
|
||||
docker build "$@" -f dockerfiles/.shellcheck .
|
||||
docker run -i --rm "$tag" shellcheck --version
|
||||
docker run -i --rm "$tag" shellcheck -C $(sources; helpers; specs; examples)
|
||||
|
||||
[ "$package_json_status" -ne 0 ] && exit "$package_json_status"
|
||||
|
||||
echo "ok"
|
||||
52
tests/shellspec/.vendor/shellspec-0.28.1/contrib/demo.sh
Executable file
52
tests/shellspec/.vendor/shellspec-0.28.1/contrib/demo.sh
Executable file
@ -0,0 +1,52 @@
|
||||
#!/bin/sh
|
||||
|
||||
#ghostplay silent
|
||||
# ttyrec -e "ghostplay contrib/demo.sh"
|
||||
# seq2gif -l 5000 -h 32 -w 139 -p win -i ttyrecord -o demo.gif
|
||||
# seq2gif -l 5000 -h 19 -w 83 -p win -i ttyrecord -o sns.gif
|
||||
GP_HOSTNAME=ubuntu
|
||||
highlight() {
|
||||
command highlight -l -O xterm256 --syntax "$1"
|
||||
}
|
||||
#ghostplay end
|
||||
|
||||
shellspec
|
||||
|
||||
#ghostplay sleep 3
|
||||
|
||||
# Parallel execution
|
||||
shellspec --jobs 4
|
||||
|
||||
#ghostplay sleep 3
|
||||
|
||||
cd contrib/demo
|
||||
|
||||
#ghostplay sleep 1
|
||||
|
||||
cat spec/demo_spec.sh | highlight sh
|
||||
|
||||
#ghostplay sleep 3
|
||||
|
||||
# It has one failure
|
||||
shellspec
|
||||
|
||||
#ghostplay sleep 5
|
||||
|
||||
# Dry run with documentation formatter
|
||||
shellspec --dry-run --format documentation
|
||||
|
||||
#ghostplay sleep 5
|
||||
|
||||
# Coverage and generate junit xml
|
||||
shellspec --kcov --output junit
|
||||
|
||||
#ghostplay sleep 5
|
||||
|
||||
cat report/results_junit.xml | highlight xml
|
||||
|
||||
#ghostplay sleep 3
|
||||
|
||||
cd profile
|
||||
|
||||
# Profiler
|
||||
shellspec --profile --format documentation
|
||||
@ -0,0 +1 @@
|
||||
--require spec_helper
|
||||
@ -0,0 +1,15 @@
|
||||
add() {
|
||||
echo $(($1 * $2)) # bug: should be '+'
|
||||
}
|
||||
|
||||
sub() {
|
||||
echo $(($1 - $2))
|
||||
}
|
||||
|
||||
mul() {
|
||||
echo $(($1 * $2))
|
||||
}
|
||||
|
||||
div() {
|
||||
echo $(($1 / $2))
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
--require spec_helper
|
||||
# --kcov-common-options "--path-strip-level=1 --include-path=. --include-pattern=.sh --exclude-pattern=/spec/,/coverage/,/report/"
|
||||
@ -0,0 +1,26 @@
|
||||
Describe "Profiler example"
|
||||
Example "1: sleep 0.1 (line 2)"
|
||||
When call sleep 0.1
|
||||
The status should be success
|
||||
End
|
||||
|
||||
Example "2: sleep 0.4 (line 7)"
|
||||
When call sleep 0.4
|
||||
The status should be success
|
||||
End
|
||||
|
||||
Example "3: sleep 0.3 (line 12)"
|
||||
When call sleep 0.3
|
||||
The status should be success
|
||||
End
|
||||
|
||||
Example "4: sleep 0.2 (line 17)"
|
||||
When call sleep 0.2
|
||||
The status should be success
|
||||
End
|
||||
|
||||
Example "5: sleep 0.5 (line 22)"
|
||||
When call sleep 0.5
|
||||
The status should be success
|
||||
End
|
||||
End
|
||||
@ -0,0 +1,14 @@
|
||||
#shellcheck shell=sh
|
||||
|
||||
# set -eu
|
||||
|
||||
# shellspec_redefinable function_name
|
||||
#
|
||||
# shellspec_redefinable is workaround for ksh (Version AJM 93u+ 2012-08-01)
|
||||
# ksh can not redefine existing function in some cases inside of sub shell.
|
||||
# If you have trouble in redefine function on ksh, try using shellspec_redefinable.
|
||||
|
||||
shellspec_spec_helper_configure() {
|
||||
# shellspec_import 'support/custom_matcher'
|
||||
:
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
Describe 'example'
|
||||
Describe 'bc command'
|
||||
It 'performs addition'
|
||||
Data '2 + 3'
|
||||
When call bc
|
||||
The output should eq 5
|
||||
End
|
||||
End
|
||||
|
||||
Describe 'add() function'
|
||||
Include ./mylib.sh # add() function defined
|
||||
It 'performs addition'
|
||||
When call add 2 3
|
||||
The output should eq 5
|
||||
End
|
||||
End
|
||||
End
|
||||
@ -0,0 +1,10 @@
|
||||
#shellcheck shell=sh
|
||||
|
||||
# set -eu
|
||||
|
||||
# shellspec_redefinable function_name
|
||||
|
||||
shellspec_spec_helper_configure() {
|
||||
# shellspec_import 'support/custom_matcher'
|
||||
:
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
FROM alpine
|
||||
RUN apk add --no-cache gcc libc-dev
|
||||
ADD https://github.com/ncopa/su-exec/archive/v0.2.tar.gz /
|
||||
COPY ./src/ ./src
|
||||
RUN gcc --static ./src/mksock.c -o /usr/local/bin/mksock \
|
||||
&& gcc --static ./src/invokesh.c -o /usr/local/bin/invokesh \
|
||||
&& cp ./src/fake-nc.sh /usr/local/bin/nc \
|
||||
&& tar xzf v0.2.tar.gz \
|
||||
&& gcc -static /su-exec-0.2/su-exec.c -o /usr/local/bin/su-exec \
|
||||
&& chmod ug+s /usr/local/bin/su-exec
|
||||
9
tests/shellspec/.vendor/shellspec-0.28.1/contrib/helpers/src/fake-nc.sh
Executable file
9
tests/shellspec/.vendor/shellspec-0.28.1/contrib/helpers/src/fake-nc.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
for i in "$@"; do
|
||||
shift
|
||||
case $i in (-*) continue; esac
|
||||
set -- "$@" "$i"
|
||||
done
|
||||
|
||||
mksock "$@"
|
||||
@ -0,0 +1,33 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define max_size 256
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *fp;
|
||||
if ((fp = fopen("/etc/invokesh.conf", "r")) == NULL) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
char bin[max_size];
|
||||
if ( fgets(bin, max_size, fp) == NULL ) {
|
||||
fclose(fp);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
char *newline;
|
||||
if ((newline = strchr(bin, '\n')) != NULL) {
|
||||
*newline = '\0';
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
argv[0] = bin;
|
||||
execvp(bin, argv);
|
||||
fprintf(stderr, "invokesh: %s: %s\n", bin, strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define UNIX_PATH_MAX 108
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int sock;
|
||||
struct sockaddr_un addr;
|
||||
|
||||
if (argc < 2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, argv[1], UNIX_PATH_MAX);
|
||||
|
||||
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
close(sock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
35
tests/shellspec/.vendor/shellspec-0.28.1/contrib/installer_test.sh
Executable file
35
tests/shellspec/.vendor/shellspec-0.28.1/contrib/installer_test.sh
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Environment for installer test
|
||||
|
||||
# This script is for development purposes.
|
||||
# It provide as is, do not any support.
|
||||
# It may change without notice.
|
||||
|
||||
set -eu
|
||||
|
||||
[ $# -eq 0 ] && set -- general
|
||||
|
||||
case ${1:-} in ( general | make | bpkg | basher | brew) ;; (*)
|
||||
cat <<'USAGE'
|
||||
Usage: installer_test.sh [ general | make | bpkg | basher | brew]
|
||||
USAGE
|
||||
exit 0
|
||||
esac
|
||||
|
||||
iid='' iidfile=$(mktemp -t shellspec.XXXXXXXX)
|
||||
dockerfile="dockerfiles/.installer-test"
|
||||
|
||||
cleanup() {
|
||||
[ -f "$iidfile" ] && rm "$iidfile"
|
||||
[ "$iid" ] && docker rmi "$iid" > /dev/null
|
||||
}
|
||||
trap 'exit 1' INT
|
||||
trap 'cleanup' EXIT
|
||||
|
||||
docker build --target="${1}_installer" -t "shellspec:${1}_installer" - < "$dockerfile"
|
||||
sleep 5
|
||||
docker build --target=test --build-arg "TYPE=$1" --iidfile "$iidfile" . -f "$dockerfile"
|
||||
iid=$(cat "$iidfile")
|
||||
shift
|
||||
docker run -it --rm "$iid" "$@"
|
||||
25
tests/shellspec/.vendor/shellspec-0.28.1/contrib/make_package_json.sh
Executable file
25
tests/shellspec/.vendor/shellspec-0.28.1/contrib/make_package_json.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
version() {
|
||||
./shellspec --version
|
||||
}
|
||||
|
||||
files() {
|
||||
echo "["
|
||||
files="$(find bin lib libexec \( -type f -o -type l \) -exec echo " \"{}\"," \; | sort)"
|
||||
echo "${files%,}"
|
||||
echo " ]"
|
||||
}
|
||||
|
||||
cat<<JSON
|
||||
{
|
||||
"name": "ShellSpec",
|
||||
"version": "$(version)",
|
||||
"description": "BDD style unit testing framework for POSIX compliant shell script",
|
||||
"homepage": "https://shellspec.info",
|
||||
"scripts": ["shellspec"],
|
||||
"license": "MIT",
|
||||
"files": $(files),
|
||||
"install": "make install"
|
||||
}
|
||||
JSON
|
||||
17
tests/shellspec/.vendor/shellspec-0.28.1/contrib/metrics.sh
Executable file
17
tests/shellspec/.vendor/shellspec-0.28.1/contrib/metrics.sh
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Measure metrics for shell scripts
|
||||
|
||||
# This script is for development purposes.
|
||||
# It provide as is, do not any support.
|
||||
# It may change without notice.
|
||||
|
||||
set -eu
|
||||
|
||||
sources() {
|
||||
echo shellspec
|
||||
echo install.sh
|
||||
find lib libexec helper -name '*.sh'
|
||||
}
|
||||
|
||||
shellmetrics $(sources)
|
||||
15
tests/shellspec/.vendor/shellspec-0.28.1/contrib/pretty.sh
Executable file
15
tests/shellspec/.vendor/shellspec-0.28.1/contrib/pretty.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Shell script beautify tool
|
||||
|
||||
# This script is for development purposes.
|
||||
# It provide as is, do not any support.
|
||||
# It may change without notice.
|
||||
|
||||
# Example of use
|
||||
# cat example.sh | contrib/pretty.sh
|
||||
|
||||
eval "__dummy__() {
|
||||
$(cat -)
|
||||
}"
|
||||
typeset -f __dummy__ | sed -E 's/( *)function /\1/; s/;$//'
|
||||
30
tests/shellspec/.vendor/shellspec-0.28.1/contrib/release.sh
Executable file
30
tests/shellspec/.vendor/shellspec-0.28.1/contrib/release.sh
Executable file
@ -0,0 +1,30 @@
|
||||
#!/bin/sh -eu
|
||||
|
||||
run() {
|
||||
echo "$@"
|
||||
"$@"
|
||||
}
|
||||
|
||||
confirm() {
|
||||
printf "%s [y/N] " "$1"
|
||||
read -r ans
|
||||
case $ans in ([yY] | [yY][eE][sS]) return; esac
|
||||
return 1
|
||||
}
|
||||
|
||||
is_prerelease() {
|
||||
case $1 in (*-*) return; esac
|
||||
return 1
|
||||
}
|
||||
|
||||
version=$(./shellspec --version)
|
||||
|
||||
confirm "Release $version?" || exit 0
|
||||
run git tag -s -a "$version" -m "$version"
|
||||
run git push origin "$version"
|
||||
|
||||
is_prerelease "$version" && exit 0
|
||||
|
||||
confirm "Update $version to latest?" || exit 0
|
||||
run git tag -f latest
|
||||
run git push -f origin latest
|
||||
24
tests/shellspec/.vendor/shellspec-0.28.1/contrib/shellspec-docker
Executable file
24
tests/shellspec/.vendor/shellspec-0.28.1/contrib/shellspec-docker
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/sh -eu
|
||||
|
||||
: "${SHELLSPEC_DOCKER:=shellspec/shellspec}"
|
||||
UID=$(id -u) GID=$(id -g)
|
||||
|
||||
case $(uname -r) in (*Microsoft*)
|
||||
PWD=$(wslpath -wa .)
|
||||
if [ "${PWD##[a-zA-Z]:[\\/]*}" ]; then
|
||||
echo "'$PWD' is not a valid Windows path" >&2
|
||||
exit 1
|
||||
fi
|
||||
esac
|
||||
|
||||
docker_run() {
|
||||
docker run -it --rm --entrypoint=/shellspec-docker "$@"
|
||||
}
|
||||
|
||||
# You can override docker_run() with initrc to changes options,
|
||||
# pass environment variables, etc.
|
||||
if [ -e .shellspec-docker/initrc ]; then
|
||||
. .shellspec-docker/initrc
|
||||
fi
|
||||
|
||||
docker_run -u "$UID:$GID" -v "$PWD:/src" "$SHELLSPEC_DOCKER" "$@"
|
||||
152
tests/shellspec/.vendor/shellspec-0.28.1/contrib/test_in_docker.sh
Executable file
152
tests/shellspec/.vendor/shellspec-0.28.1/contrib/test_in_docker.sh
Executable file
@ -0,0 +1,152 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Run tests in docker
|
||||
|
||||
# This script is for development purposes.
|
||||
# It provide as is, do not any support.
|
||||
# It may change without notice.
|
||||
|
||||
set -eu
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
cat <<'USAGE'
|
||||
Usage: test_in_docker.sh [Dockerfile..] [-- COMMAND]
|
||||
|
||||
Run tests in docker
|
||||
|
||||
Examples
|
||||
contrib/test_in_docker.sh dockerfiles/*
|
||||
contrib/test_in_docker.sh dockerfiles/debian-9-*
|
||||
contrib/test_in_docker.sh dockerfiles/*-o # ends with -o is supported os
|
||||
contrib/test_in_docker.sh dockerfiles/*bash* -- contrib/bugs.sh
|
||||
|
||||
To delete all shellspec images
|
||||
docker rmi $(docker images shellspec -q)
|
||||
USAGE
|
||||
exit 0
|
||||
fi
|
||||
|
||||
LF="
|
||||
"
|
||||
|
||||
failures='' count=0 failures_count=0 total_count=0
|
||||
|
||||
main() {
|
||||
options="" pull='' shift_count=0
|
||||
for arg in "$@"; do
|
||||
shift_count=$((shift_count + 1))
|
||||
case $arg in
|
||||
--) break ;;
|
||||
-*)
|
||||
[ "$arg" = "--pull" ] && pull=1
|
||||
options="${options}${arg} "
|
||||
;;
|
||||
*) total_count=$((total_count + 1))
|
||||
esac
|
||||
done
|
||||
|
||||
cd contrib/helpers
|
||||
docker build ${pull:+--pull} -t shellspec:helpers . | grayout
|
||||
cd "$OLDPWD"
|
||||
|
||||
for arg in "$@"; do
|
||||
shift "$shift_count"
|
||||
shift_count=0
|
||||
case $arg in
|
||||
--) break ;;
|
||||
-*) continue ;;
|
||||
esac
|
||||
run "$arg" "$@"
|
||||
done
|
||||
}
|
||||
|
||||
finished() {
|
||||
if [ -f "$iidfile" ]; then
|
||||
rm "$iidfile" ||:
|
||||
fi
|
||||
|
||||
if [ "$failures" ]; then
|
||||
echo >&2
|
||||
echo "Failures:" >&2
|
||||
echo "$failures" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
info() {
|
||||
printf '\033[1;35m%s\033[0m\n' "$*" >&2
|
||||
}
|
||||
|
||||
grayout() {
|
||||
while IFS= read -r line; do
|
||||
printf '\033[1;2;37m\033[90m%s\033[0m\n' "$line" >&2
|
||||
done
|
||||
}
|
||||
|
||||
iidfile=$(mktemp -t shellspec.XXXXXXXX)
|
||||
trap 'finished; exit 1' INT
|
||||
trap 'finished' EXIT
|
||||
|
||||
run() {
|
||||
dockerfile=$1
|
||||
shift
|
||||
|
||||
info "======================================================================"
|
||||
info "$dockerfile:" "$@"
|
||||
count=$((count + 1))
|
||||
os="${dockerfile##*/}"
|
||||
os="${os#.}"
|
||||
os="${os%-!}"
|
||||
image="shellspec:$os"
|
||||
old_image=$(docker images -q --no-trunc "$image")
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
docker build --iidfile "$iidfile" $options - < "$dockerfile" | grayout
|
||||
base_image=$(cat "$iidfile")
|
||||
|
||||
info "Create image from base image: $base_image"
|
||||
docker build --iidfile "$iidfile" -t "$image" --build-arg "IMAGE=$base_image" . -f "dockerfiles/.shellspec" | grayout
|
||||
new_image=$(cat "$iidfile")
|
||||
|
||||
if [ "$old_image" ] && [ "$old_image" != "$new_image" ]; then
|
||||
info "Delete old image $old_image"
|
||||
docker rmi "$old_image" >/dev/null ||:
|
||||
fi
|
||||
info
|
||||
info "Starting $dockerfile:" "$@"
|
||||
info
|
||||
docker run -it --rm "$image" "$@" &&:
|
||||
xs=$?
|
||||
info
|
||||
if [ "$xs" -ne 0 ]; then
|
||||
failures="${failures}- ${os} [$xs]${LF}"
|
||||
failures_count=$((failures_count + 1))
|
||||
fi
|
||||
summary
|
||||
info
|
||||
}
|
||||
|
||||
summary() {
|
||||
[ "$xs" -eq 0 ] && color="\033[32m" || color="\033[31m"
|
||||
[ "$failures_count" -eq 0 ] && fcolor="\033[32m" || fcolor="\033[31m"
|
||||
set -- "$count" "$total_count" "$failures_count"
|
||||
printf "${color}##############################\n\033[m"
|
||||
printf "${color}# exit status: %3d #\n\033[m" "$xs"
|
||||
printf "${color}# ${fcolor}%3d / %3d (failures: %3d)${color} #\n\033[m" "$@"
|
||||
printf "${color}##############################\n\033[m"
|
||||
if [ "$failures" ]; then
|
||||
echo "$failures"
|
||||
fi
|
||||
} >&2
|
||||
|
||||
start=$(date) start_sec=$(date +%s)
|
||||
main "$@"
|
||||
end=$(date) end_sec=$(date +%s)
|
||||
sec=$((end_sec - start_sec))
|
||||
|
||||
echo "$start" >&2
|
||||
echo "$end" >&2
|
||||
echo "Done. $count tests, $sec sec ($((sec / 60)) min)" >&2
|
||||
|
||||
if [ "$failures" ]; then
|
||||
exit 1
|
||||
fi
|
||||
30
tests/shellspec/.vendor/shellspec-0.28.1/contrib/various_test.sh
Executable file
30
tests/shellspec/.vendor/shellspec-0.28.1/contrib/various_test.sh
Executable file
@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
: "${SH:=sh}"
|
||||
|
||||
# Workaround for GitHub Actions (SIGPIPE)
|
||||
# In GitHub Actions, SIGPIPE seems to be set to SIG_IGN and if the process exits
|
||||
# before receiving all STDIN data, it will result in Broken PIPE or I/O will be output
|
||||
head() {
|
||||
command head "$@"
|
||||
cat >/dev/null
|
||||
}
|
||||
|
||||
shellspec() {
|
||||
set -- $SH shellspec --shell "$SH" "$@"
|
||||
echo '$' "$@" >&2
|
||||
"$@"
|
||||
}
|
||||
|
||||
shellspec --banner --output progress --output documentation --output tap --output junit --output failures
|
||||
shellspec --no-banner --skip-message quiet -j 3
|
||||
shellspec --no-banner --skip-message quiet $(shellspec --list specfiles | head -n 5)
|
||||
shellspec --no-banner --skip-message quiet $(shellspec --list examples:lineno | head -n 5)
|
||||
shellspec --no-banner --skip-message quiet spec/general_spec.sh:40:60:80:100
|
||||
shellspec --no-banner --skip-message quiet spec/libexec --profile
|
||||
shellspec --syntax-check
|
||||
shellspec --count
|
||||
shellspec --task
|
||||
shellspec --task hello:shellspec
|
||||
@ -0,0 +1,4 @@
|
||||
FROM debian/eol:woody-slim
|
||||
RUN groupadd user && useradd -m user -g user \
|
||||
&& apt-get update && apt-get -y install ash
|
||||
ENV SH=/bin/ash
|
||||
@ -0,0 +1,5 @@
|
||||
FROM debian/eol:woody-slim
|
||||
RUN groupadd user && useradd -m user -g user \
|
||||
&& apt-get update && apt-get -y install busybox \
|
||||
&& ln -s /bin/busybox /bin/ash
|
||||
ENV SH=/bin/ash
|
||||
@ -0,0 +1,5 @@
|
||||
FROM debian/eol:sarge-slim
|
||||
RUN groupadd user && useradd -m user -g user \
|
||||
&& apt-get update && apt-get -y install busybox-static \
|
||||
&& ln -s /bin/busybox /bin/ash
|
||||
ENV SH=/bin/ash
|
||||
@ -0,0 +1,5 @@
|
||||
FROM debian/eol:sarge-slim
|
||||
ENV DEBIAN_FRONTEND=noninteractive DEBCONF_NOWARNINGS=yes
|
||||
RUN groupadd user && useradd -m user -g user \
|
||||
&& apt-get update && apt-get -y install ksh
|
||||
ENV SH=/bin/ksh
|
||||
@ -0,0 +1,7 @@
|
||||
FROM debian/eol:etch-slim
|
||||
ENV DEBIAN_FRONTEND=noninteractive DEBCONF_NOWARNINGS=yes
|
||||
RUN useradd -m user \
|
||||
&& sed '/updates/s/^/# /' -i /etc/apt/sources.list \
|
||||
&& apt-get update && apt-get -y install busybox \
|
||||
&& /bin/busybox --install -s
|
||||
ENV SH=/bin/ash
|
||||
@ -0,0 +1,6 @@
|
||||
FROM debian/eol:etch-slim
|
||||
ENV DEBIAN_FRONTEND=noninteractive DEBCONF_NOWARNINGS=yes
|
||||
RUN useradd -m user \
|
||||
&& sed '/updates/s/^/# /' -i /etc/apt/sources.list \
|
||||
&& apt-get update && apt-get -y install dash
|
||||
ENV SH=/bin/dash
|
||||
@ -0,0 +1,6 @@
|
||||
FROM debian/eol:etch-slim
|
||||
ENV DEBIAN_FRONTEND=noninteractive DEBCONF_NOWARNINGS=yes
|
||||
RUN useradd -m user \
|
||||
&& sed '/updates/s/^/# /' -i /etc/apt/sources.list \
|
||||
&& apt-get update && apt-get -y install ksh
|
||||
ENV SH=/bin/ksh
|
||||
@ -0,0 +1,6 @@
|
||||
FROM debian/eol:lenny-slim
|
||||
ENV DEBIAN_FRONTEND=noninteractive DEBCONF_NOWARNINGS=yes
|
||||
RUN useradd -m user \
|
||||
&& apt-get update && apt-get -y --force-yes install busybox \
|
||||
&& /bin/busybox --install -s
|
||||
ENV SH=/bin/ash
|
||||
@ -0,0 +1,61 @@
|
||||
ARG TYPE="general"
|
||||
|
||||
FROM alpine as general_installer
|
||||
RUN apk --no-cache add git curl
|
||||
RUN echo 'cd $(dirname $(which _$1)); mv _$1 $1' > /usr/local/bin/enable \
|
||||
&& echo 'cd $(dirname $(which $1)); mv $1 _$1' > /usr/local/bin/disable \
|
||||
&& chmod +x /usr/local/bin/*
|
||||
RUN echo '#!/bin/sh' > /entrypoint.sh \
|
||||
&& echo 'echo You can use enable/disable [COMMAND]' >> /entrypoint.sh \
|
||||
&& echo 'exec "$@"' >> /entrypoint.sh \
|
||||
&& chmod +x /entrypoint.sh
|
||||
ENV PATH $PATH:/root/bin
|
||||
WORKDIR /root
|
||||
ENTRYPOINT [ "/entrypoint.sh" ]
|
||||
CMD [ "/bin/sh" ]
|
||||
|
||||
FROM alpine as make_installer
|
||||
RUN apk --no-cache add make
|
||||
WORKDIR /root/shellspec
|
||||
|
||||
FROM alpine as bpkg_installer
|
||||
RUN apk --no-cache add bash git curl make coreutils
|
||||
RUN curl -sLo- http://get.bpkg.sh | PREFIX=/usr/local bash
|
||||
RUN echo '#!/bin/sh' > /entrypoint.sh \
|
||||
&& echo 'echo Usage: bpkg install shellspec/shellspec' >> /entrypoint.sh \
|
||||
&& echo 'echo Usage: bpkg install shellspec/shellspec@0.19.0' >> /entrypoint.sh \
|
||||
&& echo 'echo Usage: bpkg install shellspec/shellspec -g' >> /entrypoint.sh \
|
||||
&& echo 'exec "$@"' >> /entrypoint.sh \
|
||||
&& chmod +x /entrypoint.sh
|
||||
ENTRYPOINT [ "/entrypoint.sh" ]
|
||||
WORKDIR /root/project
|
||||
CMD [ "/bin/bash", "-l" ]
|
||||
|
||||
FROM alpine as basher_installer
|
||||
RUN apk --no-cache add bash git
|
||||
RUN git clone https://github.com/basherpm/basher.git ~/.basher
|
||||
RUN echo 'export PATH="$HOME/.basher/bin:$PATH"' >> ~/.bash_profile
|
||||
RUN echo 'eval "$(basher init -)"' >> ~/.bash_profile
|
||||
RUN echo '#!/bin/sh' > /entrypoint.sh \
|
||||
&& echo 'echo Usage: basher install shellspec/shellspec' >> /entrypoint.sh \
|
||||
&& echo 'echo Usage: basher install shellspec/shellspec@0.19.0' >> /entrypoint.sh \
|
||||
&& echo 'echo Usage: basher link ./shellspec shellspec/shellspec' >> /entrypoint.sh \
|
||||
&& echo 'exec "$@"' >> /entrypoint.sh \
|
||||
&& chmod +x /entrypoint.sh
|
||||
ENTRYPOINT [ "/entrypoint.sh" ]
|
||||
WORKDIR /root
|
||||
CMD [ "/bin/bash", "-l" ]
|
||||
|
||||
FROM linuxbrew/brew as brew_installer
|
||||
RUN echo '#!/bin/sh' > /entrypoint.sh \
|
||||
&& echo 'echo "Usage: brew tap shellspec/shellspec"' >> /entrypoint.sh \
|
||||
&& echo 'echo " brew install shellspec"' >> /entrypoint.sh \
|
||||
&& echo 'echo " brew test shellspec"' >> /entrypoint.sh \
|
||||
&& echo 'exec "$@"' >> /entrypoint.sh \
|
||||
&& chmod +x /entrypoint.sh
|
||||
ENTRYPOINT [ "/entrypoint.sh" ]
|
||||
CMD [ "/bin/bash", "-l" ]
|
||||
|
||||
FROM shellspec:${TYPE}_installer as test
|
||||
COPY ./install.sh /root/
|
||||
COPY ./ /root/shellspec
|
||||
@ -0,0 +1,3 @@
|
||||
ARG VERSION=latest
|
||||
FROM koalaman/shellcheck-alpine:$VERSION
|
||||
COPY ./ ./
|
||||
@ -0,0 +1,21 @@
|
||||
ARG IMAGE
|
||||
|
||||
FROM shellspec:helpers as helpers
|
||||
|
||||
FROM $IMAGE
|
||||
COPY --from=helpers /usr/local/bin/* /usr/local/bin/
|
||||
WORKDIR /shellspec
|
||||
RUN chmod ug+s /usr/local/bin/su-exec \
|
||||
&& echo "--no-banner" > /home/user/.shellspec-options \
|
||||
&& if [ "$KCOV" ]; then echo "--kcov" >> /home/user/.shellspec-options; fi \
|
||||
&& ln -s /shellspec/shellspec /usr/local/bin/shellspec \
|
||||
&& echo "$SH" > /etc/invokesh.conf \
|
||||
&& [ "$SH" = "/bin/sh" ] || ln -snf /usr/local/bin/invokesh /bin/sh
|
||||
|
||||
ENTRYPOINT [ "/entrypoint.sh" ]
|
||||
CMD [ "shellspec" ]
|
||||
|
||||
COPY ./dockerfiles/.shellspec-entrypoint.sh /entrypoint.sh
|
||||
COPY --chown=user:user ./ /shellspec
|
||||
RUN chmod 777 /shellspec
|
||||
USER user
|
||||
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$1" = "shellspec" ]; then
|
||||
(
|
||||
export SUDO_GID=$(id -g) SUDO_UID=$(id -u)
|
||||
su-exec root shellspec --task fixture:stat:prepare
|
||||
)
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
@ -0,0 +1,3 @@
|
||||
FROM alpine:3.12.3
|
||||
RUN adduser -D user && apk add --no-cache bash
|
||||
ENV SH=/bin/bash
|
||||
@ -0,0 +1,3 @@
|
||||
FROM alpine:3.12.3
|
||||
RUN adduser -D user && apk add --no-cache loksh
|
||||
ENV SH=/bin/ksh
|
||||
@ -0,0 +1,3 @@
|
||||
FROM alpine:3.12.3
|
||||
RUN adduser -D user
|
||||
ENV SH=/bin/ash
|
||||
@ -0,0 +1,3 @@
|
||||
FROM alpine:edge
|
||||
RUN adduser -D user && apk add --no-cache loksh
|
||||
ENV SH=/bin/ksh
|
||||
@ -0,0 +1,4 @@
|
||||
FROM alpine:edge
|
||||
RUN echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories
|
||||
RUN adduser -D user && apk add --no-cache oksh@testing
|
||||
ENV SH=/bin/oksh
|
||||
@ -0,0 +1,3 @@
|
||||
FROM busybox:1.32.0
|
||||
RUN adduser -D user
|
||||
ENV SH=/bin/ash
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user