5541f577 |
#!/bin/bash
# This script tests the high level end-to-end functionality demonstrated |
6d660e3d |
# as part of the examples/sample-app |
5541f577 |
|
cfc65438 |
if [[ -z "$(which iptables)" ]]; then |
466b5c3a |
echo "IPTables not found - the end-to-end test requires a system with iptables for Kubernetes services."
exit 1 |
cfc65438 |
fi |
4fc93a99 |
iptables --list > /dev/null 2>&1
if [ $? -ne 0 ]; then |
466b5c3a |
sudo iptables --list > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "You do not have iptables or sudo privileges. Kubernetes services will not work without iptables access. See https://github.com/GoogleCloudPlatform/kubernetes/issues/1859. Try 'sudo hack/test-end-to-end.sh'."
exit 1
fi |
4fc93a99 |
fi
|
5541f577 |
set -o errexit
set -o nounset
set -o pipefail
|
e3bb13a1 |
OS_ROOT=$(dirname "${BASH_SOURCE}")/..
source "${OS_ROOT}/hack/util.sh"
|
2cf3cf74 |
echo "[INFO] Starting end-to-end test" |
5541f577 |
|
776b67b2 |
# Use either the latest release built images, or latest.
if [[ -z "${USE_IMAGES-}" ]]; then
USE_IMAGES='openshift/origin-${component}:latest'
if [[ -e "${OS_ROOT}/_output/local/releases/.commit" ]]; then
COMMIT="$(cat "${OS_ROOT}/_output/local/releases/.commit")"
USE_IMAGES="openshift/origin-\${component}:${COMMIT}"
fi
fi
|
6bfba153 |
ROUTER_TESTS_ENABLED="${ROUTER_TESTS_ENABLED:-true}" |
c705715f |
TEST_ASSETS="${TEST_ASSETS:-false}" |
5541f577 |
|
1a0786b4 |
if [[ -z "${BASETMPDIR-}" ]]; then |
466b5c3a |
TMPDIR="${TMPDIR:-"/tmp"}"
BASETMPDIR="${TMPDIR}/openshift-e2e"
sudo rm -rf "${BASETMPDIR}"
mkdir -p "${BASETMPDIR}" |
1a0786b4 |
fi |
366baa89 |
ETCD_DATA_DIR="${BASETMPDIR}/etcd"
VOLUME_DIR="${BASETMPDIR}/volumes" |
40be29be |
FAKE_HOME_DIR="${BASETMPDIR}/openshift.local.home" |
366baa89 |
LOG_DIR="${LOG_DIR:-${BASETMPDIR}/logs}"
ARTIFACT_DIR="${ARTIFACT_DIR:-${BASETMPDIR}/artifacts}" |
87192d34 |
mkdir -p $LOG_DIR |
c773c9cf |
mkdir -p $ARTIFACT_DIR |
30380339 |
|
c9768a7d |
DEFAULT_SERVER_IP=`ifconfig | grep -Ev "(127.0.0.1|172.17.42.1)" | grep "inet " | head -n 1 | sed 's/adr://' | awk '{print $2}'` |
30380339 |
API_HOST="${API_HOST:-${DEFAULT_SERVER_IP}}" |
ab7ef450 |
API_PORT="${API_PORT:-8443}"
API_SCHEME="${API_SCHEME:-https}" |
30380339 |
MASTER_ADDR="${API_SCHEME}://${API_HOST}:${API_PORT}" |
961eecb6 |
PUBLIC_MASTER_HOST="${PUBLIC_MASTER_HOST:-${API_HOST}}" |
53c7aa34 |
KUBELET_SCHEME="${KUBELET_SCHEME:-https}"
KUBELET_HOST="${KUBELET_HOST:-127.0.0.1}" |
e3bb13a1 |
KUBELET_PORT="${KUBELET_PORT:-10250}"
|
40be29be |
SERVER_CONFIG_DIR="${BASETMPDIR}/openshift.local.config"
MASTER_CONFIG_DIR="${SERVER_CONFIG_DIR}/master"
NODE_CONFIG_DIR="${SERVER_CONFIG_DIR}/node-${KUBELET_HOST}"
|
ab7ef450 |
# use the docker bridge ip address until there is a good way to get the auto-selected address from master
# this address is considered stable |
d1326a10 |
# used as a resolve IP to test routing |
028b5f55 |
CONTAINER_ACCESSIBLE_API_HOST="${CONTAINER_ACCESSIBLE_API_HOST:-172.17.42.1}" |
ab7ef450 |
|
2cf3cf74 |
STI_CONFIG_FILE="${LOG_DIR}/stiAppConfig.json"
DOCKER_CONFIG_FILE="${LOG_DIR}/dockerAppConfig.json"
CUSTOM_CONFIG_FILE="${LOG_DIR}/customAppConfig.json" |
e3bb13a1 |
GO_OUT="${OS_ROOT}/_output/local/go/bin" |
5541f577 |
|
cfc65438 |
# set path so OpenShift is available
export PATH="${GO_OUT}:${PATH}" |
5541f577 |
|
eeaac221 |
function cleanup() |
5541f577 |
{ |
466b5c3a |
out=$?
echo
if [ $out -ne 0 ]; then
echo "[FAIL] !!!!! Test Failed !!!!"
else
echo "[INFO] Test Succeeded"
fi
echo
|
22d4002c |
set +e |
466b5c3a |
echo "[INFO] Dumping container logs to ${LOG_DIR}"
for container in $(docker ps -aq); do
docker logs "$container" >&"${LOG_DIR}/container-$container.log"
done
echo "[INFO] Dumping build log to ${LOG_DIR}"
|
2d3b17b9 |
osc get -n test builds --output-version=v1beta1 -t '{{ range .items }}{{.metadata.name}}{{ "\n" }}{{end}}' | xargs -r -l osc build-logs -n test >"${LOG_DIR}/stibuild.log"
osc get -n docker builds --output-version=v1beta1 -t '{{ range .items }}{{.metadata.name}}{{ "\n" }}{{end}}' | xargs -r -l osc build-logs -n docker >"${LOG_DIR}/dockerbuild.log"
osc get -n custom builds --output-version=v1beta1 -t '{{ range .items }}{{.metadata.name}}{{ "\n" }}{{end}}' | xargs -r -l osc build-logs -n custom >"${LOG_DIR}/custombuild.log" |
53c7aa34 |
echo "[INFO] Dumping etcd contents to ${ARTIFACT_DIR}/etcd_dump.json"
set_curl_args 0 1
curl ${clientcert_args} -L "${API_SCHEME}://${API_HOST}:4001/v2/keys/?recursive=true" > "${ARTIFACT_DIR}/etcd_dump.json" |
466b5c3a |
echo
if [[ -z "${SKIP_TEARDOWN-}" ]]; then
echo "[INFO] Tearing down test"
pids="$(jobs -pr)"
echo "[INFO] Children: ${pids}"
sudo kill ${pids}
sudo ps f
set +u |
5baccde3 |
echo "[INFO] Stopping k8s docker containers"; docker ps | awk 'index($NF,"k8s_")==1 { print $1 }' | xargs -l -r docker stop |
466b5c3a |
if [[ -z "${SKIP_IMAGE_CLEANUP-}" ]]; then |
5baccde3 |
echo "[INFO] Removing k8s docker containers"; docker ps -a | awk 'index($NF,"k8s_")==1 { print $1 }' | xargs -l -r docker rm |
466b5c3a |
fi
set -u
fi
set -e
# clean up zero byte log files
# Clean up large log files so they don't end up on jenkins
find ${ARTIFACT_DIR} -name *.log -size +20M -exec echo Deleting {} because it is too big. \; -exec rm -f {} \;
find ${LOG_DIR} -name *.log -size +20M -exec echo Deleting {} because it is too big. \; -exec rm -f {} \;
find ${LOG_DIR} -name *.log -size 0 -exec echo Deleting {} because it is empty. \; -exec rm -f {} \;
echo "[INFO] Exiting"
exit $out |
5541f577 |
}
|
eeaac221 |
trap "exit" INT TERM
trap "cleanup" EXIT
|
2cf3cf74 |
function wait_for_app() { |
466b5c3a |
echo "[INFO] Waiting for app in namespace $1"
echo "[INFO] Waiting for database pod to start" |
cf2a6754 |
wait_for_command "osc get -n $1 pods -l name=database | grep -i Running" $((60*TIME_SEC)) |
2cf3cf74 |
|
466b5c3a |
echo "[INFO] Waiting for database service to start"
wait_for_command "osc get -n $1 services | grep database" $((20*TIME_SEC)) |
2d3b17b9 |
DB_IP=$(osc get -n $1 --output-version=v1beta1 --template="{{ .portalIP }}" service database) |
2cf3cf74 |
|
466b5c3a |
echo "[INFO] Waiting for frontend pod to start"
wait_for_command "osc get -n $1 pods | grep frontend | grep -i Running" $((120*TIME_SEC)) |
2cf3cf74 |
|
466b5c3a |
echo "[INFO] Waiting for frontend service to start"
wait_for_command "osc get -n $1 services | grep frontend" $((20*TIME_SEC)) |
2d3b17b9 |
FRONTEND_IP=$(osc get -n $1 --output-version=v1beta1 --template="{{ .portalIP }}" service frontend) |
2cf3cf74 |
|
466b5c3a |
echo "[INFO] Waiting for database to start..."
wait_for_url_timed "http://${DB_IP}:5434" "[INFO] Database says: " $((3*TIME_MIN)) |
2cf3cf74 |
|
466b5c3a |
echo "[INFO] Waiting for app to start..." |
cab06f2e |
wait_for_url_timed "http://${FRONTEND_IP}:5432" "[INFO] Frontend says: " $((2*TIME_MIN)) |
c4c8c236 |
echo "[INFO] Testing app"
wait_for_command '[[ "$(curl -s -X POST http://${FRONTEND_IP}:5432/keys/foo -d value=1337)" = "Key created" ]]'
wait_for_command '[[ "$(curl -s http://${FRONTEND_IP}:5432/keys/foo)" = "1337" ]]' |
2cf3cf74 |
}
# Wait for builds to complete
# $1 namespace
function wait_for_build() { |
466b5c3a |
echo "[INFO] Waiting for $1 namespace build to complete"
wait_for_command "osc get -n $1 builds | grep -i complete" $((10*TIME_MIN)) "osc get -n $1 builds | grep -i -e failed -e error" |
2d3b17b9 |
BUILD_ID=`osc get -n $1 builds --output-version=v1beta1 -t "{{with index .items 0}}{{.metadata.name}}{{end}}"` |
466b5c3a |
echo "[INFO] Build ${BUILD_ID} finished" |
bab21a83 |
# TODO: fix
set +e |
466b5c3a |
osc build-logs -n $1 $BUILD_ID > $LOG_DIR/$1build.log |
bab21a83 |
set -e |
2cf3cf74 |
}
|
cfc65438 |
# Setup
stop_openshift_server
echo "[INFO] `openshift version`" |
6401bcd6 |
echo "[INFO] Server logs will be at: ${LOG_DIR}/openshift.log" |
366baa89 |
echo "[INFO] Test artifacts will be in: ${ARTIFACT_DIR}" |
6401bcd6 |
echo "[INFO] Volumes dir is: ${VOLUME_DIR}" |
40be29be |
echo "[INFO] Config dir is: ${SERVER_CONFIG_DIR}" |
776b67b2 |
echo "[INFO] Using images: ${USE_IMAGES}" |
5541f577 |
# Start All-in-one server and wait for health |
30380339 |
echo "[INFO] Create certificates for the OpenShift server"
# find the same IP that openshift start will bind to. This allows access from pods that have to talk back to master |
c9768a7d |
ALL_IP_ADDRESSES=`ifconfig | grep "inet " | sed 's/adr://' | awk '{print $2}'` |
30380339 |
SERVER_HOSTNAME_LIST="${PUBLIC_MASTER_HOST},localhost"
while read -r IP_ADDRESS
do
SERVER_HOSTNAME_LIST="${SERVER_HOSTNAME_LIST},${IP_ADDRESS}"
done <<< "${ALL_IP_ADDRESSES}"
|
53c7aa34 |
openshift admin create-master-certs \ |
40be29be |
--overwrite=false \
--cert-dir="${MASTER_CONFIG_DIR}" \
--hostnames="${SERVER_HOSTNAME_LIST}" \
--master="${MASTER_ADDR}" \
--public-master="${API_SCHEME}://${PUBLIC_MASTER_HOST}" |
53c7aa34 |
openshift admin create-node-config \ |
40be29be |
--listen="${KUBELET_SCHEME}://0.0.0.0:${KUBELET_PORT}" \
--node-dir="${NODE_CONFIG_DIR}" \
--node="${KUBELET_HOST}" \
--hostnames="${KUBELET_HOST}" \
--master="${MASTER_ADDR}" \
--node-client-certificate-authority="${MASTER_CONFIG_DIR}/ca.crt" \
--certificate-authority="${MASTER_CONFIG_DIR}/ca.crt" \
--signer-cert="${MASTER_CONFIG_DIR}/ca.crt" \
--signer-key="${MASTER_CONFIG_DIR}/ca.key" \
--signer-serial="${MASTER_CONFIG_DIR}/ca.serial.txt"
osadm create-bootstrap-policy-file --filename="${MASTER_CONFIG_DIR}/policy.json"
# create openshift config
openshift start \
--write-config=${SERVER_CONFIG_DIR} \
--create-certs=false \
--listen="${API_SCHEME}://0.0.0.0:${API_PORT}" \
--master="${MASTER_ADDR}" \
--public-master="${API_SCHEME}://${PUBLIC_MASTER_HOST}" \
--hostname="${KUBELET_HOST}" \
--volume-dir="${VOLUME_DIR}" \
--etcd-dir="${ETCD_DATA_DIR}" \
--images="${USE_IMAGES}"
|
30380339 |
|
9de089a8 |
echo "[INFO] Starting OpenShift server" |
8fb6ec59 |
sudo env "PATH=${PATH}" OPENSHIFT_PROFILE=web OPENSHIFT_ON_PANIC=crash openshift start \ |
40be29be |
--master-config=${MASTER_CONFIG_DIR}/master-config.yaml \
--node-config=${NODE_CONFIG_DIR}/node-config.yaml \
--loglevel=4 \
&> "${LOG_DIR}/openshift.log" & |
cfc65438 |
OS_PID=$! |
cab06f2e |
|
40be29be |
export HOME="${FAKE_HOME_DIR}" |
5541f577 |
|
366baa89 |
if [[ "${API_SCHEME}" == "https" ]]; then |
40be29be |
export CURL_CA_BUNDLE="${MASTER_CONFIG_DIR}/ca.crt"
export CURL_CERT="${MASTER_CONFIG_DIR}/admin.crt"
export CURL_KEY="${MASTER_CONFIG_DIR}/admin.key"
# Make osc use ${MASTER_CONFIG_DIR}/admin.kubeconfig, and ignore anything in the running user's $HOME dir
export OPENSHIFTCONFIG="${MASTER_CONFIG_DIR}/admin.kubeconfig"
sudo chmod -R a+rwX "${OPENSHIFTCONFIG}" |
ce40bd34 |
echo "[INFO] To debug: export OPENSHIFTCONFIG=$OPENSHIFTCONFIG" |
ab7ef450 |
fi |
5541f577 |
|
53c7aa34 |
wait_for_url "${KUBELET_SCHEME}://${KUBELET_HOST}:${KUBELET_PORT}/healthz" "[INFO] kubelet: " 0.5 60 |
6401bcd6 |
wait_for_url "${API_SCHEME}://${API_HOST}:${API_PORT}/healthz" "apiserver: " 0.25 80 |
53c7aa34 |
wait_for_url "${API_SCHEME}://${API_HOST}:${API_PORT}/api/v1beta1/minions/${KUBELET_HOST}" "apiserver(minions): " 0.25 80 |
6401bcd6 |
|
30380339 |
# add e2e-user as a viewer for the default namespace so we can see infrastructure pieces appear |
a600f8ce |
openshift admin policy add-role-to-user view e2e-user --namespace=default |
30380339 |
|
961eecb6 |
# create test project so that this shows up in the console |
a600f8ce |
openshift admin new-project test --description="This is an example project to demonstrate OpenShift v3" --admin="e2e-user" |
f07b2e98 |
openshift admin new-project docker --description="This is an example project to demonstrate OpenShift v3" --admin="e2e-user"
openshift admin new-project custom --description="This is an example project to demonstrate OpenShift v3" --admin="e2e-user" |
c98eb29f |
openshift admin new-project cache --description="This is an example project to demonstrate OpenShift v3" --admin="e2e-user" |
961eecb6 |
|
ccb307cf |
echo "The console should be available at ${API_SCHEME}://${PUBLIC_MASTER_HOST}:${API_PORT}/console." |
4258b754 |
echo "Log in as 'e2e-user' to see the 'test' project." |
961eecb6 |
|
fbfd1713 |
# install the router
echo "[INFO] Installing the router" |
40be29be |
openshift admin router --create --credentials="${MASTER_CONFIG_DIR}/openshift-router.kubeconfig" --images="${USE_IMAGES}" |
961eecb6 |
|
22d4002c |
# install the registry. The --mount-host option is provided to reuse local storage. |
fbfd1713 |
echo "[INFO] Installing the registry" |
c98eb29f |
openshift admin registry --create --credentials="${MASTER_CONFIG_DIR}/openshift-registry.kubeconfig" --mount-host="/tmp/openshift.local.registry" --images="${USE_IMAGES}" |
5541f577 |
|
cf2a6754 |
echo "[INFO] Pre-pulling and pushing ruby-20-centos7"
docker pull openshift/ruby-20-centos7:latest
echo "[INFO] Pulled ruby-20-centos7" |
5541f577 |
|
22d4002c |
echo "[INFO] Waiting for Docker registry pod to start"
# TODO: simplify when #4702 is fixed upstream |
2d3b17b9 |
wait_for_command '[[ "$(osc get endpoints docker-registry --output-version=v1beta1 -t "{{ if .endpoints }}{{ len .endpoints }}{{ else }}0{{ end }}" || echo "0")" != "0" ]]' $((5*TIME_MIN)) |
cfc65438 |
|
466b5c3a |
# services can end up on any IP. Make sure we get the IP we need for the docker registry |
1dcda276 |
DOCKER_REGISTRY=$(osc get --output-version=v1beta3 --template="{{ .spec.portalIP }}:{{ with index .spec.ports 0 }}{{ .port }}{{ end }}" service docker-registry) |
5541f577 |
|
22d4002c |
echo "[INFO] Verifying the docker-registry is up at ${DOCKER_REGISTRY}" |
bfacaf33 |
wait_for_url_timed "http://${DOCKER_REGISTRY}/v2/" "[INFO] Docker registry says: " $((2*TIME_MIN)) |
8defe754 |
|
3befb47d |
[ "$(dig @${API_HOST} "docker-registry.default.local." A)" ]
|
c98eb29f |
# Client setup (log in as e2e-user and set 'test' as the default project)
# This is required to be able to push to the registry!
echo "[INFO] Logging in as a regular user (e2e-user:pass) with project 'test'..."
osc login -u e2e-user -p pass
osc project cache |
33b7dabd |
token=$(osc config view --flatten -o template -t '{{with index .users 0}}{{.user.token}}{{end}}') |
c98eb29f |
[[ -n ${token} ]]
# TODO reenable this once we've got docker push secrets 100% ready
#docker login -u e2e-user -p ${token} -e e2e-user@openshift.com ${DOCKER_REGISTRY}
# TODO remove the following line once we've got docker push secrets 100% ready
echo '{"apiVersion": "v1beta1", "kind": "ImageStream", "metadata": {"name": "ruby-20-centos7"}}' | osc create -f -
docker tag -f openshift/ruby-20-centos7:latest ${DOCKER_REGISTRY}/cache/ruby-20-centos7:latest
docker push ${DOCKER_REGISTRY}/cache/ruby-20-centos7:latest |
cf2a6754 |
echo "[INFO] Pushed ruby-20-centos7" |
8defe754 |
|
c98eb29f |
echo "[INFO] Back to 'master' context with 'admin' user..."
osc project default
|
f89cda25 |
# Process template and create |
aba61fe0 |
echo "[INFO] Submitting application template json for processing..." |
2cf3cf74 |
osc process -n test -f examples/sample-app/application-template-stibuild.json > "${STI_CONFIG_FILE}"
osc process -n docker -f examples/sample-app/application-template-dockerbuild.json > "${DOCKER_CONFIG_FILE}"
osc process -n custom -f examples/sample-app/application-template-custombuild.json > "${CUSTOM_CONFIG_FILE}"
|
c98eb29f |
echo "[INFO] Back to 'test' context with 'e2e-user' user" |
ce40bd34 |
osc project test
|
2cf3cf74 |
echo "[INFO] Applying STI application config" |
ce40bd34 |
osc create -f "${STI_CONFIG_FILE}" |
5541f577 |
|
10a73724 |
|
c98eb29f |
# this needs to be done before waiting for the build because right now only cluster-admins can see build logs, because that uses proxy |
10a73724 |
echo "[INFO] Back to 'master' context with 'admin' user..."
osc project default |
16df0e88 |
|
5541f577 |
# Trigger build |
50f134ea |
echo "[INFO] Starting build from ${STI_CONFIG_FILE} and streaming its logs..." |
ae1dca33 |
#osc start-build -n test ruby-sample-build --follow |
2cf3cf74 |
wait_for_build "test"
wait_for_app "test"
|
ad390e66 |
#echo "[INFO] Applying Docker application config" |
f89cda25 |
#osc create -n docker -f "${DOCKER_CONFIG_FILE}" |
ad390e66 |
#echo "[INFO] Invoking generic web hook to trigger new docker build using curl"
#curl -k -X POST $API_SCHEME://$API_HOST:$API_PORT/osapi/v1beta1/buildConfigHooks/ruby-sample-build/secret101/generic?namespace=docker && sleep 3
#wait_for_build "docker"
#wait_for_app "docker"
#echo "[INFO] Applying Custom application config" |
f89cda25 |
#osc create -n custom -f "${CUSTOM_CONFIG_FILE}" |
ad390e66 |
#echo "[INFO] Invoking generic web hook to trigger new custom build using curl"
#curl -k -X POST $API_SCHEME://$API_HOST:$API_PORT/osapi/v1beta1/buildConfigHooks/ruby-sample-build/secret101/generic?namespace=custom && sleep 3
#wait_for_build "custom"
#wait_for_app "custom" |
6bfba153 |
|
fbfd1713 |
# ensure the router is started |
22d4002c |
# TODO: simplify when #4702 is fixed upstream |
2d3b17b9 |
wait_for_command '[[ "$(osc get endpoints router --output-version=v1beta1 -t "{{ if .endpoints }}{{ len .endpoints }}{{ else }}0{{ end }}" || echo "0")" != "0" ]]' $((5*TIME_MIN)) |
6bfba153 |
|
fbfd1713 |
echo "[INFO] Validating routed app response..."
validate_response "-s -k --resolve www.example.com:443:${CONTAINER_ACCESSIBLE_API_HOST} https://www.example.com" "Hello from OpenShift" 0.2 50 |
c705715f |
|
87d9e2ab |
# Remote command execution |
47e4f92d |
echo "[INFO] Validating exec" |
d53a2fa2 |
registry_pod=$(osc get pod | grep deployment=docker-registry | grep docker-registry | awk '{print $1}') |
87d9e2ab |
osc exec -p ${registry_pod} whoami | grep root
# Port forwarding |
47e4f92d |
echo "[INFO] Validating port-forward" |
50eb1bbd |
osc port-forward -p ${registry_pod} 5001:5000 &> "${LOG_DIR}/port-forward.log" & |
c98eb29f |
wait_for_url_timed "http://localhost:5001/healthz" "[INFO] Docker registry says: " $((10*TIME_SEC)) |
87d9e2ab |
|
c705715f |
# UI e2e tests can be found in assets/test/e2e
if [[ "$TEST_ASSETS" == "true" ]]; then
echo "[INFO] Running UI e2e tests..."
pushd ${OS_ROOT}/assets > /dev/null
grunt test-e2e
popd > /dev/null
fi |