diff --git a/basis/bin/auto_env.sh b/basis/bin/auto_env.sh index 41522789..b47c88b5 100755 --- a/basis/bin/auto_env.sh +++ b/basis/bin/auto_env.sh @@ -325,6 +325,11 @@ if [ -f $STATE_FILE ]; then else export TF_VAR_docker_image_rest="busybox" fi + if [ -f $TARGET_DIR/docker_image_mcp_server.txt ]; then + export TF_VAR_docker_image_mcp_server=`cat $TARGET_DIR/docker_image_mcp_server.txt` + else + export TF_VAR_docker_image_mcp_server="busybox" + fi fi # export all OUTPUTS of the terraform file @@ -360,8 +365,7 @@ if [ -f $STATE_FILE ]; then if [ "$TF_VAR_deploy_type" == "kubernetes" ] || [ -f $PROJECT_DIR/src/terraform/oke.tf ]; then # OKE if [ -f $KUBECONFIG ]; then - export TF_VAR_ingress_ip=`kubectl get service -n ingress-nginx ingress-nginx-controller -o jsonpath="{.status.loadBalancer.ingress[0].ip}"` - export INGRESS_LB_OCID=`oci lb load-balancer list --compartment-id $TF_VAR_compartment_ocid | jq -r '.data[] | select(.["ip-addresses"][0]["ip-address"]=="'$TF_VAR_ingress_ip'") | .id'` + oke_get_gateway_ip fi fi diff --git a/basis/bin/compute/compute_install.sh b/basis/bin/compute/compute_install.sh index b62e149a..0c3a6257 100755 --- a/basis/bin/compute/compute_install.sh +++ b/basis/bin/compute/compute_install.sh @@ -17,6 +17,12 @@ if ! grep -q "export LC_CTYPE" $HOME/.bashrc; then # Set VI and NANO in utf8 echo "export LC_CTYPE=en_US.UTF-8" >> $HOME/.bashrc echo "shopt -s direxpand" >> $HOME/.bashrc + cat >> $HOME/.vimrc <47GB) sudo /usr/libexec/oci-growfs -y +fi - # Build_host = bastion +if ! grep -q "# Build Bastion" $HOME/.bashrc; then if [ "$TF_VAR_build_host" == "bastion" ]; then - # Kubernetes - if [ "$TF_VAR_deploy_type" == "kubernetes" ]; then + echo "# Build Bastion" >> $HOME/.bashrc# Build_host = bastion + # Kubernetes + if [ "$TF_VAR_oke_ocid" != "" ]; then install_docker_tools echo "export KUBECONFIG=$HOME/compute/kubeconfig_starter" >> $HOME/.bashrc fi - # Kubernetes - if [ "$TF_VAR_language" == "java" ]; then + # Java + if [ "$TF_VAR_language" == "java" ] || [ "$TF_VAR_oke_ocid" != "" ]; then install_java fi # Create a git branch diff --git a/basis/bin/compute/rebuild.sh b/basis/bin/compute/rebuild.sh index b0ac7931..eada64bd 100755 --- a/basis/bin/compute/rebuild.sh +++ b/basis/bin/compute/rebuild.sh @@ -23,11 +23,11 @@ for APP_DIR in `app_dir_list`; do # Build in bastion $APP_NAME/build.sh fi - if [ "APP_NAME" == "db" ]; then + if [ "$APP_NAME" == "db" ]; then # Database title "Rebuild - $APP_NAME: Install" ${APP_DIR}/install.sh - elif [ -f $APP_DIR/install.sh ] && [ is_deploy_compute ]; then + elif [ -f $APP_DIR/install.sh ] && is_deploy_compute; then # Build in terraform - compute title "Rebuild: $APP_NAME: Install" ${APP_DIR}/install.sh @@ -42,6 +42,10 @@ for APP_DIR in `app_dir_list`; do fi done +if [ -f $HOME/bastion_lock ]; then + rm $HOME/bastion_lock +fi + end_time=$(date +%s) echo echo " Time taken: $((end_time - start_time)) seconds" \ No newline at end of file diff --git a/basis/bin/compute/shared_compute.sh b/basis/bin/compute/shared_compute.sh index f50ae52d..5eb1b052 100755 --- a/basis/bin/compute/shared_compute.sh +++ b/basis/bin/compute/shared_compute.sh @@ -116,7 +116,6 @@ install_java() { # sudo update-alternatives --set native-image $JAVA_HOME/lib/svm/bin/native-image fi sudo update-alternatives --set java $JAVA_HOME/bin/java - echo "export JAVA_HOME=${JAVA_HOME}" >> $HOME/.bashrc else # JDK # Needed due to concurrency @@ -137,7 +136,9 @@ install_java() { # cd - # sudo update-alternatives --set java $JAVA_LATEST_PATH/bin/java fi + export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java)))) fi + echo "export JAVA_HOME=${JAVA_HOME}" >> $HOME/.bashrc # JMS agent deploy (to fleet_ocid ) if [ -f jms_agent_deploy.sh ]; then @@ -147,7 +148,16 @@ install_java() { # Build on Bastion if [ "$TF_VAR_build_host" == "bastion" ]; then - sudo dnf install -y maven + # sudo dnf install -y maven + if [ ! -d $HOME/maven ]; then + MVN_VERSION=3.9.15 + wget https://dlcdn.apache.org/maven/maven-3/$MVN_VERSION/binaries/apache-maven-$MVN_VERSION-bin.tar.gz + tar xfz apache-maven-$MVN_VERSION-bin.tar.gz + mv apache-maven-$MVN_VERSION $HOME/maven + rm apache-maven-$MVN_VERSION-bin.tar.gz + export PATH=$HOME/maven/bin:$PATH + echo "export PATH=$HOME/maven/bin:$PATH" >> $HOME/.bashrc + fi fi } export -f install_java @@ -228,7 +238,9 @@ install_python() { sudo dnf install -y python3.12 python3.12-pip python3-devel wget sudo update-alternatives --set python /usr/bin/python3.12 curl -LsSf https://astral.sh/uv/install.sh | sh - uv venv myenv + if [ ! -d myenv ]; then + uv venv myenv + fi source myenv/bin/activate if [ -f requirements.txt ]; then uv pip install -r requirements.txt @@ -242,7 +254,9 @@ export -f install_python # -- install_libreoffice --------------------------------------------------- install_libreoffice() { export STABLE_VERSIONS=`curl -s https://download.documentfoundation.org/libreoffice/stable/` - export LIBREOFFICE_VERSION=`echo $STABLE_VERSIONS | sed 's/.*//' | sed 's/\/<\/a>.*//' | sed 's/.*\/">//'` + # export LIBREOFFICE_VERSION=`echo $STABLE_VERSIONS | sed 's/.*//' | sed 's/\/<\/a>.*//' | sed 's/.*\/">//'` + # Version 26.2 is incompatible with RHEL8... + export LIBREOFFICE_VERSION=`echo $STABLE_VERSIONS | sed 's/.*>25.8/25.8/' | sed 's/\/<\/a>.*//' | sed 's/.*\/">//'` echo LIBREOFFICE_VERSION=$LIBREOFFICE_VERSION cd /tmp export LIBREOFFICE_TGZ="LibreOffice_${LIBREOFFICE_VERSION}_Linux_x86-64_rpm.tar.gz" @@ -297,6 +311,8 @@ install_instant_client() { } export -f install_instant_client +# -- create_self_signed_ip_certificate -------------------------------------- + create_self_signed_ip_certificate() { mkdir -p certificate @@ -367,7 +383,8 @@ EOF } export -f create_self_signed_ip_certificate -# -- Install NGINX ------------------------------------------------------------------ +# -- install_ngnix ---------------------------------------------------------- + install_ngnix() { title "NGINX" sudo dnf install nginx -y > /tmp/dnf_nginx.log @@ -468,7 +485,9 @@ copy_replace_apply_target_oke() { export -f copy_replace_apply_target_oke # -- docker_login ----------------------------------------------------------- + docker_login() { + echo "" get_docker_prefix # Login only if needed if ! docker system info 2>/dev/null | grep -q "Username"; then @@ -476,6 +495,7 @@ docker_login() { fi exit_on_error "Docker Login" } +export -f docker_login # -- ocir_docker_push_app ------------------------------------------------------- ocir_docker_push_app() { @@ -516,12 +536,21 @@ oke_deploy_app() { if [ -f k8s.yaml ]; then copy_replace_apply_target_oke k8s.yaml $APP fi - if [ -f k8s-ingress.yaml ]; then - copy_replace_apply_target_oke k8s-ingress.yaml $APP + if [ -f k8s-httproute.yaml ]; then + copy_replace_apply_target_oke k8s-httproute.yaml $APP fi } export -f oke_deploy_app +# -- oke_get_gateway_ip ----------------------------------------------------- + +oke_get_gateway_ip() { + if [ "$TF_VAR_gateway_ip" == "" ]; then + export TF_VAR_gateway_ip=$(kubectl get gateway oke-gateway -n default -o json | jq -r '.status.addresses[].value | select(startswith("10.") | not)') + fi +} +export -f oke_get_gateway_ip + # -- is_deploy_compute ------------------------------------------------------ is_deploy_compute() { if [ "$TF_VAR_deploy_type" == "public_compute" ] || [ "$TF_VAR_deploy_type" == "private_compute" ] || [ "$TF_VAR_deploy_type" == "instance_pool" ]; then @@ -531,6 +560,8 @@ is_deploy_compute() { fi } +export -f is_deploy_compute + # -- build_ui --------------------------------------------------------------- build_ui() { cd $SCRIPT_DIR diff --git a/basis/bin/config_oke.sh b/basis/bin/config_oke.sh index bd5a7360..8d1c6923 100755 --- a/basis/bin/config_oke.sh +++ b/basis/bin/config_oke.sh @@ -8,74 +8,64 @@ title "Config OKE" export TARGET_OKE=$TARGET_DIR/oke mkdir -p $TARGET_OKE -function wait_ingress() { - # Wait for the ingress deployment - echo "Waiting for Ingress Controller Pods..." - kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=600s - kubectl wait --namespace ingress-nginx --for=condition=Complete job/ingress-nginx-admission-patch -} - # One time configuration if [ ! -f $KUBECONFIG ]; then create_kubeconfig - # Check if Ingress Controller is installed - kubectl get service ingress-nginx-controller -n ingress-nginx + # Check if Gateway Controller is installed + kubectl get gateway oke-gateway -n default if [ "$?" != "0" ]; then - # Deploy Latest ingress-nginx + # Deploy Latest istio-gateway kubectl create clusterrolebinding starter_clst_adm --clusterrole=cluster-admin --user=$TF_VAR_current_user_ocid echo "OKE Deploy: Role Binding created" - # LATEST_INGRESS_CONTROLLER=`curl --silent "https://api.github.com/repos/kubernetes/ingress-nginx/releases/latest" | jq -r .name` - # echo LATEST_INGRESS_CONTROLLER=$LATEST_INGRESS_CONTROLLER - # kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/$LATEST_INGRESS_CONTROLLER/deploy/static/provider/cloud/deploy.yaml - if [ "$TF_VAR_tls" == "new_http_01" ]; then - helm install ingress-nginx ingress-nginx --repo https://kubernetes.github.io/ingress-nginx \ - --namespace ingress-nginx \ - --create-namespace \ - --set controller.enableExternalDNS=true - wait_ingress - # ccm-letsencrypt-prod.yaml - sed "s&##CERTIFICATE_EMAIL##&${TF_VAR_certificate_email}&" src/oke/tls/ccm-letsencrypt-prod.yaml > $TARGET_OKE/ccm-letsencrypt-prod.yaml - kubectl apply -f $TARGET_OKE/ccm-letsencrypt-prod.yaml --timeout=600s - sed "s&##CERTIFICATE_EMAIL##&${TF_VAR_certificate_email}&" src/oke/tls/ccm-letsencrypt-staging.yaml > $TARGET_OKE/ccm-letsencrypt-staging.yaml - kubectl apply -f $TARGET_OKE/ccm-letsencrypt-staging.yaml + # See: https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengworkingwithistioaddonforgatewayapi.htm + + # Install Gateway API CRDs + kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml + kubectl get crd gateways.gateway.networking.k8s.io + # Deploy the Istio cluster add-on + oci ce cluster install-addon --addon-name Istio --cluster-id $OKE_OCID --from-json file://src/oke/istio_addon.json + oci ce cluster list-addons --cluster-id $OKE_OCID + # Wait istiod + echo "Waiting for istiod pod to be Running..." - # external-dns-config.yaml - sed "s&##COMPARTMENT_OCID##&${TF_VAR_compartment_ocid}&" src/oke/tls/external-dns-config.yaml > $TARGET_OKE/external-dns-config.tmp - sed "s&##REGION##&${TF_VAR_region}&" $TARGET_OKE/external-dns-config.tmp > $TARGET_OKE/external-dns-config.yaml - kubectl create secret generic external-dns-config --from-file=$TARGET_OKE/external-dns-config.yaml + ELAPSED=0 + while true; do + STATUS=$(kubectl get pods -n istio-system -l app=istiod -o jsonpath='{.items[0].status.phase}' 2>/dev/null) - # external-dns.yaml - sed "s&##COMPARTMENT_OCID##&${TF_VAR_compartment_ocid}&" src/oke/tls/external-dns.yaml > $TARGET_OKE/external-dns.tmp - sed "s&##REGION##&${TF_VAR_region}&" $TARGET_OKE/external-dns.tmp > $TARGET_OKE/external-dns.yaml - kubectl apply -f $TARGET_OKE/external-dns.yaml - else - helm install ingress-nginx ingress-nginx --repo https://kubernetes.github.io/ingress-nginx \ - --namespace ingress-nginx \ - --create-namespace - wait_ingress - fi - - # Wait for the ingress external IP - TF_VAR_ingress_ip="" - while [ -z $TF_VAR_ingress_ip ]; do - echo "Waiting for Ingress IP..." - TF_VAR_ingress_ip=`kubectl get service -n ingress-nginx ingress-nginx-controller -o jsonpath="{.status.loadBalancer.ingress[0].ip}"` - if [ -z "$TF_VAR_ingress_ip" ]; then - sleep 10 + if [ "$STATUS" = "Running" ]; then + echo "Istiod is Running ($ELAPSED secs)" + break + fi + ELAPSED=$((ELAPSED + 5 )) + if [ $ELAPSED -gt 300 ]; then + exit_error "Istiod not started after 300 secs" fi + echo "Waiting 5 secs..." + sleep 5 done - date - kubectl get all -n ingress-nginx - sleep 5 - echo "Ingress ready: $TF_VAR_ingress_ip" + # Create a Gateway + kubectl apply -f src/oke/gateway.yaml + # Wait + echo "Waiting for Gateway to be ready..." + kubectl wait --for=condition=Programmed gateway/oke-gateway -n default --timeout=120s + exit_on_error "Gateway Programmed State" + + # Get the IP + oke_get_gateway_ip + echo "Gateway ready: $TF_VAR_gateway_ip" else - echo "OKE Deploy: Skipping creation of ingress" + echo "OKE Deploy: Skipping creation of Gateway" fi fi +if ! grep -q "TF_VAR_gateway_ip" $TARGET_DIR/tf_env.sh; then + oke_get_gateway_ip + echo "export TF_VAR_gateway_ip=$TF_VAR_gateway_ip" >> $TARGET_DIR/tf_env.sh +fi + # Create secrets kubectl delete secret ${TF_VAR_prefix}-db-secret --ignore-not-found=true kubectl create secret generic ${TF_VAR_prefix}-db-secret --from-literal=db_user=$TF_VAR_db_user --from-literal=db_password=$TF_VAR_db_password --from-literal=db_url=$DB_URL --from-literal=jdbc_url=$JDBC_URL --from-literal=TF_VAR_compartment_ocid=$TF_VAR_compartment_ocid --from-literal=TF_VAR_nosql_endpoint=$TF_VAR_nosql_endpoint diff --git a/basis/bin/deploy_bastion.sh b/basis/bin/deploy_bastion.j2.sh similarity index 70% rename from basis/bin/deploy_bastion.sh rename to basis/bin/deploy_bastion.j2.sh index f5eb2613..a739c82d 100755 --- a/basis/bin/deploy_bastion.sh +++ b/basis/bin/deploy_bastion.j2.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash if [ "$PROJECT_DIR" == "" ]; then - echo "ERROR: PROJECT_DIR undefined. Please use starter.sh deploy bastion" - exit 1 + echo "ERROR: PROJECT_DIR undefined. Please use starter.sh deploy bastion" + exit 1 fi cd $PROJECT_DIR . starter.sh env -silent @@ -14,7 +14,7 @@ function scp_or_rsync() { fi } -function scp_bastion() { +function setup_bastion_dir() { if [ "$TF_VAR_deploy_type" == "public_compute" ] && [ "$TF_VAR_build_host" != "bastion" ]; then BASTION_DIR=$TARGET_DIR/compute else @@ -33,13 +33,26 @@ function scp_bastion() { cp -R src/app/db $BASTION_DIR/app/. fi cp $TARGET_DIR/tf_env.sh $BASTION_DIR/compute/. +} - scp_or_rsync $BASTION_DIR/app +function scp_bastion() { scp_or_rsync $BASTION_DIR/compute + RESULT=$? + if [ $RESULT -eq 0 ]; then + echo "Success - scp $BASTION_DIR/compute" + else + return 1 + fi + {%- if test_name %} + # Get Lock CleanUp + ssh -o StrictHostKeyChecking=no -i $TF_VAR_ssh_private_path opc@$BASTION_IP "bash compute/test_bastion_lock.sh $TEST_NAME" + {%- endif %} + scp_or_rsync $BASTION_DIR/app } # Try 5 times to copy the files / wait 5 secs between each try i=0 +setup_bastion_dir while [ true ]; do scp_bastion if [ $? -eq 0 ]; then @@ -48,9 +61,10 @@ while [ true ]; do echo "deploy_bastion.sh: Maximum number of scp retries, ending." error_exit fi + echo "Warning - scp_bastion failed. Retrying in 5 secs." sleep 5 i=$(($i+1)) done -ssh -o StrictHostKeyChecking=no -i $TF_VAR_ssh_private_path opc@$BASTION_IP "bash compute/compute_install.sh 2>&1 | tee -a compute/compute_install.log" -exit_on_error "Deploy Bastion -" +ssh -o StrictHostKeyChecking=no -i $TF_VAR_ssh_private_path opc@$BASTION_IP "bash compute/compute_install.sh 2>&1 | tee compute/compute_install.log" +exit_on_error "Deploy Bastion - ssh" diff --git a/basis/bin/deploy_ci.sh b/basis/bin/deploy_ci.sh index 3f9836b9..d82d6614 100755 --- a/basis/bin/deploy_ci.sh +++ b/basis/bin/deploy_ci.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash if [ "$PROJECT_DIR" == "" ]; then - echo "ERROR: PROJECT_DIR undefined. Please use starter.sh" - exit 1 + echo "ERROR: PROJECT_DIR undefined. Please use starter.sh" + exit 1 fi cd $PROJECT_DIR . starter.sh env -no-auto @@ -11,8 +11,8 @@ cd $PROJECT_DIR ocir_docker_push if [ "$CALLED_BY_TERRAFORM" == "" ]; then - # Run terraform a second time - cd $PROJECT_DIR - . starter.sh env - $BIN_DIR/terraform_apply.sh --auto-approve -no-color + # Run terraform a second time + cd $PROJECT_DIR + . starter.sh env + $BIN_DIR/terraform_apply.sh --auto-approve -no-color fi \ No newline at end of file diff --git a/basis/bin/deploy_compute.sh b/basis/bin/deploy_compute.sh index bb792860..b9dfef9e 100755 --- a/basis/bin/deploy_compute.sh +++ b/basis/bin/deploy_compute.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash if [ "$PROJECT_DIR" == "" ]; then - echo "ERROR: PROJECT_DIR undefined. Please use starter.sh deploy compute" - exit 1 + echo "ERROR: PROJECT_DIR undefined. Please use starter.sh deploy compute" + exit 1 fi cd $PROJECT_DIR . starter.sh env -silent @@ -12,6 +12,6 @@ echo "COMPUTE_IP=$COMPUTE_IP" cp $TARGET_DIR/tf_env.sh $TARGET_DIR/compute/compute/. scp_via_bastion "target/compute/*" opc@$COMPUTE_IP:/home/opc/. -ssh -o StrictHostKeyChecking=no -oProxyCommand="$BASTION_PROXY_COMMAND" opc@$COMPUTE_IP "bash compute/compute_install.sh 2>&1 | tee -a compute/compute_install.log" +ssh -o StrictHostKeyChecking=no -oProxyCommand="$BASTION_PROXY_COMMAND" opc@$COMPUTE_IP "bash compute/compute_install.sh 2>&1 | tee compute/compute_install.log" exit_on_error "Deploy Compute - ssh" diff --git a/basis/bin/destroy_all.sh b/basis/bin/destroy_all.sh index 5ee0e021..873d116a 100755 --- a/basis/bin/destroy_all.sh +++ b/basis/bin/destroy_all.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash if [ "$PROJECT_DIR" == "" ]; then - echo "ERROR: PROJECT_DIR undefined. Please use starter.sh destroy" - exit 1 + echo "ERROR: PROJECT_DIR undefined. Please use starter.sh destroy" + exit 1 fi cd $PROJECT_DIR SECONDS=0 @@ -11,25 +11,25 @@ SECONDS=0 # Confidential APP disableConfidentialApp() { - # Disable the app before destroy... (Bug?) if not destroy fails... - CONFIDENTIAL_APP_OCID=$1 - echo "Confidential app: set active to false. APP_ID=$CONFIDENTIAL_APP_OCID" - # Remove trailing / - IDCS_URL=${IDCS_URL::-1} - oci identity-domains app-status-changer put --force --active false --app-status-changer-id $CONFIDENTIAL_APP_OCID --schemas '["urn:ietf:params:scim:schemas:oracle:idcs:AppStatusChanger"]' --endpoint $IDCS_URL --force - exit_on_error "disableConfidentialApp" + # Disable the app before destroy... (Bug?) if not destroy fails... + CONFIDENTIAL_APP_OCID=$1 + echo "Confidential app: set active to false. APP_ID=$CONFIDENTIAL_APP_OCID" + # Remove trailing / + IDCS_URL=${IDCS_URL::-1} + oci identity-domains app-status-changer put --force --active false --app-status-changer-id $CONFIDENTIAL_APP_OCID --schemas '["urn:ietf:params:scim:schemas:oracle:idcs:AppStatusChanger"]' --endpoint $IDCS_URL --force + exit_on_error "disableConfidentialApp" } # Buckets cleanBucket() { - BUCKET_NAME=$1 - export TF_OBJECT_STORAGE=`cat $STATE_FILE | jq -r '.resources[] | select(.instances[0].attributes.name=="'${BUCKET_NAME}'") | .instances[].attributes.bucket_id'` - if [ "$TF_OBJECT_STORAGE" != "" ] && [ "$TF_OBJECT_STORAGE" != "null" ]; then - title "Delete Object Storage" - oci os bucket delete --bucket-name $BUCKET_NAME --namespace-name $TF_VAR_namespace --empty --force - else - echo "No Object storage $BUCKET_NAME" - fi + BUCKET_NAME=$1 + export TF_OBJECT_STORAGE=`cat $STATE_FILE | jq -r '.resources[] | select(.instances[0].attributes.name=="'${BUCKET_NAME}'") | .instances[].attributes.bucket_id'` + if [ "$TF_OBJECT_STORAGE" != "" ] && [ "$TF_OBJECT_STORAGE" != "null" ]; then + title "Delete Object Storage" + oci os bucket delete --bucket-name $BUCKET_NAME --namespace-name $TF_VAR_namespace --empty --force + else + echo "No Object storage $BUCKET_NAME" + fi } # cleanUp @@ -44,68 +44,72 @@ cleanUp() { if [ "$TF_VAR_infra_as_code" != "from_resource_manager" ]; then - # Check if there is something to destroy. - title "OCI Starter - Destroy" - echo - echo "Warning: This will destroy all the resources created by Terraform." - echo - if [ "$1" != "--auto-approve" ] && [ "$1" != "--called_by_resource_manager" ]; then - read -p "Do you want to proceed? (yes/no) " yn - case $yn in - yes ) echo Deleting;; - no ) echo Exiting...; - exit 1;; - * ) echo Invalid response; - exit 1;; - esac - fi - . starter.sh env + # Check if there is something to destroy. + title "OCI Starter - Destroy" + echo + echo "Warning: This will destroy all the resources created by Terraform." + echo + if [ "$1" != "--auto-approve" ] && [ "$1" != "--called_by_resource_manager" ]; then + read -p "Do you want to proceed? (yes/no) " yn + case $yn in + yes ) echo Deleting;; + no ) echo Exiting...; + exit 1;; + * ) echo Invalid response; + exit 1;; + esac + fi + . starter.sh env - # Check if there is something to destroy. - if [ -f $STATE_FILE ]; then - export TF_RESOURCE=`cat $STATE_FILE | jq ".resources | length"` - if [ "$TF_RESOURCE" == "0" ]; then - echo "No resource in terraform state file. Nothing to destroy." - cleanUp + # Check if there is something to destroy. + if [ -f $STATE_FILE ]; then + export TF_RESOURCE=`cat $STATE_FILE | jq ".resources | length"` + if [ "$TF_RESOURCE" == "0" ]; then + echo "No resource in terraform state file. Nothing to destroy." + cleanUp + exit 0 + fi + else + echo "File $STATE_FILE does not exist. Nothing to destroy." + cleanUp exit 0 fi - else - echo "File $STATE_FILE does not exist. Nothing to destroy." - cleanUp - exit 0 - fi - # before_destroy.sh - if [ -f src/before_destroy.sh ]; then - src/before_destroy.sh - fi + # before_destroy.sh + if [ -f src/before_destroy.sh ]; then + src/before_destroy.sh + fi - for CONFIDENTIAL_APP_OCID in `cat $STATE_FILE | jq -r '.resources[] | select(.type=="oci_identity_domains_app") | .instances[].attributes.id'`; - do - disableConfidentialApp $CONFIDENTIAL_APP_OCID - done; + for CONFIDENTIAL_APP_OCID in `cat $STATE_FILE | jq -r '.resources[] | select(.type=="oci_identity_domains_app") | .instances[].attributes.id'`; + do + disableConfidentialApp $CONFIDENTIAL_APP_OCID + done; # OKE - if [ -f $PROJECT_DIR/src/terraform/oke.tf ]; then - title "OKE Destroy" - $BIN_DIR/destroy_oke.sh --auto-approve - fi + if [ -f $PROJECT_DIR/src/terraform/oke.tf ]; then + $BIN_DIR/destroy_oke.sh --auto-approve + fi - for BUCKET_NAME in `cat $STATE_FILE | jq -r '.resources[] | select(.type=="oci_objectstorage_bucket") | .instances[].attributes.name'`; - do - cleanBucket $BUCKET_NAME - done; + # Remove created pods and httproute + if [ -d $TARGET_DIR/oke ]; then + kubectl delete -f *k8s* + fi + + for BUCKET_NAME in `cat $STATE_FILE | jq -r '.resources[] | select(.type=="oci_objectstorage_bucket") | .instances[].attributes.name'`; + do + cleanBucket $BUCKET_NAME + done; fi if [ "$1" != "--called_by_resource_manager" ]; then - title "Terraform Destroy" - $BIN_DIR/terraform_destroy.sh --auto-approve -no-color - exit_on_error "terraform_destroy.sh" + title "Terraform Destroy" + $BIN_DIR/terraform_destroy.sh --auto-approve -no-color + exit_on_error "terraform_destroy.sh" - export TF_RESOURCE=`cat $STATE_FILE | jq ".resources | length"` - if [ "$TF_RESOURCE" == "0" ]; then - cleanUp - fi + export TF_RESOURCE=`cat $STATE_FILE | jq ".resources | length"` + if [ "$TF_RESOURCE" == "0" ]; then + cleanUp + fi - echo "Destroy time: ${SECONDS} secs" + echo "Destroy time: ${SECONDS} secs" fi \ No newline at end of file diff --git a/basis/bin/destroy_oke.sh b/basis/bin/destroy_oke.sh index b10c4652..05b2d947 100755 --- a/basis/bin/destroy_oke.sh +++ b/basis/bin/destroy_oke.sh @@ -1,17 +1,16 @@ #!/usr/bin/env bash SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -. $SCRIPT_DIR/../starter.sh env -no-auto -silent -. $BIN_DIR/build_common.sh +. $SCRIPT_DIR/../starter.sh env -silent cd $PROJECT_DIR +title "OKE Destroy" + if [ ! -f $PROJECT_DIR/src/terraform/oke.tf ]; then echo "oke.tf not found" echo "Nothing to delete. This was an existing OKE installation" exit fi -echo "OKE DESTROY" - if [ "$1" != "--auto-approve" ]; then error_exit "Please call this script via ./starter.sh destroy" fi @@ -30,10 +29,11 @@ fi # The goal is to destroy all LoadBalancers created by OKE in OCI before to delete OKE. # # Delete all ingress, services -kubectl delete ingress,services --all +kubectl delete httproute,services --all +kubectl delete -f src/oke/gateway.yaml # Delete the ingress controller -helm uninstall ingress-nginx --namespace ingress-nginx +# helm uninstall ingress-nginx --namespace ingress-nginx # kubectl delete -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.4.0/deploy/static/provider/cloud/deploy.yaml # Rename kubeconfig. Avoid to reuse if a new OKE is created for the same directory. diff --git a/basis/bin/oci_starter.sh b/basis/bin/oci_starter.sh index b78febe7..9759d697 100755 --- a/basis/bin/oci_starter.sh +++ b/basis/bin/oci_starter.sh @@ -2,17 +2,20 @@ # Should be called from starter.sh if [ "$PROJECT_DIR" == "" ]; then - echo "ERROR: PROJECT_DIR not set" - exit 1 + echo "ERROR: PROJECT_DIR not set" + exit 1 fi if [ "$BIN_DIR" == "" ]; then - export BIN_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + export BIN_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) fi export TARGET_DIR=$PROJECT_DIR/target mkdir -p $TARGET_DIR/logs -DATE_POSTFIX=`date '+%Y%m%d-%H%M%S'` +if [ "$DATE_POSTFIX" == "" ]; then + DATE_POSTFIX=`date '+%Y%m%d-%H%M%S'` + START_EPOCH=`date '+%s'` +fi set -o pipefail export ARG1=$1 @@ -20,192 +23,197 @@ export ARG2=$2 export ARG3=$3 if [ -z $ARG1 ]; then - COMMAND_FILE=$TARGET_DIR/command.txt - if [ -f $COMMAND_FILE ]; then - rm $COMMAND_FILE - fi - if [ ! -f $COMMAND_FILE ]; then - python3 $BIN_DIR/starter_menu.py + COMMAND_FILE=$TARGET_DIR/command.txt if [ -f $COMMAND_FILE ]; then - COMMAND=$(cat $COMMAND_FILE) - rm $COMMAND_FILE - # Execute the command from bash to avoid issue with terminal prompt - eval "$COMMAND" + rm $COMMAND_FILE + fi + if [ ! -f $COMMAND_FILE ]; then + python3 $BIN_DIR/starter_menu.py + if [ -f $COMMAND_FILE ]; then + COMMAND=$(cat $COMMAND_FILE) + rm $COMMAND_FILE + # Execute the command from bash to avoid issue with terminal prompt + eval "$COMMAND" + fi fi - fi elif [ "$ARG1" == "help" ]; then - echo "--- BUILD ------------------------------------------------------------------------------------" - echo "./starter.sh build - Build and deploy all" - echo "./starter.sh build app - Build the application (APP)" - echo "./starter.sh build ui - Build the user interface (UI)" - echo "--- DESTROY ----------------------------------------------------------------------------------" - echo "./starter.sh destroy - Destroy all" - echo "--- SSH --------------------------------------------------------------------------------------" - echo "target/ssh_key_starter - SSH private key" - echo "./starter.sh ssh compute - SSH to compute (Deployment: Compute)" - echo "./starter.sh ssh bastion - SSH to bastion" - echo "./starter.sh ssh db_node - SSH to DB_NODE (Database: Oracle DB)" - echo "--- START/STOP -------------------------------------------------------------------------------" - echo "./starter.sh start - Start all resources" - echo "./starter.sh stop - Stop all resources" - echo "--- TERRAFORM (or RESOURCE MANAGER ) ---------------------------------------------------------" - echo "./starter.sh terraform plan - Plan" - echo "./starter.sh terraform apply - Apply" - echo "./starter.sh terraform destroy - Destroy" - echo "--- GENERATE ---------------------------------------------------------------------------------" - echo "./starter.sh generate auth_token - Create OCI Auth Token (ex: docker login)" - echo "--- DEPLOY -----------------------------------------------------------------------------------" - echo "./starter.sh deploy bastion - Deploy the bastion (+create DB tables)" - echo "./starter.sh deploy compute - Deploy APP and UI on Compute (Deployment: Compute)" - echo "./starter.sh deploy oke - Deploy APP and UI on OKE (Deployment: Kubernetes)" - echo "--- KUBECTL ----------------------------------------------------------------------------------" - echo "./starter.sh env - Set environment variable like KUBECONFIG for Kubernetes" - echo "kubectl get pods - Example of a command to check the PODs" - echo "--- LOGS -------------------------------------------------------------------------------------" - echo "cat target/build.log - Show last build log" - echo "cat target/destroy.log - Show last destroy log" - echo "--- HELP -------------------------------------------------------------------------------------" - echo "https://www.ocistarter.com/" - echo "https://www.ocistarter.com/help (tutorial + how to customize)" - echo - exit + echo "--- BUILD ------------------------------------------------------------------------------------" + echo "./starter.sh build - Build and deploy all" + echo "./starter.sh build app - Build the application (APP)" + echo "./starter.sh build ui - Build the user interface (UI)" + echo "--- DESTROY ----------------------------------------------------------------------------------" + echo "./starter.sh destroy - Destroy all" + echo "--- SSH --------------------------------------------------------------------------------------" + echo "target/ssh_key_starter - SSH private key" + echo "./starter.sh ssh compute - SSH to compute (Deployment: Compute)" + echo "./starter.sh ssh bastion - SSH to bastion" + echo "./starter.sh ssh db_node - SSH to DB_NODE (Database: Oracle DB)" + echo "--- START/STOP -------------------------------------------------------------------------------" + echo "./starter.sh start - Start all resources" + echo "./starter.sh stop - Stop all resources" + echo "--- TERRAFORM (or RESOURCE MANAGER ) ---------------------------------------------------------" + echo "./starter.sh terraform plan - Plan" + echo "./starter.sh terraform apply - Apply" + echo "./starter.sh terraform destroy - Destroy" + echo "--- GENERATE ---------------------------------------------------------------------------------" + echo "./starter.sh generate auth_token - Create OCI Auth Token (ex: docker login)" + echo "--- DEPLOY -----------------------------------------------------------------------------------" + echo "./starter.sh deploy bastion - Deploy the bastion (+create DB tables)" + echo "./starter.sh deploy compute - Deploy APP and UI on Compute (Deployment: Compute)" + echo "./starter.sh deploy oke - Deploy APP and UI on OKE (Deployment: Kubernetes)" + echo "--- KUBECTL ----------------------------------------------------------------------------------" + echo "./starter.sh env - Set environment variable like KUBECONFIG for Kubernetes" + echo "kubectl get pods - Example of a command to check the PODs" + echo "--- LOGS -------------------------------------------------------------------------------------" + echo "cat target/build.log - Show last build log" + echo "cat target/destroy.log - Show last destroy log" + echo "--- HELP -------------------------------------------------------------------------------------" + echo "https://www.ocistarter.com/" + echo "https://www.ocistarter.com/help (tutorial + how to customize)" + echo + exit elif [ "$ARG1" == "build" ]; then - if [ "$ARG2" == "app" ]; then - # Build all apps - for APP_NAME in `app_name_list_build`; do - src/app/$APP_NAME/build.sh ${@:2} - exit_on_error "Build App $APP_NAME" - done - elif [ "$ARG2" == "ui" ]; then - $PROJECT_DIR/src/app/build_ui.sh ${@:2} - else - export LOG_NAME=$TARGET_DIR/logs/build.${DATE_POSTFIX}.log - # Show the log and save it to target/build.log and target/logs - ln -sf $LOG_NAME $TARGET_DIR/build.log - $BIN_DIR/build_all.sh ${@:2} 2>&1 | tee $LOG_NAME - fi + if [ "$ARG2" == "app" ]; then + # Build all apps + for APP_NAME in `app_name_list_build`; do + src/app/$APP_NAME/build.sh ${@:2} + exit_on_error "Build App $APP_NAME" + done + elif [ "$ARG2" == "ui" ]; then + $PROJECT_DIR/src/app/build_ui.sh ${@:2} + else + export LOG_NAME=$TARGET_DIR/logs/build.${DATE_POSTFIX}.log + # Show the log and save it to target/build.log and target/logs + ln -sf $LOG_NAME $TARGET_DIR/build.log + $BIN_DIR/build_all.sh ${@:2} 2>&1 | tee $LOG_NAME + fi elif [ "$ARG1" == "rm" ]; then - if [ "$ARG2" == "build" ]; then - export TF_VAR_infra_as_code="build_resource_manager" - $BIN_DIR/terraform_apply.sh - elif [ "$ARG2" == "create" ]; then - export TF_VAR_infra_as_code="create_resource_manager" - $BIN_DIR/terraform_apply.sh - elif [ "$ARG2" == "" ]; then - export TF_VAR_infra_as_code="distribute_resource_manager" - $BIN_DIR/terraform_apply.sh - else - echo "Unknown command: $ARG1 $ARG2" - fi + if [ "$ARG2" == "build" ]; then + export TF_VAR_infra_as_code="build_resource_manager" + $BIN_DIR/terraform_apply.sh + elif [ "$ARG2" == "create" ]; then + export TF_VAR_infra_as_code="create_resource_manager" + $BIN_DIR/terraform_apply.sh + elif [ "$ARG2" == "" ]; then + export TF_VAR_infra_as_code="distribute_resource_manager" + $BIN_DIR/terraform_apply.sh + else + echo "Unknown command: $ARG1 $ARG2" + fi elif [ "$ARG1" == "destroy" ]; then - if [ -f $TARGET_DIR/resource_manager_stackid ]; then - # From the shell that created a RM Stack - $BIN_DIR/terraform_destroy.sh - elif [ "$TF_VAR_infra_as_code" == "from_resource_manager" ] && [ "$2" != "--called_by_resource_manager" ]; then - # ./starter.sh destroy - # - with terraform stack in resource_manager (=from_resource_manager) - # - called from Command Line - # - and not called by the resource_manager - $BIN_DIR/terraform_destroy.sh - else - LOG_NAME=$TARGET_DIR/logs/destroy.${DATE_POSTFIX}.log - # Show the log and save it to target/build.log and target/logs - ln -sf $LOG_NAME $TARGET_DIR/destroy.log - $BIN_DIR/destroy_all.sh ${@:2} 2>&1 | tee $LOG_NAME - fi + if [ -f $TARGET_DIR/resource_manager_stackid ]; then + # From the shell that created a RM Stack + $BIN_DIR/terraform_destroy.sh + elif [ "$TF_VAR_infra_as_code" == "from_resource_manager" ] && [ "$2" != "--called_by_resource_manager" ]; then + # ./starter.sh destroy + # - with terraform stack in resource_manager (=from_resource_manager) + # - called from Command Line + # - and not called by the resource_manager + $BIN_DIR/terraform_destroy.sh + else + LOG_NAME=$TARGET_DIR/logs/destroy.${DATE_POSTFIX}.log + # Show the log and save it to target/build.log and target/logs + ln -sf $LOG_NAME $TARGET_DIR/destroy.log + $BIN_DIR/destroy_all.sh ${@:2} 2>&1 | tee $LOG_NAME + fi elif [ "$ARG1" == "ssh" ]; then - if [ "$ARG2" == "compute" ]; then - $BIN_DIR/ssh_compute.sh - elif [ "$ARG2" == "bastion" ]; then - $BIN_DIR/ssh_bastion.sh - elif [ "$ARG2" == "db_node" ]; then - $BIN_DIR/ssh_db_node.sh - else - echo "Unknown command: $ARG1 $ARG2" - fi + if [ "$ARG2" == "compute" ]; then + $BIN_DIR/ssh_compute.sh + elif [ "$ARG2" == "bastion" ]; then + $BIN_DIR/ssh_bastion.sh + elif [ "$ARG2" == "db_node" ]; then + $BIN_DIR/ssh_db_node.sh + else + echo "Unknown command: $ARG1 $ARG2" + fi elif [ "$ARG1" == "rebuild" ]; then - . $BIN_DIR/shared_bash_function.sh + . $BIN_DIR/shared_bash_function.sh - # Destroy - LOG_NAME=$TARGET_DIR/logs/destroy.${DATE_POSTFIX}.log - ln -sf $LOG_NAME $TARGET_DIR/destroy.log - $BIN_DIR/destroy_all.sh ${@:2} 2>&1 | tee $LOG_NAME - exit_on_error "destroy_all.sh" - - # Double check - if [ -f $TARGET_DIR ]; then - error_exit "target dir is still there..." - fi + # Destroy + LOG_NAME=$TARGET_DIR/logs/destroy.${DATE_POSTFIX}.log + ln -sf $LOG_NAME $TARGET_DIR/destroy.log + $BIN_DIR/destroy_all.sh ${@:2} 2>&1 | tee $LOG_NAME + exit_on_error "destroy_all.sh" + + # Double check + if [ -f $TARGET_DIR ]; then + error_exit "target dir is still there..." + fi - # Pull - git pull - exit_on_error "git pull" - - # Cleanup target dir - mkdir -p $TARGET_DIR/logs + # Pull + git pull + exit_on_error "git pull" + + # Cleanup target dir + mkdir -p $TARGET_DIR/logs - # Build - LOG_NAME=$TARGET_DIR/logs/build.${DATE_POSTFIX}.log - ln -sf $LOG_NAME $TARGET_DIR/build.log - $BIN_DIR/build_all.sh ${@:2} 2>&1 | tee $LOG_NAME + # Build + LOG_NAME=$TARGET_DIR/logs/build.${DATE_POSTFIX}.log + ln -sf $LOG_NAME $TARGET_DIR/build.log + $BIN_DIR/build_all.sh ${@:2} 2>&1 | tee $LOG_NAME elif [ "$ARG1" == "terraform" ]; then - if [ "$ARG2" == "plan" ]; then - $BIN_DIR/terraform_plan.sh ${@:3} - elif [ "$ARG2" == "apply" ]; then - $BIN_DIR/terraform_apply.sh ${@:3} - elif [ "$ARG2" == "destroy" ]; then - $BIN_DIR/terraform_destroy.sh ${@:3} - else - echo "Unknown command: $ARG1 $ARG2" - fi + if [ "$ARG2" == "plan" ]; then + $BIN_DIR/terraform_plan.sh ${@:3} + elif [ "$ARG2" == "apply" ]; then + $BIN_DIR/terraform_apply.sh ${@:3} + elif [ "$ARG2" == "destroy" ]; then + $BIN_DIR/terraform_destroy.sh ${@:3} + else + echo "Unknown command: $ARG1 $ARG2" + fi elif [ "$ARG1" == "frm" ]; then # From Resource Manager - . $BIN_DIR/shared_bash_function.sh - export CALLED_BY_TERRAFORM="TRUE" + . $BIN_DIR/shared_bash_function.sh + export CALLED_BY_TERRAFORM="TRUE" - if [ "$ARG2" == "before_terraform" ]; then - export LOG_NAME=$TARGET_DIR/frm_before_terraform.log - $BIN_DIR/build_all.sh --before_terraform | tee $LOG_NAME - exit_on_error "build_all.sh --before_terraform" - fi - . shared_infra_as_code.sh - . ./starter.sh env -silent - resource_manager_variables_json + if [ "$ARG2" == "before_terraform" ]; then + export LOG_NAME=$TARGET_DIR/frm_before_terraform.log + $BIN_DIR/build_all.sh --before_terraform | tee $LOG_NAME + exit_on_error "build_all.sh --before_terraform" + fi + . shared_infra_as_code.sh + . ./starter.sh env -silent + resource_manager_variables_json elif [ "$ARG1" == "start" ]; then $BIN_DIR/start_stop.sh start $ARG1 $ARG2 elif [ "$ARG1" == "stop" ]; then $BIN_DIR/start_stop.sh start $ARG1 $ARG2 elif [ "$ARG1" == "generate" ]; then - if [ "$ARG2" == "auth_token" ]; then - $BIN_DIR/gen_auth_token.sh - else - echo "Unknown command: $ARG1 $ARG2" - fi + if [ "$ARG2" == "auth_token" ]; then + $BIN_DIR/gen_auth_token.sh + else + echo "Unknown command: $ARG1 $ARG2" + fi elif [ "$ARG1" == "deploy" ]; then - if [ "$ARG2" == "compute" ]; then - $BIN_DIR/deploy_compute.sh - elif [ "$ARG2" == "bastion" ]; then - $BIN_DIR/deploy_bastion.sh - else - echo "Unknown command: $ARG1 $ARG2" - exit 1 - fi + if [ "$ARG2" == "compute" ]; then + $BIN_DIR/deploy_compute.sh + elif [ "$ARG2" == "bastion" ]; then + $BIN_DIR/deploy_bastion.sh + else + echo "Unknown command: $ARG1 $ARG2" + exit 1 + fi elif [ "$ARG1" == "env" ]; then - # Check if sourced or not - (return 0 2>/dev/null) && SOURCED=1 || SOURCED=0 - if [ "$SOURCED" == "1" ]; then - . $BIN_DIR/auto_env.sh ${@:2} - return - else - bash --rcfile $BIN_DIR/auto_env.sh ${@:2} - fi + # Check if sourced or not + (return 0 2>/dev/null) && SOURCED=1 || SOURCED=0 + if [ "$SOURCED" == "1" ]; then + . $BIN_DIR/auto_env.sh ${@:2} + return + else + bash --rcfile $BIN_DIR/auto_env.sh ${@:2} + fi elif [ "$ARG1" == "upgrade" ]; then - $BIN_DIR/upgrade.sh + $BIN_DIR/upgrade.sh else - echo "Unknown command: $ARG1" - exit 1 + echo "Unknown command: $ARG1" + exit 1 fi + +now_epoch=$(date +%s) +elapsed=$((now_epoch - START_EPOCH)) +echo "Elapsed time: ${elapsed} secs" + # Return the exit code -exit ${PIPESTATUS[0]} \ No newline at end of file +exit ${PIPESTATUS[0]} diff --git a/basis/bin/shared_bash_function.sh b/basis/bin/shared_bash_function.sh index 58907d76..6e7bdc91 100755 --- a/basis/bin/shared_bash_function.sh +++ b/basis/bin/shared_bash_function.sh @@ -58,7 +58,7 @@ build_function() { # Create KUBECONFIG file create_kubeconfig() { oci ce cluster create-kubeconfig --cluster-id $OKE_OCID --file $KUBECONFIG --region $TF_VAR_region --token-version 2.0.0 --kube-endpoint PUBLIC_ENDPOINT - exit_on_error "create_kubeconfig - failed.... $OKE_OCID / $TF_VAR_region" + exit_on_error "create_kubeconfig - $OKE_OCID / $TF_VAR_region" chmod 600 $KUBECONFIG } @@ -285,8 +285,8 @@ get_ui_url() { if [ ! -f $KUBECONFIG ]; then create_kubeconfig fi - export TF_VAR_ingress_ip=`kubectl get service -n ingress-nginx ingress-nginx-controller -o jsonpath="{.status.loadBalancer.ingress[0].ip}"` - export UI_URL=http://${TF_VAR_ingress_ip}/${TF_VAR_prefix} + oke_get_gateway_ip + export UI_URL=http://${TF_VAR_gateway_ip}/${TF_VAR_prefix} if [ "$TF_VAR_tls" != "" ] && [ "$TF_VAR_dns_name" != "" ]; then export UI_HTTP=$UI_URL export UI_URL=https://${TF_VAR_dns_name}/${TF_VAR_prefix} @@ -589,7 +589,7 @@ certificate_post_deploy() { echo "Skip: TLS - Kubernetes - HTTP_01" fi elif [ "$TF_VAR_deploy_type" == "kubernetes" ]; then - # Set the TF_VAR_ingress_ip + # Set the TF_VAR_gateway_ip get_ui_url $BIN_DIR/terraform_apply.sh --auto-approve -no-color exit_on_error "certificate_post_deploy - terraform apply" diff --git a/basis/bin/upgrade.sh b/basis/bin/upgrade.sh index df2b4b3e..9dc3d302 100755 --- a/basis/bin/upgrade.sh +++ b/basis/bin/upgrade.sh @@ -83,7 +83,7 @@ if [ -f src/terraform/build.tf ]; then # Output the required export command echo "export $KEY=\"$VALUE\"" export $KEY=$VALUE - else + elif [[ "$LINE" =~ chmod ]]; then # Stop reading when a line does not match the expected pattern PARSING_STATE=2 break diff --git a/basis/src/app/rest/k8s-httproute.j2.yaml b/basis/src/app/rest/k8s-httproute.j2.yaml new file mode 100644 index 00000000..92947e96 --- /dev/null +++ b/basis/src/app/rest/k8s-httproute.j2.yaml @@ -0,0 +1,91 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: ##TF_VAR_prefix##-rest-route +spec: + parentRefs: + - name: oke-gateway + hostnames: +{%- if tls == "new_http_01" %} + - "##TF_VAR_dns_name##" +{%- endif %} + rules: + - matches: + - path: + type: PathPrefix + value: /##TF_VAR_prefix##/app + filters: +{%- if language in [ "apex", "ords" ] %} + - type: RequestHeaderModifier + requestHeaderModifier: + set: + - name: Host + value: ##ORDS_HOST## +{%- endif %} + +{%- if language == "apex" %} + - type: URLRewrite + urlRewrite: + path: + type: ReplacePrefixMatch + replacePrefixMatch: /ords/r/apex_app/apex_app + +{%- elif language == "ords" %} + - type: URLRewrite + urlRewrite: + path: + type: ReplacePrefixMatch + replacePrefixMatch: /ords/starter/module + +{%- elif language == "java" and java_framework == "tomcat" %} + - type: URLRewrite + urlRewrite: + path: + type: ReplacePrefixMatch + replacePrefixMatch: /starter-1.0 + +{%- else %} + - type: URLRewrite + urlRewrite: + path: + type: ReplacePrefixMatch + replacePrefixMatch: / + +{%- endif %} + + backendRefs: + - name: ##TF_VAR_prefix##-rest-service + port: +{%- if language in [ "apex", "ords" ] %} + 443 +{%- else %} + 80 +{%- endif %} + +{%- if language in [ "apex", "ords" ] %} +--- +apiVersion: networking.istio.io/v1beta1 +kind: ServiceEntry +metadata: + name: ##TF_VAR_prefix##-service-entry +spec: + hosts: + - ##ORDS_HOST## + ports: + - number: 443 + name: https + protocol: HTTPS + resolution: DNS + location: MESH_EXTERNAL +--- +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: ##TF_VAR_prefix##-destination-rule +spec: + host: ##ORDS_HOST## + trafficPolicy: + tls: + mode: SIMPLE + sni: ##ORDS_HOST## +{%- endif %} \ No newline at end of file diff --git a/basis/src/app/rest/k8s-ingress.j2.yaml b/basis/src/app/rest/k8s-ingress.j2.yaml deleted file mode 100644 index 809e259d..00000000 --- a/basis/src/app/rest/k8s-ingress.j2.yaml +++ /dev/null @@ -1,47 +0,0 @@ -# Use 2 Ingress since the parameter replacement work differently in NGINX for / and /app (see annotation) -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: ##TF_VAR_prefix##-rest-ingress - annotations: -{%- if language == "apex" %} - nginx.ingress.kubernetes.io/rewrite-target: /ords/r/apex_app/apex_app/$2 - nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" - nginx.ingress.kubernetes.io/upstream-vhost: "##ORDS_HOST##" -{%- elif language == "ords" %} - nginx.ingress.kubernetes.io/rewrite-target: /ords/starter/module/$2 - nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" - nginx.ingress.kubernetes.io/upstream-vhost: "##ORDS_HOST##" -{%- elif language == "java" and java_framework == "tomcat" %} - nginx.ingress.kubernetes.io/rewrite-target: /starter-1.0/$2 -{%- else %} - nginx.ingress.kubernetes.io/rewrite-target: /$2 -{%- endif %} - # nginx.ingress.kubernetes.io/affinity: "cookie" - # nginx.ingress.kubernetes.io/session-cookie-path: "/" -spec: - ingressClassName: nginx -{%- if tls == "new_http_01" %} - tls: - - hosts: - - ##TF_VAR_dns_name## - secretName: ##TF_VAR_prefix##-tls-secret - rules: - - host: ##TF_VAR_dns_name## - http: -{%- else %} - rules: - - http: -{%- endif %} - paths: - - path: /##TF_VAR_prefix##/app(/|$)(.*) - pathType: ImplementationSpecific - backend: - service: - name: ##TF_VAR_prefix##-rest-service - port: -{%- if language in [ "apex", "ords" ] %} - number: 443 -{%- else %} - number: 80 -{%- endif %} diff --git a/basis/src/app/rest/k8s.j2.yaml b/basis/src/app/rest/k8s.j2.yaml index f7f096a0..36f7f179 100644 --- a/basis/src/app/rest/k8s.j2.yaml +++ b/basis/src/app/rest/k8s.j2.yaml @@ -66,6 +66,30 @@ spec: secretKeyRef: name: {{ prefix }}-db-secret key: TF_VAR_nosql_endpoint +{%- endif %} +{%- if python_framework in [ "langgraph", "responses" ] %} + - name: TF_VAR_region + valueFrom: + configMapKeyRef: + name: tf-env-configmap + key: TF_VAR_region + - name: TF_VAR_compartment_ocid + valueFrom: + configMapKeyRef: + name: tf-env-configmap + key: TF_VAR_compartment_ocid +{%- endif %} +{%- if python_framework == "langgraph" %} + - name: MCP_SERVER_URL + value: "http://{{ prefix }}-mcp-server-service:2025/mcp" +{%- elif python_framework == "responses" %} + - name: TF_VAR_project_ocid + valueFrom: + configMapKeyRef: + name: tf-env-configmap + key: TF_VAR_project_ocid + - name: MCP_SERVER_URL + value: "http://##TF_VAR_gateway_ip##/##TF_VAR_prefix##/mcp_server/mcp" {%- endif %} imagePullSecrets: - name: ocirsecret diff --git a/basis/src/app/ui/k8s-httproute.j2.yaml b/basis/src/app/ui/k8s-httproute.j2.yaml new file mode 100644 index 00000000..3d354d3f --- /dev/null +++ b/basis/src/app/ui/k8s-httproute.j2.yaml @@ -0,0 +1,32 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: ##TF_VAR_prefix##-ui-route +{%- if tls == "new_http_01" %} + annotations: + # These remain controller-specific (not part of Gateway API) + cert-manager.io/issuer: "letsencrypt-prod" + external-dns.alpha.kubernetes.io/hostname: ##TF_VAR_dn_name## +{%- endif %} +spec: + parentRefs: + - name: oke-gateway +{%- if tls == "new_http_01" %} + hostnames: + - "##TF_VAR_dn_name##" +{%- endif %} + rules: + - matches: + - path: + type: PathPrefix + value: /##TF_VAR_prefix## + filters: + - type: URLRewrite + urlRewrite: + path: + type: ReplacePrefixMatch + replacePrefixMatch: / + backendRefs: + - name: ##TF_VAR_prefix##-ui-service + port: 80 + diff --git a/basis/src/app/ui/k8s-ingress.j2.yaml b/basis/src/app/ui/k8s-ingress.j2.yaml deleted file mode 100644 index 36a793be..00000000 --- a/basis/src/app/ui/k8s-ingress.j2.yaml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: ##TF_VAR_prefix##-ui-ingress - annotations: - nginx.ingress.kubernetes.io/rewrite-target: /$2 - # nginx.ingress.kubernetes.io/affinity: "cookie" - # nginx.ingress.kubernetes.io/session-cookie-path: "/" -{%- if tls == "new_http_01" %} - cert-manager.io/issuer: "letsencrypt-prod" - # Logs: - # - kubectl get certificate - # - kubectl get certificaterequest - # - kubectl describe issuer letsencrypt-prod - external-dns.alpha.kubernetes.io/hostname: ##TF_VAR_dn_name## - # Logs: kubectl logs external-dns-xxxx -{%- endif %} -spec: - ingressClassName: nginx -{%- if tls == "new_http_01" %} - tls: - - hosts: - - ##TF_VAR_dn_name## - secretName: ##TF_VAR_prefix##-tls-secret - rules: - - host: ##TF_VAR_dn_name## - http: -{%- else %} - rules: - - http: -{%- endif %} - paths: - - path: /##TF_VAR_prefix##(/|$)(.*) - pathType: ImplementationSpecific - backend: - service: - name: ##TF_VAR_prefix##-ui-service - port: - number: 80 diff --git a/basis/src/done.j2.sh b/basis/src/done.j2.sh index 5477edd4..107a9615 100755 --- a/basis/src/done.j2.sh +++ b/basis/src/done.j2.sh @@ -18,8 +18,12 @@ if [ "$UI_URL" != "" ]; then if [ "$UI_HTTP" != "" ]; then append_done "- HTTP : $UI_HTTP/" fi - append_done "- REST: $UI_URL/app/dept" - append_done "- REST: $UI_URL/app/info" + if [ "$TF_VAR_ui_type" == "langgraph" ]; then + append_done "- REST: $UI_URL/app/threads" + else + append_done "- REST: $UI_URL/app/dept" + append_done "- REST: $UI_URL/app/info" + fi {%- if language=="java" and java_framework=="tomcat" %} append_done "- REST: $UI_URL/app/index.jsp" {%- endif %} diff --git a/option/oke/gateway.j2.yaml b/option/oke/gateway.j2.yaml new file mode 100644 index 00000000..99b8b7f8 --- /dev/null +++ b/option/oke/gateway.j2.yaml @@ -0,0 +1,27 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: oke-gateway + namespace: default + annotations: + # OCI specific annotation for Network Load Balancer (Layer 4) + oci.oraclecloud.com/load-balancer-type: "nlb" +spec: + gatewayClassName: istio + listeners: + - name: http + port: 80 + protocol: HTTP + allowedRoutes: + namespaces: + from: Same +{%- if tls == "new_http_01" %} + - name: https + port: 443 + protocol: HTTPS + hostname: ##TF_VAR_dns_name## + tls: + mode: Terminate + certificateRefs: + - name: ##TF_VAR_prefix##-tls-secret +{%- endif %} \ No newline at end of file diff --git a/option/oke/istio_addon.json b/option/oke/istio_addon.json new file mode 100644 index 00000000..479e39fc --- /dev/null +++ b/option/oke/istio_addon.json @@ -0,0 +1,9 @@ +{ + "addonName": "Istio", + "configurations": [ + { + "key": "enableIngressGateway", + "value": "false" + } + ] +} \ No newline at end of file diff --git a/option/src/app/java_micronaut/rest/pom.j2.xml b/option/src/app/java_micronaut/rest/pom.j2.xml index 58809f95..d2ac012e 100644 --- a/option/src/app/java_micronaut/rest/pom.j2.xml +++ b/option/src/app/java_micronaut/rest/pom.j2.xml @@ -10,13 +10,13 @@ io.micronaut.platform micronaut-parent - 4.2.1 + 4.10.12 jar 17 17 - 4.2.1 + 4.10.12 false com.example.aot.generated true diff --git a/option/src/app/python_langgraph/after_auto_env.sh b/option/src/app/python_langgraph/after_auto_env.sh deleted file mode 100644 index 530540e9..00000000 --- a/option/src/app/python_langgraph/after_auto_env.sh +++ /dev/null @@ -1,9 +0,0 @@ -XXXXX -# Kubernetes -if [ "$TF_VAR_deploy_type" == "kubernetes" ]; then - append_tf_env "export LANGGRAPH_URL=\"http://langgraph-service:2024\"" - append_tf_env "export MCP_SERVER_URL=\"http://mcp-server-service:2025/mcp\"" -else - append_tf_env "export LANGGRAPH_URL=\"http://127.0.0.1:2024\"" - append_tf_env "export MCP_SERVER_URL=\"http://localhost:2025/mcp\"" -fi \ No newline at end of file diff --git a/option/src/app/python_langgraph/rest/Dockerfile b/option/src/app/python_langgraph/rest/Dockerfile new file mode 100644 index 00000000..46ac0606 --- /dev/null +++ b/option/src/app/python_langgraph/rest/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3-bookworm + +RUN pip install --upgrade pip + +WORKDIR /app +ENV PATH="/app/.local/bin:${PATH}" +COPY ./ /app/ +RUN pip3 install -r requirements.txt +WORKDIR "/app/agent" +ENTRYPOINT ["langgraph", "dev", "--port", "8080", "--host", "0.0.0.0"] + diff --git a/option/src/app/python_langgraph/rest/agent/agent.py b/option/src/app/python_langgraph/rest/agent/agent.py index 65097339..1afe4838 100644 --- a/option/src/app/python_langgraph/rest/agent/agent.py +++ b/option/src/app/python_langgraph/rest/agent/agent.py @@ -16,6 +16,7 @@ MCP_SERVER_URL = os.getenv("MCP_SERVER_URL") or "http://localhost:2025/mcp" if REGION == "eu-amsterdam-1": REGION = "eu-frankfurt-1" +AUTH_TYPE = os.getenv("AUTH_TYPE") or "INSTANCE_PRINCIPAL" # auth = oci_openai.OciInstancePrincipalAuth() # llm = ChatOpenAI( @@ -29,7 +30,7 @@ # ) llm = ChatOCIGenAI( - auth_type="API_KEY" if "LIVELABS" in os.environ else "INSTANCE_PRINCIPAL", + auth_type="API_KEY" if "LIVELABS" in os.environ else AUTH_TYPE, model_id="openai.gpt-oss-120b", # model_id="meta.llama-4-scout-17b-16e-instruct", # model_id="cohere.command-a-03-2025", diff --git a/option/src/app/python_langgraph/rest/start.sh b/option/src/app/python_langgraph/rest/start.sh index 6870493a..c1ba1a95 100755 --- a/option/src/app/python_langgraph/rest/start.sh +++ b/option/src/app/python_langgraph/rest/start.sh @@ -4,6 +4,7 @@ cd $SCRIPT_DIR export PATH=~/.local/bin/:$PATH . $HOME/compute/tf_env.sh +export MCP_SERVER_URL="http://localhost:2025/mcp" # Start LangGraph CompiledStateGraph on port 2024 source myenv/bin/activate diff --git a/option/src/app/python_mcp_server/mcp_server/k8s-httproute.j2.yaml b/option/src/app/python_mcp_server/mcp_server/k8s-httproute.j2.yaml new file mode 100644 index 00000000..1c01fe81 --- /dev/null +++ b/option/src/app/python_mcp_server/mcp_server/k8s-httproute.j2.yaml @@ -0,0 +1,25 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: ##TF_VAR_prefix##-mcp-server-route +spec: + parentRefs: + - name: oke-gateway +{%- if tls == "new_http_01" %} + hostnames: + - "##TF_VAR_dns_name##" +{%- endif %} + rules: + - matches: + - path: + type: PathPrefix + value: /##TF_VAR_prefix##/mcp_server + filters: + - type: URLRewrite + urlRewrite: + path: + type: ReplacePrefixMatch + replacePrefixMatch: / + backendRefs: + - name: ##TF_VAR_prefix##-mcp-server-service + port: 2025 \ No newline at end of file diff --git a/option/src/app/python_mcp_server/mcp_server/k8s-ingress.j2.yaml b/option/src/app/python_mcp_server/mcp_server/k8s-ingress.j2.yaml deleted file mode 100644 index b97fe1a5..00000000 --- a/option/src/app/python_mcp_server/mcp_server/k8s-ingress.j2.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# Use 2 Ingress since the parameter replacement work differently in NGINX for / and /app (see annotation) -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: ##TF_VAR_prefix##-mcp-server-ingress - annotations: - nginx.ingress.kubernetes.io/rewrite-target: /$2 - # nginx.ingress.kubernetes.io/affinity: "cookie" - # nginx.ingress.kubernetes.io/session-cookie-path: "/" -spec: - ingressClassName: nginx -{%- if tls == "new_http_01" %} - tls: - - hosts: - - ##TF_VAR_dns_name## - secretName: ##TF_VAR_prefix##-tls-secret - rules: - - host: ##TF_VAR_dns_name## - http: -{%- else %} - rules: - - http: -{%- endif %} - paths: - - path: /##TF_VAR_prefix##/mcp_server(/|$)(.*) - pathType: ImplementationSpecific - backend: - service: - name: ##TF_VAR_prefix##-mcp-server-service - port: - number: 2025 diff --git a/option/src/app/python_mcp_server/mcp_server/k8s.j2.yaml b/option/src/app/python_mcp_server/mcp_server/k8s.j2.yaml index 807cd7f1..4a729480 100644 --- a/option/src/app/python_mcp_server/mcp_server/k8s.j2.yaml +++ b/option/src/app/python_mcp_server/mcp_server/k8s.j2.yaml @@ -1,7 +1,7 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: {{ prefix }}-dep + name: {{ prefix }}-mcp-server-dep labels: app: {{ prefix }}-mcp-server spec: @@ -16,7 +16,7 @@ spec: spec: containers: - name: app - image: ##DOCKER_PREFIX##/{{ prefix }}-mcp-server:##DOCKER_IMG_VERSION## + image: ##DOCKER_PREFIX##/{{ prefix }}-mcp_server:##DOCKER_IMG_VERSION## ports: - containerPort: 2025 name: app-port diff --git a/option/src/app/python_mcp_server/mcp_server/mcp_server.py b/option/src/app/python_mcp_server/mcp_server/mcp_server.py index 8199fa96..89edc5ac 100644 --- a/option/src/app/python_mcp_server/mcp_server/mcp_server.py +++ b/option/src/app/python_mcp_server/mcp_server/mcp_server.py @@ -24,8 +24,8 @@ def send_email(to: str, subject: str, body: str) -> dict[str, str]: def get_dept() -> list[dict[str, Any]]: """Return all rows from the DEPT table.""" log( "") - user = os.getenv("TF_VAR_db_user") - password = os.getenv("TF_VAR_db_password") + user = os.getenv("DB_USER") + password = os.getenv("DB_PASSWORD") dsn = os.getenv("DB_URL") if not user or not password or not dsn: diff --git a/option/src/app/python_mcp_server/mcp_server/requirements.txt b/option/src/app/python_mcp_server/mcp_server/requirements.txt index 18c5c56d..a4213de4 100644 --- a/option/src/app/python_mcp_server/mcp_server/requirements.txt +++ b/option/src/app/python_mcp_server/mcp_server/requirements.txt @@ -4,13 +4,5 @@ fastmcp #DB26ai oracledb -# Langgraph -langchain_oci -langchain_community -langchain_openai -oci-openai -langgraph-cli[inmem] -langchain_mcp_adapters - # OAuth Caching aiocache \ No newline at end of file diff --git a/option/src/app/python_responses/rest/responses.py b/option/src/app/python_responses/rest/rest.py similarity index 97% rename from option/src/app/python_responses/rest/responses.py rename to option/src/app/python_responses/rest/rest.py index d6a60564..4ee475a6 100644 --- a/option/src/app/python_responses/rest/responses.py +++ b/option/src/app/python_responses/rest/rest.py @@ -7,7 +7,7 @@ from fastapi.responses import StreamingResponse # OCI Auth -from oci_genai_auth import OciInstancePrincipalAuth +from oci_genai_auth import OciInstancePrincipalAuth, OciResourcePrincipalAuth import httpx REGION = os.getenv("TF_VAR_region") @@ -16,6 +16,10 @@ MODEL_ID = "openai.gpt-oss-120b" # REGION = "us-chicago-1" # MODEL_ID = "xai.grok-4-fast-non-reasoning" +if os.getenv("AUTH_TYPE")=="RESOURCE_PRINCIPAL": + auth = OciResourcePrincipalAuth() +else: + auth = OciInstancePrincipalAuth() PROJECT_OCID = os.environ.get("TF_VAR_project_ocid") COMPARTMENT_OCID = os.environ.get("TF_VAR_compartment_ocid") @@ -33,7 +37,7 @@ base_url=f"https://inference.generativeai.{REGION}.oci.oraclecloud.com/20231130/openai/v1", api_key="unused", http_client=httpx.Client( - auth=OciInstancePrincipalAuth(), + auth=auth, headers={ "opc-compartment-id": COMPARTMENT_OCID, }, diff --git a/option/src/app/python_responses/rest/start.j2.sh b/option/src/app/python_responses/rest/start.j2.sh new file mode 100755 index 00000000..36a934d4 --- /dev/null +++ b/option/src/app/python_responses/rest/start.j2.sh @@ -0,0 +1,16 @@ +#!/bin/bash +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +cd $SCRIPT_DIR +export PATH=~/.local/bin/:$PATH + +. $HOME/compute/tf_env.sh + +{%- if deploy_type == "public_compute" %} +export MCP_SERVER_URL="http://$BASTION_IP/mcp_server/mcp" +{%- else %} +export MCP_SERVER_URL="https://$APIGW_HOSTNAME/$TF_VAR_prefix/mcp_server/mcp" +{%- endif %} + +# Default port is 2025 +source myenv/bin/activate +python rest.py 2>&1 | tee rest.log diff --git a/option/src/app/python_responses/rest/start.sh b/option/src/app/python_responses/rest/start.sh deleted file mode 100755 index ee83b8cc..00000000 --- a/option/src/app/python_responses/rest/start.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -cd $SCRIPT_DIR -export PATH=~/.local/bin/:$PATH - -. $HOME/compute/tf_env.sh - -# Default port is 2025 -source myenv/bin/activate -python responses.py 2>&1 | tee rest.log diff --git a/option/src/app/python_responses/ui/nginx_app.locations b/option/src/app/python_responses/ui/nginx_app.locations new file mode 100644 index 00000000..1880c950 --- /dev/null +++ b/option/src/app/python_responses/ui/nginx_app.locations @@ -0,0 +1,11 @@ + + location /app/ { + proxy_http_version 1.1; + proxy_pass http://localhost:8080/; + } + + location /mcp_server/ { + proxy_http_version 1.1; + proxy_pass http://localhost:2025/; + } + diff --git a/option/src/ui/langgraph/ui/html/chat.css b/option/src/ui/langgraph/ui/html/chat.css index dc5220e6..61ebac31 100644 --- a/option/src/ui/langgraph/ui/html/chat.css +++ b/option/src/ui/langgraph/ui/html/chat.css @@ -82,9 +82,14 @@ body { border-bottom-right-radius: 18px; border-top-right-radius: 18px; border-top-left-radius: 18px; + overflow: visible; +} + +.bubble-content { overflow: auto; } + form { display: flex; gap: 8px; diff --git a/option/src/ui/langgraph/ui/html/chat.js b/option/src/ui/langgraph/ui/html/chat.js index d018fe9c..e8d0a4db 100644 --- a/option/src/ui/langgraph/ui/html/chat.js +++ b/option/src/ui/langgraph/ui/html/chat.js @@ -5,10 +5,10 @@ mermaid.initialize({ startOnLoad: false }); // -- Variables ----------------------------------------------------------------- -let BASE_URL = '/app'; +let BASE_URL = 'app'; let currentBackend = 'LangGraph'; const backends = [ - { name: 'LangGraph', baseUrl: '/app' } + { name: 'LangGraph', baseUrl: 'app' } ]; let currentAgent = 'agent'; let currentUser = 'customer'; @@ -77,6 +77,11 @@ function hideSpinner() { spinnerContainer.innerHTML = ''; } +// Remove spinner (when SSE is done) +function errorSpinner() { + spinnerContainer.innerHTML = 'ERROR'; +} + function scrollToBottom() { // Scroll so the anchor div is visible document.getElementById('spinner-container').scrollIntoView({ behavior: "smooth" }); @@ -112,10 +117,10 @@ async function renderMessage(msgObj) { let innerHTML = ''; // Human message if (msgObj.type === 'human') { - innerHTML = `
You
${renderMarkdown(msgObj.content)}
`; + innerHTML = `
You
${renderMarkdown(msgObj.content)}
`; } else if (msgObj.type === 'ai') { if (msgObj.content) { - innerHTML = `
AI
${await renderContent(msgObj.content)}
`; + innerHTML = `
AI
${await renderContent(msgObj.content)}
`; } else if (msgObj.tool_calls && msgObj.tool_calls.length > 0) { const toolNames = msgObj.tool_calls.map(t => t.name).join(' - '); let bubble = `
Tool Calls - ${toolNames}
`; @@ -158,7 +163,7 @@ function startSSE(reqBody, onMessage, onDone) { body: JSON.stringify(reqBody) }).then(async response => { if (!response.ok || !response.body) { - hideSpinner(); + errorSpinner(); onMessage({ type: "ai", content: "Network/server error." }); if (onDone) onDone(); return; @@ -196,7 +201,7 @@ function startSSE(reqBody, onMessage, onDone) { hideSpinner(); if (onDone) onDone(); }).catch(e => { - hideSpinner(); + errorSpinner(); onMessage({ type: "ai", content: "Connection error." }); if (onDone) onDone(); }); diff --git a/option/terraform/apigw.j2.tf b/option/terraform/apigw.j2.tf index dbaee3e6..bf69b382 100644 --- a/option/terraform/apigw.j2.tf +++ b/option/terraform/apigw.j2.tf @@ -11,6 +11,7 @@ data "oci_apigateway_gateway" "starter_apigw" { locals { apigw_ocid = var.apigw_ocid apigw_ip = try(data.oci_apigateway_gateway.starter_apigw.ip_addresses[0].ip_address,"") + local_apigw_hostname = data.oci_apigateway_gateway.starter_apigw.hostname } {%- else %} @@ -41,6 +42,7 @@ resource "oci_apigateway_api" "starter_api" { locals { apigw_ocid = try(oci_apigateway_gateway.starter_apigw.id, "") apigw_ip = try(oci_apigateway_gateway.starter_apigw.ip_addresses[0].ip_address,"") + local_apigw_hostname = oci_apigateway_gateway.starter_apigw.hostname } {%- endif %} diff --git a/option/terraform/container_instance_part2.j2.tf b/option/terraform/container_instance_part2.j2.tf index 2ba3d507..9bf74ea8 100644 --- a/option/terraform/container_instance_part2.j2.tf +++ b/option/terraform/container_instance_part2.j2.tf @@ -1,95 +1,138 @@ locals { - docker_image_ui=data.external.env_part2.result.docker_image_ui - docker_image_rest=data.external.env_part2.result.docker_image_rest + docker_image_ui=data.external.env_part2.result.docker_image_ui + docker_image_rest=data.external.env_part2.result.docker_image_rest + {%- if python_framework in [ "langgraph", "responses" ] %} + docker_image_mcp_server=data.external.env_part2.result.docker_image_mcp_server + {%- endif %} } resource oci_container_instances_container_instance starter_container_instance { - depends_on = [ local.docker_image_ui ] + depends_on = [ local.docker_image_ui ] - availability_domain = local.availability_domain_name - compartment_id = local.lz_app_cmp_ocid - container_restart_policy = "ALWAYS" - containers { - display_name = "rest" - image_url = local.docker_image_rest - is_resource_principal_disabled = "false" - environment_variables = { - {%- if db_type != "none" %} - "DB_URL" = local.local_db_url, - "JDBC_URL" = local.local_jdbc_url, - "DB_USER" = var.db_user != null ? var.db_user : "{{ db_user }}", - "DB_PASSWORD" = var.db_password, - "JAVAX_SQL_DATASOURCE_DS1_DATASOURCE_URL" = local.local_jdbc_url - {%- endif %} - {%- if db_type == "nosql" %} - "TF_VAR_compartment_ocid" = var.compartment_ocid, - # XXX Ideally it should be nosql.${region}.oci.${regionDomain} - "TF_VAR_nosql_endpoint" = "nosql.${var.region}.oci.oraclecloud.com", - {%- endif %} + availability_domain = local.availability_domain_name + compartment_id = local.lz_app_cmp_ocid + container_restart_policy = "ALWAYS" + containers { + display_name = "rest" + image_url = local.docker_image_rest + is_resource_principal_disabled = "false" + environment_variables = { + {%- if db_type != "none" %} + "DB_URL" = local.local_db_url + "JDBC_URL" = local.local_jdbc_url + "DB_USER" = var.db_user != null ? var.db_user : "{{ db_user }}" + "DB_PASSWORD" = var.db_password + "JAVAX_SQL_DATASOURCE_DS1_DATASOURCE_URL" = local.local_jdbc_url + {%- endif %} + {%- if db_type == "nosql" %} + "TF_VAR_compartment_ocid" = var.compartment_ocid + # XXX Ideally it should be nosql.${region}.oci.${regionDomain} + "TF_VAR_nosql_endpoint" = "nosql.${var.region}.oci.oraclecloud.com" + {%- endif %} + {%- if python_framework in [ "langgraph", "responses" ] %} + "TF_VAR_region" = var.region + "TF_VAR_compartment_ocid" = var.compartment_ocid + "AUTH_TYPE" = "RESOURCE_PRINCIPAL" + {%- endif %} + {%- if python_framework == "langgraph" %} + "MCP_SERVER_URL" = "http://localhost:2025/mcp" + {%- elif python_framework == "responses" %} + "TF_VAR_project_ocid" = var.project_ocid + "MCP_SERVER_URL" = "https://${local.local_apigw_hostname}/${var.prefix}/mcp_server/mcp" + {%- endif %} + } + } + containers { + display_name = "ui" + image_url = local.docker_image_ui + is_resource_principal_disabled = "false" + } + {%- if python_framework in [ "langgraph", "responses" ] %} + containers { + display_name = "mcp_server" + image_url = local.docker_image_mcp_server + is_resource_principal_disabled = "false" + environment_variables = { + {%- if db_type != "none" %} + "DB_URL" = local.local_db_url, + "JDBC_URL" = local.local_jdbc_url, + "DB_USER" = var.db_user != null ? var.db_user : "{{ db_user }}", + "DB_PASSWORD" = var.db_password, + "JAVAX_SQL_DATASOURCE_DS1_DATASOURCE_URL" = local.local_jdbc_url + {%- endif %} + {%- if db_type == "nosql" %} + "TF_VAR_compartment_ocid" = var.compartment_ocid, + # XXX Ideally it should be nosql.${region}.oci.${regionDomain} + "TF_VAR_nosql_endpoint" = "nosql.${var.region}.oci.oraclecloud.com", + {%- endif %} + } } - } - containers { - display_name = "ui" - image_url = local.docker_image_ui - is_resource_principal_disabled = "false" - } - display_name = "${var.prefix}-ci" - graceful_shutdown_timeout_in_seconds = "0" - shape = startswith(var.instance_shape, "VM.Standard.A") ? "CI.Standard.A1.Flex" : "CI.Standard.E4.Flex" - shape_config { - memory_in_gbs = "4" - ocpus = "1" - } - state = "ACTIVE" - vnics { - display_name = "${var.prefix}-ci" - hostname_label = "${var.prefix}-ci" - skip_source_dest_check = "true" - subnet_id = data.oci_core_subnet.starter_app_subnet.id - } - freeform_tags = local.freeform_tags + {%- endif %} + display_name = "${var.prefix}-ci" + graceful_shutdown_timeout_in_seconds = "0" + shape = startswith(var.instance_shape, "VM.Standard.A") ? "CI.Standard.A1.Flex" : "CI.Standard.E4.Flex" + shape_config { + memory_in_gbs = "4" + ocpus = "1" + } + state = "ACTIVE" + vnics { + display_name = "${var.prefix}-ci" + hostname_label = "${var.prefix}-ci" + skip_source_dest_check = "true" + subnet_id = data.oci_core_subnet.starter_app_subnet.id + } + freeform_tags = local.freeform_tags } locals { - apigw_dest_private_ip = try(oci_container_instances_container_instance.starter_container_instance.vnics[0].private_ip, "") + apigw_dest_private_ip = try(oci_container_instances_container_instance.starter_container_instance.vnics[0].private_ip, "") } resource "oci_apigateway_deployment" "starter_apigw_deployment" { {%- if tls is defined %} - count = (var.certificate_ocid == null) ? 0 : 1 + count = (var.certificate_ocid == null) ? 0 : 1 {%- endif %} - compartment_id = local.lz_app_cmp_ocid - display_name = "${var.prefix}-apigw-deployment" - gateway_id = local.apigw_ocid - path_prefix = "/${var.prefix}" - specification { - logging_policies { - access_log { - is_enabled = true - } - execution_log { - #Optional - is_enabled = true - } - } - routes { - path = "/app/{pathname*}" - methods = [ "ANY" ] - backend { - type = "HTTP_BACKEND" - url = "##APP_URL##" - } - } - routes { - path = "/{pathname*}" - methods = [ "ANY" ] - backend { - type = "HTTP_BACKEND" - url = "http://${local.apigw_dest_private_ip}/$${request.path[pathname]}" - } + compartment_id = local.lz_app_cmp_ocid + display_name = "${var.prefix}-apigw-deployment" + gateway_id = local.apigw_ocid + path_prefix = "/${var.prefix}" + specification { + logging_policies { + access_log { + is_enabled = true + } + execution_log { + #Optional + is_enabled = true + } + } + routes { + path = "/app/{pathname*}" + methods = [ "ANY" ] + backend { + type = "HTTP_BACKEND" + url = "##APP_URL##" + } + } + {%- if python_framework in [ "langgraph", "responses" ] %} + routes { + path = "/mcp_server/{pathname*}" + methods = [ "ANY" ] + backend { + type = "HTTP_BACKEND" + url = "http://${local.apigw_dest_private_ip}:2025/$${request.path[pathname]}" + } + } + {%- endif %} + routes { + path = "/{pathname*}" + methods = [ "ANY" ] + backend { + type = "HTTP_BACKEND" + url = "http://${local.apigw_dest_private_ip}/$${request.path[pathname]}" + } + } } - } - freeform_tags = local.api_tags -} - - + freeform_tags = local.api_tags +} \ No newline at end of file diff --git a/option/terraform/network.j2.tf b/option/terraform/network.j2.tf index 95ff455f..fb52fbff 100644 --- a/option/terraform/network.j2.tf +++ b/option/terraform/network.j2.tf @@ -315,6 +315,19 @@ resource "oci_core_security_list" "starter_security_list" { } } + // MCP Server + ingress_security_rules { + protocol = "6" // tcp + source = local.cidr_vcn + stateless = false + + tcp_options { + min = 2025 + max = 2025 + } + } + + freeform_tags = local.freeform_tags } diff --git a/option/terraform/oke.j2.tf b/option/terraform/oke.j2.tf index 40f9cc61..29fc3225 100644 --- a/option/terraform/oke.j2.tf +++ b/option/terraform/oke.j2.tf @@ -37,15 +37,6 @@ data "oci_containerengine_cluster_option" "starter_cluster_option" { cluster_option_id = "all" } -# Do not use versions ending with .0 (K8s Preview versions) -locals { - oke_stable_versions = [ - for v in data.oci_containerengine_cluster_option.starter_cluster_option.kubernetes_versions : v - if !endswith(v, ".0") - ] - oke_latest_stable_version=local.oke_stable_versions[length(local.oke_stable_versions)-1] -} - data "oci_containerengine_node_pool_option" "starter_node_pool_option" { node_pool_option_id = "all" } @@ -62,16 +53,49 @@ data "oci_core_images" "shape_specific_images" { } locals { + oke_stable_versions = [ + for v in data.oci_containerengine_cluster_option.starter_cluster_option.kubernetes_versions : v + if !endswith(v, ".0") + ] + oke_latest_stable_version=local.oke_stable_versions[length(local.oke_stable_versions)-1] + k8s_version = replace(local.oke_latest_stable_version, "v", "") + + # Get the image id from data.oci_containerengine_cluster_option.starter_cluster_option.kubernetes_versions + # Ex: Oracle-Linux-8.10-2026.02.28-0-OKE-1.35.2-1392 -> ocid..... + oke_images_amd = [ + for s in data.oci_containerengine_node_pool_option.starter_node_pool_option.sources : s + if !can(regex("aarch64|GPU", s.source_name)) + && can(regex("OKE-${local.k8s_version}", s.source_name)) + && can(regex("Linux-8", s.source_name)) + ] + oke_images_ampere = [ + for s in data.oci_containerengine_node_pool_option.starter_node_pool_option.sources : s + if can(regex("aarch64", s.source_name)) + && can(regex("OKE-${local.k8s_version}", s.source_name)) + && can(regex("Linux-8", s.source_name)) + ] + oke_images = (var.instance_shape=="VM.Standard.A1.Flex")?local.oke_images_ampere:local.oke_images_amd + + oke_image_id = length(local.oke_images) > 0 ? element( + [ + for s in sort(local.oke_images[*].source_name) : + one([for x in local.oke_images : x.image_id if x.source_name == s]) + ], + length(local.oke_images) - 1 + ) : data.oci_core_images.oraclelinux.images.0.id + # all_images = "${data.oci_core_images.shape_specific_images.images}" # all_sources = "${data.oci_containerengine_node_pool_option.starter_node_pool_option.sources}" # compartment_images = [for image in local.all_images : image.id if length(regexall("Oracle-Linux-[0-9]*.[0-9]*-20[0-9]*",image.display_name)) > 0 ] # oracle_linux_images = [for source in local.all_sources : source.image_id if length(regexall("Oracle-Linux-[0-9]*.[0-9]*-20[0-9]*",source.source_name)) > 0] # image_id = tolist(setintersection( toset(local.compartment_images), toset(local.oracle_linux_images)))[0] - image_id = data.oci_core_images.oraclelinux.images.0.id + # image_id = data.oci_core_images.oraclelinux.images.0.id } - + + #---------------------------------------------------------------------------- # SECURITY LISTS +# See: https://docs.oracle.com/en-us/iaas/Content/ContEng/Concepts/contengnetworkconfigexample.htm resource "oci_core_security_list" "starter_seclist_lb" { compartment_id = local.lz_network_cmp_ocid @@ -117,6 +141,7 @@ resource "oci_core_security_list" "starter_seclist_node" { protocol = "all" stateless = "false" } + egress_security_rules { description = "Access to Kubernetes API Endpoint" destination = local.oke_cidr_api @@ -124,8 +149,8 @@ resource "oci_core_security_list" "starter_seclist_node" { protocol = "6" stateless = "false" tcp_options { - max = "6443" min = "6443" + max = "6443" } } egress_security_rules { @@ -135,8 +160,8 @@ resource "oci_core_security_list" "starter_seclist_node" { protocol = "6" stateless = "false" tcp_options { - max = "12250" min = "12250" + max = "12250" } } egress_security_rules { @@ -157,8 +182,8 @@ resource "oci_core_security_list" "starter_seclist_node" { protocol = "6" stateless = "false" tcp_options { - max = "443" min = "443" + max = "443" } } egress_security_rules { @@ -187,6 +212,7 @@ resource "oci_core_security_list" "starter_seclist_node" { source_type = "CIDR_BLOCK" stateless = "false" } + ingress_security_rules { description = "Path discovery" icmp_options { @@ -198,6 +224,7 @@ resource "oci_core_security_list" "starter_seclist_node" { source_type = "CIDR_BLOCK" stateless = "false" } + ingress_security_rules { description = "TCP access from Kubernetes Control Plane" protocol = "6" @@ -205,6 +232,7 @@ resource "oci_core_security_list" "starter_seclist_node" { source_type = "CIDR_BLOCK" stateless = "false" } + ingress_security_rules { description = "Inbound SSH traffic to worker nodes" protocol = "6" @@ -212,11 +240,35 @@ resource "oci_core_security_list" "starter_seclist_node" { source_type = "CIDR_BLOCK" stateless = "false" tcp_options { - max = "22" min = "22" + max = "22" } } + ingress_security_rules { + description = "NodePort" + protocol = "6" + source = "0.0.0.0/0" + source_type = "CIDR_BLOCK" + stateless = "false" + tcp_options { + min = "30000" + max = "32767" + } + } + + ingress_security_rules { + description = "Allow load balancer to communicate with kube-proxy on worker nodes." + protocol = "6" + source = "0.0.0.0/0" + source_type = "CIDR_BLOCK" + stateless = "false" + tcp_options { + min = "10256" + max = "10256" + } + } + freeform_tags = local.freeform_tags } @@ -225,7 +277,7 @@ resource "oci_core_security_list" "starter_seclist_node" { resource oci_core_security_list starter_seclist_api { compartment_id = local.lz_network_cmp_ocid vcn_id = data.oci_core_vcn.starter_vcn.id - display_name = "${var.prefix}-seclist-node" + display_name = "${var.prefix}-seclist-api" egress_security_rules { description = "Allow Kubernetes Control Plane to communicate with OKE" @@ -268,6 +320,7 @@ resource oci_core_security_list starter_seclist_api { min = "6443" } } + ingress_security_rules { description = "Kubernetes worker to control plane communication" protocol = "6" @@ -279,6 +332,7 @@ resource oci_core_security_list starter_seclist_api { min = "12250" } } + ingress_security_rules { description = "Path discovery" icmp_options { @@ -321,7 +375,7 @@ resource "oci_core_subnet" "starter_lb_subnet" { # Provider code tries to maintain compatibility with old versions. # security_list_ids = [data.oci_core_vcn.starter_vcn.default_security_list_id, oci_core_security_list.starter_security_list.id] - security_list_ids = [data.oci_core_vcn.starter_vcn.default_security_list_id] + security_list_ids = [data.oci_core_vcn.starter_vcn.default_security_list_id,oci_core_security_list.starter_seclist_lb.id] display_name = "${var.prefix}-oke-lb-subnet" route_table_id = data.oci_core_vcn.starter_vcn.default_route_table_id @@ -402,6 +456,8 @@ resource "oci_containerengine_cluster" "starter_oke" { # } } + depends_on = [ oci_identity_policy.starter_oke_policy ] + freeform_tags = local.freeform_tags } @@ -422,7 +478,7 @@ resource "oci_containerengine_node_pool" "starter_node_pool" { node_source_details { #Required - image_id = local.image_id + image_id = local.oke_image_id source_type = "IMAGE" } @@ -442,6 +498,12 @@ resource "oci_containerengine_node_pool" "starter_node_pool" { # pod_subnet_ids = [ oci_core_subnet.starter_pod_subnet.id ] # } } + + node_eviction_node_pool_settings { + eviction_grace_duration = "PT0S" + is_force_delete_after_grace_duration = "true" + } + ssh_public_key = local.ssh_public_key freeform_tags = local.freeform_tags @@ -473,6 +535,7 @@ resource oci_containerengine_addon starter_oke_addon_certmanager { remove_addon_resources_on_delete = "true" } + #---------------------------------------------------------------------------- # OUTPUTS @@ -491,9 +554,39 @@ output "node_pool" { locals { local_oke_ocid = oci_containerengine_cluster.starter_oke.id + local_oke_lb_subnet_ocid = oci_core_subnet.starter_lb_subnet.id } + {%- endif %} output "oke_ocid" { value = local.local_oke_ocid } + +# Doc: https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengsettingupnativeingresscontroller-addon-prereqs.htm#contengsettingupnativeingresscontroller-addon-permissions +resource "oci_identity_policy" "starter_oke_policy" { + provider = oci.home + name = "${var.prefix}-oke-policy-${random_string.id.result}" + description = "${var.prefix}-oke-policy" + compartment_id = local.lz_app_cmp_ocid + statements = [ + "allow any-user to manage load-balancers in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to use virtual-network-family in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to manage cabundles in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to manage cabundle-associations in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to manage leaf-certificates in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to read leaf-certificate-bundles in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to manage leaf-certificate-versions in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to manage certificate-associations in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to read certificate-authorities in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to manage certificate-authority-associations in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to read certificate-authority-bundles in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to read public-ips in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to manage floating-ips in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to manage waf-family in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to read cluster-family in compartment id ${local.lz_app_cmp_ocid}", + "allow any-user to use tag-namespaces in compartment id ${local.lz_app_cmp_ocid}", + ] + freeform_tags = local.freeform_tags +} + diff --git a/py_oci_starter.py b/py_oci_starter.py index 4fb837f1..67b1b0d7 100755 --- a/py_oci_starter.py +++ b/py_oci_starter.py @@ -92,7 +92,7 @@ def mandatory_options(mode): '-atp_ocid', '-db_ocid', '-db_compartment_ocid', '-pdb_ocid', '-mysql_ocid', '-psql_ocid', '-opensearch_ocid', '-nosql_ocid', '-db_user', '-fnapp_ocid', '-apigw_ocid', '-bastion_ocid', '-auth_token', '-tls', '-subnet_ocid','-web_subnet_ocid','-app_subnet_ocid','-db_subnet_ocid','-shape','-db_install', - '-ui', '-deploy', '-database', '-license'] + '-ui', '-deploy', '-database', '-license', '-test_name'] # hidden_options - allowed but not advertised hidden_options = ['-zip', '-group_common','-group_name'] @@ -861,6 +861,9 @@ def create_output_dir(): if params.get('deploy_type') == "function": output_copy_tree("option/src/app/fn/fn_common", "src/app") + if params.get('test_name'): + output_copy("test_suite/test_bastion_lock.sh", "bin/compute") + # Generic version for Oracle DB if os.path.exists("option/src/app/"+app): output_copy_tree("option/src/app/"+app, "src/app") @@ -905,7 +908,7 @@ def create_output_dir(): if params.get('java_vm') == "graalvm": params['java_docker'] = 'container-registry.oracle.com/graalvm/jdk:25' else: - params['java_docker'] = 'eclipse-temurin:25' + params['java_docker'] = 'docker.io/library/eclipse-temurin:25' # Check if any script exists that is NOT build_rest.sh has_build_rest = False diff --git a/test_suite/cleanup_ocir.py b/test_suite/cleanup_ocir.py index a4188b08..a6b77c5f 100644 --- a/test_suite/cleanup_ocir.py +++ b/test_suite/cleanup_ocir.py @@ -22,7 +22,7 @@ def main(): # List all container repositories repos = list_call_get_all_results( artifacts_client.list_container_repositories, - compartment_ocid=compartment_ocid + compartment_id=compartment_ocid ).data if not repos: @@ -35,7 +35,7 @@ def main(): # List all image versions in the repository images = list_call_get_all_results( artifacts_client.list_container_images, - compartment_ocid=compartment_ocid, + compartment_id=compartment_ocid, repository_id=repo.id ).data diff --git a/test_suite/cleanup_ocir.sh b/test_suite/cleanup_ocir.sh new file mode 100755 index 00000000..c3728a37 --- /dev/null +++ b/test_suite/cleanup_ocir.sh @@ -0,0 +1,5 @@ +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +cd $SCRIPT_DIR + +. $HOME/.oci_starter_profile +python3 cleanup_ocir.py \ No newline at end of file diff --git a/test_suite/install_dev.sh b/test_suite/install_dev.sh index 78da04f3..97a38ea7 100755 --- a/test_suite/install_dev.sh +++ b/test_suite/install_dev.sh @@ -42,7 +42,14 @@ sudo update-alternatives --set java /usr/lib64/graalvm/graalvm-java25/bin/java echo "export JAVA_HOME=/usr/lib64/graalvm/graalvm-java25" >> $HOME/.bashrc # Maven -sudo dnf install -y maven +# sudo dnf install -y maven (too old version in OL8) +MVN_VERSION=3.9.15 +wget https://dlcdn.apache.org/maven/maven-3/$MVN_VERSION/binaries/apache-maven-$MVN_VERSION-bin.tar.gz +tar xfz apache-maven-$MVN_VERSION-bin.tar.gz +mv apache-maven-$MVN_VERSION $HOME/maven +rm apache-maven-$MVN_VERSION-bin.tar.gz +export PATH=$HOME/maven/bin:$PATH +echo "export PATH=$HOME/maven/bin:$PATH" >> $HOME/.bashrc # Node (JET/Angular/ReactJS) sudo dnf module enable -y nodejs:20 @@ -84,8 +91,8 @@ sudo dnf install -y tmux # VIM cat >> $HOME/.vimrc <<'EOT' -set tabstop=2 +set tabstop=4 set expandtab -set shiftwidth=2 +set shiftwidth=4 set paste EOT diff --git a/test_suite/test_bastion_lock.sh b/test_suite/test_bastion_lock.sh new file mode 100755 index 00000000..b80c13bf --- /dev/null +++ b/test_suite/test_bastion_lock.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +cd $HOME + +LOCKFILE="bastion_lock" +TIMEOUT=300 +WAIT=5 +ELAPSED=0 +DATE_POSTFIX=`date '+%Y%m%d-%H%M%S'` +NAME="$DATE_POSTFIX - $1" +echo "$NAME" >> bastion_lock_waiting + +while [ "$ELAPSED" -lt "$TIMEOUT" ]; do + if [ -e "$LOCKFILE" ]; then + echo "bastion_lock file exists, waiting..." + else + # Try to create the lock atomically + if ( set -o noclobber; > "$LOCKFILE" ) 2> /dev/null; then + echo "Lock acquired." + sed -i "s/$NAME/$NAME - $ELAPSED secs/" bastion_lock_waiting + rm -Rf $HOME/app/* + exit 0 + else + echo "Race condition, retrying..." + fi + fi + + sleep "$WAIT" + ELAPSED=$((ELAPSED + WAIT)) +done + +sed -i "s/$NAME/$NAME - ERROR TIMEOUT/" bastion_lock_waiting +echo "Failed to acquire lock after ${TIMEOUT} seconds." +exit 1 \ No newline at end of file diff --git a/test_suite/test_done.sh b/test_suite/test_done.sh index b5a06b35..8261924e 100755 --- a/test_suite/test_done.sh +++ b/test_suite/test_done.sh @@ -8,7 +8,8 @@ if [ "$UI_URL" != "" ]; then rm -Rf $TMP_PATH mkdir -p $TMP_PATH echo $UI_URL > $TMP_PATH/ui_url.txt - + echo "URL = $UI_URL" + if [ "$TF_VAR_deploy_type" == "kubernetes" ]; then kubectl wait --for=condition=ready pod ${TF_VAR_prefix}-app kubectl wait --for=condition=ready pod ${TF_VAR_prefix}-ui @@ -49,17 +50,17 @@ if [ "$UI_URL" != "" ]; then fi # Check (Same test is also done test_suite_shared) - if grep -q -i "deptno" $TMP_PATH/result_dept.json; then - echo -e "\u2705 deptno detected" + if grep -qiE "deptno|department" $TMP_PATH/result_dept.json; then + echo -e "\u2705 deptno or department detected" break else - echo -e "Waiting 5 secs: deptno not found" + echo -e "Waiting 5 secs: deptno or department not found" fi sleep 5 x=$(( $x + 1 )) done if [ "$x" == "20" ]; then - echo -e "\u2705 deptno not detected in $UI_URL/app/dept" + echo -e "\u2705 deptno or department not detected in $UI_URL/app/dept" fi echo "See $TMP_PATH/result_dept.json" diff --git a/test_suite/test_no_destroy.sh b/test_suite/test_no_destroy.sh deleted file mode 100755 index 9330f276..00000000 --- a/test_suite/test_no_destroy.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -cd $SCRIPT_DIR - -if [ -z "$1" ]; then - echo "Usage: test_rerun.sh " - exit -fi - -export TEST_DIRECTORY_ONLY=$1 -export TEST_NO_DESTROY=TRUE -./test_suite.sh diff --git a/test_suite/test_rerun.sh b/test_suite/test_rerun.sh index 781a4ce7..a162f686 100755 --- a/test_suite/test_rerun.sh +++ b/test_suite/test_rerun.sh @@ -2,9 +2,34 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) cd $SCRIPT_DIR -if [ -z "$1" ]; then - echo "Usage: test_rerun.sh " - exit +if [ "$#" -lt 1 ]; then + echo "Usage: test_rerun.sh " + exit 1 +fi + +if [ "$2" == "destroy_refresh_build_destroy" ]; then + MODE_ID=1 +elif [ "$2" == "destroy_refresh_build" ]; then + MODE_ID=2 +elif [ "$2" == "refresh" ]; then + MODE_ID=3 +else + echo "Mode" + echo "[1] ./test_rerun.sh destroy_refresh_build_destroy" + echo "[2] ./test_rerun.sh destroy_refresh_build" + echo "[3] ./test_rerun.sh refresh" + read -p "Enter choice [1/3]: " MODE_ID +fi + +if [ "$MODE_ID" == "1" ]; then + echo "-" +elif [ "$MODE_ID" == "2" ]; then + export TEST_RERUN_NO_DESTROY=TRUE +elif [ "$MODE_ID" == "3" ]; then + export TEST_RERUN_REFRESH=TRUE +else + echo "ERROR: Unknown choice" + exit 1 fi export TEST_DIRECTORY_ONLY=$1 diff --git a/test_suite/test_suite.sh b/test_suite/test_suite.sh index ff785fcd..1d23cad3 100755 --- a/test_suite/test_suite.sh +++ b/test_suite/test_suite.sh @@ -6,170 +6,170 @@ export TEST_HOME=$SCRIPT_DIR/test_group_all export BUILD_COUNT=1 loop_ui() { - if [ "$OPTION_LANG" == "php" ]; then - OPTION_UI=php - build_option - elif [ "$OPTION_LANG" == "apex" ]; then - OPTION_UI=apex - build_option - else - OPTION_UI=html - build_option - # Test all the UIs with ORDS only - if [ "$OPTION_DEPLOY" == "kubernetes" ] && [ "$OPTION_LANG" == "ords" ]; then - OPTION_UI=reactjs - build_option - OPTION_UI=angular - build_option - OPTION_UI=jet - build_option - fi - if [ "$OPTION_JAVA_FRAMEWORK" == "tomcat" ]; then - OPTION_UI=jsp - build_option - fi - if [ "$OPTION_LANG" == "node" ] && [ "$OPTION_DB" == "atp" ]; then - OPTION_UI=api - build_option - fi - fi + if [ "$OPTION_LANG" == "php" ]; then + OPTION_UI=php + build_option + elif [ "$OPTION_LANG" == "apex" ]; then + OPTION_UI=apex + build_option + else + OPTION_UI=html + build_option + # Test all the UIs with ORDS only + if [ "$OPTION_DEPLOY" == "kubernetes" ] && [ "$OPTION_LANG" == "ords" ]; then + OPTION_UI=reactjs + build_option + OPTION_UI=angular + build_option + OPTION_UI=jet + build_option + fi + if [ "$OPTION_JAVA_FRAMEWORK" == "tomcat" ]; then + OPTION_UI=jsp + build_option + fi + if [ "$OPTION_LANG" == "node" ] && [ "$OPTION_DB" == "atp" ]; then + OPTION_UI=api + build_option + fi + fi } loop_shape() { - if [ `arch` == "aarch64" ]; then - OPTION_SHAPE=ampere - loop_ui - else - OPTION_SHAPE=amd - loop_ui - fi + if [ `arch` == "aarch64" ]; then + OPTION_SHAPE=ampere + loop_ui + else + OPTION_SHAPE=amd + loop_ui + fi } loop_db() { - if [ "$OPTION_DEPLOY" != "instance_pool" ] ; then - # OPTION_DB=database - # loop_ui - OPTION_DB=atp - loop_shape - OPTION_DB=psql - loop_shape - OPTION_DB=mysql - loop_shape - OPTION_DB=opensearch + if [ "$OPTION_DEPLOY" != "instance_pool" ] ; then + # OPTION_DB=database + # loop_ui + OPTION_DB=atp + loop_shape + OPTION_DB=psql + loop_shape + OPTION_DB=mysql + loop_shape + OPTION_DB=opensearch + loop_shape + # NoSQL has no PHP Support + if [ "$OPTION_LANG" != "php" ]; then + OPTION_DB=nosql + loop_shape + fi + fi + OPTION_DB=none loop_shape - # NoSQL has no PHP Support - if [ "$OPTION_LANG" != "php" ]; then - OPTION_DB=nosql - loop_shape - fi - fi - OPTION_DB=none - loop_shape - # Build Host Bastion - if [ "$OPTION_DEPLOY" == "public_compute" ] || [ "$OPTION_DEPLOY" == "kubernetes" ]; then - OPTION_BUILD_HOST=bastion - OPTION_DB=atp - loop_shape - OPTION_BUILD_HOST=terraform - fi -} + # Build Host Bastion + if [ "$OPTION_DEPLOY" == "public_compute" ] || [ "$OPTION_DEPLOY" == "kubernetes" ]; then + OPTION_BUILD_HOST=bastion + OPTION_DB=atp + loop_shape + OPTION_BUILD_HOST=terraform + fi + } -loop_java_vm() { - OPTION_JAVA_VM=jdk - loop_db - if [ "$OPTION_JAVA_FRAMEWORK" == "springboot" ] ; then - OPTION_JAVA_VM=graalvm + loop_java_vm() { + OPTION_JAVA_VM=jdk loop_db - fi + if [ "$OPTION_JAVA_FRAMEWORK" == "springboot" ] ; then + OPTION_JAVA_VM=graalvm + loop_db + fi - if [ -n "$TEST_GRAALVM_NATIVE" ] && [ "$OPTION_JAVA_FRAMEWORK" != "tomcat" ] ; then - if [ "$OPTION_DEPLOY" == "private_compute" ] || [ "$OPTION_DEPLOY" == "kubernetes" ]; then - OPTION_JAVA_VM=graalvm-native - loop_db - fi - fi + if [ -n "$TEST_GRAALVM_NATIVE" ] && [ "$OPTION_JAVA_FRAMEWORK" != "tomcat" ] ; then + if [ "$OPTION_DEPLOY" == "private_compute" ] || [ "$OPTION_DEPLOY" == "kubernetes" ]; then + OPTION_JAVA_VM=graalvm-native + loop_db + fi + fi } loop_java_framework () { - OPTION_JAVA_FRAMEWORK=springboot - loop_java_vm - OPTION_JAVA_FRAMEWORK=helidon - loop_java_vm - OPTION_JAVA_FRAMEWORK=micronaut - loop_java_vm - OPTION_JAVA_VM=jdk - OPTION_JAVA_FRAMEWORK=tomcat - loop_db - # Reset the value to default - OPTION_JAVA_FRAMEWORK=springboot + OPTION_JAVA_FRAMEWORK=springboot + loop_java_vm + OPTION_JAVA_FRAMEWORK=helidon + loop_java_vm + OPTION_JAVA_FRAMEWORK=micronaut + loop_java_vm + OPTION_JAVA_VM=jdk + OPTION_JAVA_FRAMEWORK=tomcat + loop_db + # Reset the value to default + OPTION_JAVA_FRAMEWORK=springboot } loop_lang () { - OPTION_LANG=java - OPTION_JAVA_VM=jdk - if [ "$OPTION_DEPLOY" == "function" ]; then - # Dummy value, not used - OPTION_JAVA_FRAMEWORK=helidon + OPTION_LANG=java + OPTION_JAVA_VM=jdk + if [ "$OPTION_DEPLOY" == "function" ]; then + # Dummy value, not used + OPTION_JAVA_FRAMEWORK=helidon + loop_db + else + loop_java_framework + fi + # OCI Function has no PHP support + if [ "$OPTION_DEPLOY" != "function" ]; then + OPTION_LANG=php + loop_db + fi + if [ "$OPTION_DEPLOY" == "private_compute" ]; then + OPTION_LANG=apex + OPTION_DB=atp + loop_shape + OPTION_DB=database + loop_shape + fi + OPTION_LANG=go + loop_db + OPTION_LANG=node loop_db - else - loop_java_framework - fi - # OCI Function has no PHP support - if [ "$OPTION_DEPLOY" != "function" ]; then - OPTION_LANG=php + OPTION_LANG=python + OPTION_PYTHON_FRAMEWORK=fastapi loop_db - fi - if [ "$OPTION_DEPLOY" == "private_compute" ]; then - OPTION_LANG=apex - OPTION_DB=atp - loop_shape - OPTION_DB=database - loop_shape - fi - OPTION_LANG=go - loop_db - OPTION_LANG=node - loop_db - OPTION_LANG=python - OPTION_PYTHON_FRAMEWORK=fastapi - loop_db - if [ "$OPTION_DEPLOY" != "function" ]; then - OPTION_PYTHON_FRAMEWORK=langgraph + if [ "$OPTION_DEPLOY" != "function" ]; then + OPTION_PYTHON_FRAMEWORK=langgraph + OPTION_DB=atp + loop_ui + OPTION_PYTHON_FRAMEWORK=responses + loop_ui + OPTION_PYTHON_FRAMEWORK=fastapi + fi + OPTION_LANG=dotnet + loop_db + # XXXX ORDS works only with ATP (DBSystems is not test/done) + OPTION_LANG=ords OPTION_DB=atp loop_ui - OPTION_PYTHON_FRAMEWORK=responses - loop_ui - OPTION_PYTHON_FRAMEWORK=fastapi - fi - OPTION_LANG=dotnet - loop_db - # XXXX ORDS works only with ATP (DBSystems is not test/done) - OPTION_LANG=ords - OPTION_DB=atp - loop_ui } loop_compute_other() { - # Public compute / LiveLabs Green Button - OPTION_SHAPE=amd - OPTION_LANG=java - OPTION_JAVA_VM=jdk - OPTION_JAVA_FRAMEWORK=springboot - OPTION_DEPLOY=public_compute - OPTION_UI=html - OPTION_DB=db_free - build_option - OPTION_DB=mysql - build_option + # Public compute / LiveLabs Green Button + OPTION_SHAPE=amd + OPTION_LANG=java + OPTION_JAVA_VM=jdk + OPTION_JAVA_FRAMEWORK=springboot + OPTION_DEPLOY=public_compute + OPTION_UI=html + OPTION_DB=db_free + build_option + OPTION_DB=mysql + build_option - # Resource Manager - OPTION_DEPLOY=private_compute - OPTION_DB_INSTALL=default - OPTION_DB=atp - OPTION_INFRA_AS_CODE=resource_manager - build_option - OPTION_INFRA_AS_CODE=terraform_local + # Resource Manager + OPTION_DEPLOY=private_compute + OPTION_DB_INSTALL=default + OPTION_DB=atp + OPTION_INFRA_AS_CODE=resource_manager + build_option + OPTION_INFRA_AS_CODE=terraform_local # From Resource Manager # OPTION_INFRA_AS_CODE=from_resource_manager @@ -185,110 +185,117 @@ loop_compute_other() { # build_option # OPTION_INFRA_AS_CODE=terraform_local - # Pluggable DB - OPTION_DB=pdb - build_option + # Pluggable DB + OPTION_DB=pdb + build_option - # Helidon 4 - OPTION_JAVA_FRAMEWORK=helidon4 - OPTION_DB=atp - build_option + # Helidon 4 + OPTION_JAVA_FRAMEWORK=helidon4 + OPTION_DB=atp + build_option - # Java Compute ATP / No Compartment - # XXX Not possible in tenancy XXX + # Java Compute ATP / No Compartment + # XXX Not possible in tenancy XXX } loop_tls_deploy() { - # Maybe remove one compute when all is working - OPTION_DEPLOY=public_compute - build_option - OPTION_DEPLOY=private_compute - build_option - OPTION_DEPLOY=kubernetes - build_option - OPTION_DEPLOY=instance_pool - build_option - OPTION_DEPLOY=container_instance - build_option - OPTION_DEPLOY=function - build_option + # Maybe remove one compute when all is working + OPTION_DEPLOY=public_compute + build_option + OPTION_DEPLOY=private_compute + build_option + OPTION_DEPLOY=kubernetes + build_option + OPTION_DEPLOY=instance_pool + build_option + OPTION_DEPLOY=container_instance + build_option + OPTION_DEPLOY=function + build_option } loop_tls() { - # TLS - OPTION_GROUP_NAME=none - OPTION_LANG=java - OPTION_JAVA_VM=jdk - OPTION_JAVA_FRAMEWORK=springboot - OPTION_UI=html - OPTION_DB=none - OPTION_TLS=existing_dir - loop_tls_deploy - # existing_ocid is part of existing_dir + # TLS + OPTION_GROUP_NAME=none + OPTION_LANG=java + OPTION_JAVA_VM=jdk + OPTION_JAVA_FRAMEWORK=springboot + OPTION_UI=html + OPTION_DB=none + OPTION_TLS=existing_dir + loop_tls_deploy + # existing_ocid is part of existing_dir - OPTION_DEPLOY=public_compute - OPTION_TLS=new_http_01 - build_option - OPTION_DB_INSTALL=default + OPTION_DEPLOY=public_compute + OPTION_TLS=new_http_01 + build_option + OPTION_DB_INSTALL=default - OPTION_TLS=new_http_01 - OPTION_DEPLOY=kubernetes - build_option + OPTION_TLS=new_http_01 + OPTION_DEPLOY=kubernetes + build_option - OPTION_TLS=new_dns_01 - OPTION_DEPLOY=container_instance - build_option + OPTION_TLS=new_dns_01 + OPTION_DEPLOY=container_instance + build_option - OPTION_GROUP_NAME=dummy - OPTION_TLS=none + OPTION_GROUP_NAME=dummy + OPTION_TLS=none } loop_deploy() { - # Maybe remove one compute type when all is working - OPTION_DEPLOY=public_compute - loop_lang - OPTION_DEPLOY=private_compute - loop_compute_other - loop_lang - OPTION_DEPLOY=kubernetes - loop_lang - OPTION_DEPLOY=instance_pool - OPTION_LANG=java - OPTION_JAVA_FRAMEWORK=springboot - OPTION_DB=atp - loop_shape - OPTION_DEPLOY=container_instance - loop_lang - OPTION_DEPLOY=function - loop_lang + # Maybe remove one compute type when all is working + OPTION_DEPLOY=public_compute + loop_lang + OPTION_DEPLOY=private_compute + loop_compute_other + loop_lang + OPTION_DEPLOY=kubernetes + loop_lang + OPTION_DEPLOY=instance_pool + OPTION_LANG=java + OPTION_JAVA_FRAMEWORK=springboot + OPTION_DB=atp + loop_shape + OPTION_DEPLOY=container_instance + loop_lang + OPTION_DEPLOY=function + loop_lang - loop_tls + loop_tls } generate_only() { - if [ -d $TEST_HOME ]; then - echo "$TEST_HOME directory detected" - else - echo "ERROR: $TEST_HOME does not exist" - exit - fi - rm -rf $TEST_HOME/compute $TEST_HOME/kubernetes $TEST_HOME/container_instance $TEST_HOME/function - export GENERATE_ONLY=true + if [ -d $TEST_HOME ]; then + echo "$TEST_HOME directory detected" + else + echo "ERROR: $TEST_HOME does not exist" + exit + fi + rm -rf $TEST_HOME/compute $TEST_HOME/kubernetes $TEST_HOME/container_instance $TEST_HOME/function + export GENERATE_ONLY=true } if [ "$PROJECT_DIR" != "" ]; then - echo "ERROR: PROJECT_DIR set. Exiting." - exit 1 + echo "ERROR: PROJECT_DIR set. Exiting." + exit 1 fi if [ -d $TEST_HOME ]; then - pre_git_refresh - if [ ! -f $TEST_HOME/group_common_env.sh ]; then - echo "ERROR: $TEST_HOME/group_common_env.sh not detected" - exit - fi + ELAPSED=0 + while [ ! -f "${TEST_HOME}/group_common_env.sh" ] && [ $ELAPSED -lt 3600 ]; do + echo "Waiting 10 secs that group_common_env.sh is available." + sleep 10 + ELAPSED=$((ELAPSED + 10)) + done + if [ ! -f "${TEST_HOME}/group_common_env.sh" ]; then + echo "ERROR: ${TEST_HOME}/group_common_env.sh not detected after 3600 secs" + exit 1 + fi + + pre_git_refresh else - pre_test_suite + pre_test_suite fi # generate_only cd $TEST_HOME diff --git a/test_suite/test_suite_shared.sh b/test_suite/test_suite_shared.sh index dbaf449e..520d4ebd 100755 --- a/test_suite/test_suite_shared.sh +++ b/test_suite/test_suite_shared.sh @@ -21,423 +21,450 @@ OPTION_BUILD_HOST=terraform export nocolorarg=1 exit_on_error() { - RESULT=$? - if [ $RESULT -eq 0 ]; then - echo "Success - $1" - else - echo "EXIT ON ERROR - HISTORY - $1 " - history 2 | cut -c1-256 - echo "Command Failed (RESULT=$RESULT)" - exit - fi + RESULT=$? + if [ $RESULT -eq 0 ]; then + echo "Success - $1" + else + echo "EXIT ON ERROR - HISTORY - $1 " + history 2 | cut -c1-256 + echo "Command Failed (RESULT=$RESULT)" + exit + fi } start_test() { - export TEST_NAME=$1 - if [ "$OPTION_GROUP_NAME" != "none" ]; then - export TEST_DIR=$TEST_HOME/$OPTION_DEPLOY/$TEST_NAME - else - export TEST_DIR=$TEST_HOME/no_group/$OPTION_DEPLOY/$TEST_NAME - mkdir -p $TEST_DIR - fi - echo "-- TEST: $OPTION_DEPLOY - $TEST_NAME ---------------------------------------" + export TEST_NAME=$1 + if [ "$OPTION_GROUP_NAME" != "none" ]; then + export TEST_DIR=$TEST_HOME/$OPTION_DEPLOY/$TEST_NAME + else + export TEST_DIR=$TEST_HOME/no_group/$OPTION_DEPLOY/$TEST_NAME + mkdir -p $TEST_DIR + fi + echo "-- TEST: $OPTION_DEPLOY - $TEST_NAME ---------------------------------------" } # Speed test of 100 calls test_run_100() { - START=$(date +%s.%N) - UI_URL=`cat $TMP_PATH/ui_url.txt` - x=0 - while [ $x -lt 100 ] - do - curl $UI_URL/app/dept -s -D $TMP_PATH/speed_json.log > $TMP_PATH/speed.json - if grep -q -i "deptno" $TMP_PATH/speed.json; then - CSV_RUN100_OK=$(( $CSV_RUN100_OK + 1 )) - fi - x=$(( $x + 1 )) + START=$(date +%s.%N) + UI_URL=`cat $TMP_PATH/ui_url.txt` + x=0 + while [ $x -lt 100 ]; do + curl $UI_URL/app/dept -s -D $TMP_PATH/speed_json.log > $TMP_PATH/speed.json + if grep -qiE "deptno|department" $TMP_PATH/speed.json; then + CSV_RUN100_OK=$(( $CSV_RUN100_OK + 1 )) + fi + x=$(( $x + 1 )) done - END=$(date +%s.%N) - CSV_RUN100_SECOND=`echo "scale=2;($END-$START)/1" | bc` - echo "Speed Test Result (100 runs):" - echo "- Time in seconds: $CSV_RUN100_SECOND" - echo "- OK (results including deptno): $CSV_RUN100_OK" + END=$(date +%s.%N) + CSV_RUN100_SECOND=`echo "scale=2;($END-$START)/1" | bc` + echo "Speed Test Result (100 runs):" + echo "- Time in seconds: $CSV_RUN100_SECOND" + echo "- OK (results including deptno or department): $CSV_RUN100_OK" } build_test () { - SECONDS=0 - # Change to the TEST_HOME directory first in case that the creation of TEST_DIR failed - cd $TEST_HOME - cd $TEST_DIR - pwd - ./starter.sh build --auto-approve > build_$BUILD_ID.log 2>&1 - - CSV_NAME=$PREFIX - CSV_DIR=$TEST_DIR - CSV_DATE=`date '+%Y%m%d-%H%M%S'` - CSV_BUILD_SECOND=$SECONDS - CSV_HTML_OK=0 - CSV_JSON_OK=0 - CSV_RUN100_SECOND=0 - CSV_RUN100_OK=0 - TMP_PATH="/tmp/$PREFIX" - - echo "build_secs_$BUILD_ID=$SECONDS" >> ${TEST_DIR}_time.txt - if [ -f $TMP_PATH/result_html.html ]; then - if grep -qiE "starter|deptno|messages" "$TMP_PATH/result_html.html"; then - echo -e "\u2705 RESULT HTML: OK" - CSV_HTML_OK=1 - else - echo -e "\u274C RESULT HTML - starter or deptno or messages not found. ***** BAD ******" - fi - if grep -q -i "deptno" $TMP_PATH/result_dept.json; then - echo -e "\u2705 RESULT JSON: deptno found - "`cat $TMP_PATH/result_dept.json` | cut -c 1-100 - CSV_JSON_OK=1 + SECONDS=0 + # Change to the TEST_HOME directory first in case that the creation of TEST_DIR failed + cd $TEST_HOME + cd $TEST_DIR + pwd + ./starter.sh build --auto-approve > build_$BUILD_ID.log 2>&1 + + CSV_NAME=$PREFIX + CSV_DIR=$TEST_DIR + CSV_DATE=`date '+%Y%m%d-%H%M%S'` + CSV_BUILD_SECOND=$SECONDS + CSV_HTML_OK=0 + CSV_JSON_OK=0 + CSV_RUN100_SECOND=0 + CSV_RUN100_OK=0 + TMP_PATH="/tmp/$PREFIX" + + echo "build_secs_$BUILD_ID=$SECONDS" >> ${TEST_DIR}_time.txt + if [ -f $TMP_PATH/result_html.html ]; then + if grep -qiE "starter|deptno|messages" "$TMP_PATH/result_html.html"; then + echo -e "\u2705 RESULT HTML: OK" + CSV_HTML_OK=1 + else + echo -e "\u274C RESULT HTML - starter or deptno or messages not found. ***** BAD ******" + fi + if [ -f $TMP_PATH/result_dept.json ]; then + if grep -qiE "deptno|department" $TMP_PATH/result_dept.json; then + echo -e "\u2705 RESULT JSON: deptno or department found - $(cut -c 1-100 "$TMP_PATH/result_dept.json")" + CSV_JSON_OK=1 + else + echo -e "\u274C RESULT JSON: no deptno or department found - $(cut -c 1-100 "$TMP_PATH/result_dept.json")" + fi + else + echo -e "\u274C ERROR: No file $TMP_PATH/result_dept.json" + fi + if [ -f $TMP_PATH/result_info.html ]; then + echo -e "\u2705 RESULT INFO: $(cut -c 1-100 "$TMP_PATH/result_info.html")" + else + echo -e "\u274C ERROR: No file $TMP_PATH/result_info.html" + fi else - echo -e "\u274C RESULT JSON: no deptno found - "`cat $TMP_PATH/result_dept.json` | cut -c 1-100 + echo -e "\u274C ERROR: No file $TMP_PATH/result_html.html" fi - echo -e "\u2139 RESULT INFO: "`cat $TMP_PATH/result_info.html` | cut -c 1-100 - else - echo -e "\u274C ERROR: No file $TMP_PATH/result_html.html" - fi - - mv $TMP_PATH/result_html.html ${TEST_DIR}_${BUILD_ID}_result_html.html 2>/dev/null; - mv $TMP_PATH/result_dept.json ${TEST_DIR}_${BUILD_ID}_result_dept.json 2>/dev/null; - mv $TMP_PATH/result_info.html ${TEST_DIR}_${BUILD_ID}_result_info.html 2>/dev/null; - mv $TMP_PATH/result_html.log ${TEST_DIR}_${BUILD_ID}_result_html.log 2>/dev/null; - mv $TMP_PATH/result_dept.log ${TEST_DIR}_${BUILD_ID}_result_dept.log 2>/dev/null; - mv $TMP_PATH/result_info.log ${TEST_DIR}_${BUILD_ID}_result_info.log 2>/dev/null; - - if [ "$CSV_JSON_OK" == "1" ]; then - test_run_100 - fi + echo "URL = $(cat $TMP_PATH/ui_url.txt)/" + + cp $TMP_PATH/result_html.html ${TEST_DIR}_${BUILD_ID}_result_html.html 2>/dev/null; + cp $TMP_PATH/result_dept.json ${TEST_DIR}_${BUILD_ID}_result_dept.json 2>/dev/null; + cp $TMP_PATH/result_info.html ${TEST_DIR}_${BUILD_ID}_result_info.html 2>/dev/null; + cp $TMP_PATH/result_html.log ${TEST_DIR}_${BUILD_ID}_result_html.log 2>/dev/null; + cp $TMP_PATH/result_dept.log ${TEST_DIR}_${BUILD_ID}_result_dept.log 2>/dev/null; + cp $TMP_PATH/result_info.log ${TEST_DIR}_${BUILD_ID}_result_info.log 2>/dev/null; + + if [ "$CSV_JSON_OK" == "1" ]; then + test_run_100 + fi } add_inprogress_rerun() { - echo "./test_rerun.sh $TEST_DIR" >> $TEST_HOME/inprogress_rerun.sh + echo "./test_rerun.sh $TEST_DIR" >> $TEST_HOME/inprogress_rerun.sh } add_errors_rerun() { - echo "./test_rerun.sh $TEST_DIR" >> $TEST_HOME/errors_rerun.sh - # Remove from inprogress_rerun - sed -i "\#$TEST_DIR#d" $TEST_HOME/inprogress_rerun.sh + echo "./test_rerun.sh $TEST_DIR" >> $TEST_HOME/errors_rerun.sh + # Remove from inprogress_rerun + sed -i "\#$TEST_DIR#d" $TEST_HOME/inprogress_rerun.sh } add_ok_rerun() { - echo "./test_rerun.sh $TEST_DIR" >> $TEST_HOME/ok_rerun.sh - # Remove from inprogress_rerun - sed -i "\#$TEST_DIR#d" $TEST_HOME/inprogress_rerun.sh - # Remove from errors_rerun - if [ -f $TEST_HOME/errors_rerun.sh ]; then - if grep -q "$TEST_DIR" $TEST_HOME/errors_rerun.sh; then - sed -i "\#$TEST_DIR#d" $TEST_HOME/errors_rerun.sh - echo "./test_rerun.sh $TEST_DIR" >> $TEST_HOME/errors_old.sh - fi - fi + echo "./test_rerun.sh $TEST_DIR" >> $TEST_HOME/ok_rerun.sh + # Remove from inprogress_rerun + sed -i "\#$TEST_DIR#d" $TEST_HOME/inprogress_rerun.sh + # Remove from errors_rerun + if [ -f $TEST_HOME/errors_rerun.sh ]; then + if grep -q "$TEST_DIR" $TEST_HOME/errors_rerun.sh; then + sed -i "\#$TEST_DIR#d" $TEST_HOME/errors_rerun.sh + echo "./test_rerun.sh $TEST_DIR" >> $TEST_HOME/errors_old.sh + fi + fi } build_test_destroy () { - BUILD_ID=1 - build_test - if [ "$BUILD_COUNT" = "2" ]; then - BUILD_ID=2 + BUILD_ID=1 build_test - fi - if [ -f $TEST_HOME/stop_after_build ]; then - echo "-------------------------------------------------------" - echo "stop_after_build file dectected" - echo "Exiting before destroy_all.sh" - echo "Last directory: $TEST_DIR" - rm $TEST_HOME/stop_after_build - exit - fi - if [ "$TEST_NO_DESTROY" != "" ]; then - echo "TEST_NO_DESTROY - Exiting before destroy_all.sh" - echo "Last directory: $TEST_DIR" - exit - fi - SECONDS=0 - ./starter.sh destroy --auto-approve > destroy.log 2>&1 - if [ -d "target" ]; then - # Avoid to have a lot of left resource in the tenancy after a lot of destroy that failed - echo "FATAL ERROR: target directory not fully destroyed" - echo "Last directory: $TEST_DIR" - exit - fi - - echo "destroy_secs=$SECONDS" >> ${TEST_DIR}_time.txt - CSV_DESTROY_SECOND=$SECONDS - cat ${TEST_DIR}_time.txt - - if [ "$OPTION_LANG" == "java" ]; then - echo "$CSV_DATE,$OPTION_DEPLOY,$OPTION_LANG,$OPTION_JAVA_FRAMEWORK,$OPTION_JAVA_VM,$OPTION_DB,$OPTION_DB_INSTALL,$OPTION_UI,$OPTION_SHAPE,$CSV_NAME,$CSV_HTML_OK,$CSV_JSON_OK,$CSV_BUILD_SECOND,$CSV_DESTROY_SECOND,$CSV_RUN100_OK,$CSV_RUN100_SECOND" >> $TEST_HOME/result.csv - elif [ "$OPTION_LANG" == "python" ]; then - echo "$CSV_DATE,$OPTION_DEPLOY,$OPTION_LANG,$OPTION_PYTHON_FRAMEWORK,-,$OPTION_DB,$OPTION_DB_INSTALL,$OPTION_UI,$OPTION_SHAPE,$CSV_NAME,$CSV_HTML_OK,$CSV_JSON_OK,$CSV_BUILD_SECOND,$CSV_DESTROY_SECOND,$CSV_RUN100_OK,$CSV_RUN100_SECOND" >> $TEST_HOME/result.csv - else - echo "$CSV_DATE,$OPTION_DEPLOY,$OPTION_LANG,-,-,$OPTION_DB,$OPTION_DB_INSTALL,$OPTION_UI,$OPTION_SHAPE,$CSV_NAME,$CSV_HTML_OK,$CSV_JSON_OK,$CSV_BUILD_SECOND,$CSV_DESTROY_SECOND,$CSV_RUN100_OK,$CSV_RUN100_SECOND" >> $TEST_HOME/result.csv - fi - if [ "$CSV_JSON_OK" != "1" ] || [ "$CSV_HTML_OK" != "1" ]; then - echo "$CSV_DATE,$OPTION_DEPLOY,$OPTION_LANG,$OPTION_JAVA_FRAMEWORK,$OPTION_JAVA_VM,$OPTION_DB,$OPTION_DB_INSTALL,$OPTION_UI,$OPTION_SHAPE,$CSV_NAME,$CSV_HTML_OK,$CSV_JSON_OK,$CSV_BUILD_SECOND,$CSV_DESTROY_SECOND,$CSV_RUN100_OK,$CSV_RUN100_SECOND" >> $TEST_HOME/errors.csv - add_errors_rerun - else - add_ok_rerun - fi - - if [ -f $TEST_HOME/stop_all_after_destroy ]; then - echo "-------------------------------------------------------" - echo "stop_all_after_destroy file dectected" - echo "Last directory: $TEST_DIR" - # rm $TEST_HOME/stop_all_after_destroy - exit - fi + if [ "$BUILD_COUNT" = "2" ]; then + BUILD_ID=2 + build_test + fi + if [ -f $TEST_HOME/stop_after_build ]; then + echo "-------------------------------------------------------" + echo "stop_after_build file dectected" + echo "Exiting before destroy_all.sh" + echo "Last directory: $TEST_DIR" + rm $TEST_HOME/stop_after_build + exit + fi + if [ "$TEST_RERUN_NO_DESTROY" != "" ]; then + echo "TEST_RERUN_NO_DESTROY - Exiting before destroy_all.sh" + echo "Last directory: $TEST_DIR" + exit + fi + SECONDS=0 + ./starter.sh destroy --auto-approve > destroy.log 2>&1 + if [ -d "target" ]; then + # Avoid to have a lot of left resource in the tenancy after a lot of destroy that failed + echo "FATAL ERROR: target directory not fully destroyed" + echo "Last directory: $TEST_DIR" + exit + fi + + echo "destroy_secs=$SECONDS" >> ${TEST_DIR}_time.txt + CSV_DESTROY_SECOND=$SECONDS + cat ${TEST_DIR}_time.txt + + if [ "$OPTION_LANG" == "java" ]; then + echo "$CSV_DATE,$OPTION_DEPLOY,$OPTION_LANG,$OPTION_JAVA_FRAMEWORK,$OPTION_JAVA_VM,$OPTION_DB,$OPTION_DB_INSTALL,$OPTION_UI,$OPTION_SHAPE,$CSV_NAME,$CSV_HTML_OK,$CSV_JSON_OK,$CSV_BUILD_SECOND,$CSV_DESTROY_SECOND,$CSV_RUN100_OK,$CSV_RUN100_SECOND" >> $TEST_HOME/result.csv + elif [ "$OPTION_LANG" == "python" ]; then + echo "$CSV_DATE,$OPTION_DEPLOY,$OPTION_LANG,$OPTION_PYTHON_FRAMEWORK,-,$OPTION_DB,$OPTION_DB_INSTALL,$OPTION_UI,$OPTION_SHAPE,$CSV_NAME,$CSV_HTML_OK,$CSV_JSON_OK,$CSV_BUILD_SECOND,$CSV_DESTROY_SECOND,$CSV_RUN100_OK,$CSV_RUN100_SECOND" >> $TEST_HOME/result.csv + else + echo "$CSV_DATE,$OPTION_DEPLOY,$OPTION_LANG,-,-,$OPTION_DB,$OPTION_DB_INSTALL,$OPTION_UI,$OPTION_SHAPE,$CSV_NAME,$CSV_HTML_OK,$CSV_JSON_OK,$CSV_BUILD_SECOND,$CSV_DESTROY_SECOND,$CSV_RUN100_OK,$CSV_RUN100_SECOND" >> $TEST_HOME/result.csv + fi + if [ "$CSV_JSON_OK" != "1" ] || [ "$CSV_HTML_OK" != "1" ]; then + echo "$CSV_DATE,$OPTION_DEPLOY,$OPTION_LANG,$OPTION_JAVA_FRAMEWORK,$OPTION_JAVA_VM,$OPTION_DB,$OPTION_DB_INSTALL,$OPTION_UI,$OPTION_SHAPE,$CSV_NAME,$CSV_HTML_OK,$CSV_JSON_OK,$CSV_BUILD_SECOND,$CSV_DESTROY_SECOND,$CSV_RUN100_OK,$CSV_RUN100_SECOND" >> $TEST_HOME/errors.csv + add_errors_rerun + else + add_ok_rerun + fi + + if [ -f $TEST_HOME/stop_all_after_destroy ]; then + echo "-------------------------------------------------------" + echo "stop_all_after_destroy file dectected" + echo "Last directory: $TEST_DIR" + # rm $TEST_HOME/stop_all_after_destroy + exit + fi } build_option() { - mkdir_deploy - if [ "$OPTION_TLS" != "none" ]; then - NAME=tls-${OPTION_TLS}-${OPTION_DEPLOY} - elif [ "$OPTION_LANG" == "java" ] && [ "$OPTION_DEPLOY" != "function" ]; then - NAME=${OPTION_LANG}-${OPTION_JAVA_FRAMEWORK}-${OPTION_JAVA_VM}-${OPTION_DB}-${OPTION_UI} - elif [ "$OPTION_LANG" == "python" ] && [ "$OPTION_DEPLOY" != "function" ]; then - NAME=${OPTION_LANG}-${OPTION_PYTHON_FRAMEWORK}-${OPTION_DB}-${OPTION_UI} - else - NAME=${OPTION_LANG}-${OPTION_DB}-${OPTION_UI} - fi - if [ "$OPTION_SHAPE" != "amd" ]; then - NAME=${NAME}-$OPTION_SHAPE - fi - if [ "$OPTION_BUILD_HOST" != "terraform" ]; then - NAME=${NAME}-bh - fi - if [ "$OPTION_INFRA_AS_CODE" == "resource_manager" ]; then - NAME=${NAME}-rm - elif [ "$OPTION_INFRA_AS_CODE" == "from_resource_manager" ]; then - NAME=${NAME}-frm - fi - NAME=${NAME/_/-} - NAME=${NAME/_/-} - NAME=${NAME/_/-} - start_test $NAME - if [ "$TEST_DIRECTORY_ONLY" != "" ]; then - if [ "$TEST_DIRECTORY_ONLY" == "$TEST_DIR" ]; then - echo "FOUND TEST_DIRECTORY_ONLY: $TEST_DIR" + mkdir_deploy + if [ "$OPTION_TLS" != "none" ]; then + NAME=tls-${OPTION_TLS}-${OPTION_DEPLOY} + elif [ "$OPTION_LANG" == "java" ] && [ "$OPTION_DEPLOY" != "function" ]; then + NAME=${OPTION_LANG}-${OPTION_JAVA_FRAMEWORK}-${OPTION_JAVA_VM}-${OPTION_DB}-${OPTION_UI} + elif [ "$OPTION_LANG" == "python" ] && [ "$OPTION_DEPLOY" != "function" ]; then + NAME=${OPTION_LANG}-${OPTION_PYTHON_FRAMEWORK}-${OPTION_DB}-${OPTION_UI} else - echo "SKIP: $TEST_DIR" - return + NAME=${OPTION_LANG}-${OPTION_DB}-${OPTION_UI} fi - else - if grep -q "$TEST_DIR" $TEST_HOME/inprogress_rerun.sh; then - echo "SKIP - FOUND in inprogress_rerun.sh: $TEST_DIR" - return + if [ "$OPTION_SHAPE" != "amd" ]; then + NAME=${NAME}-$OPTION_SHAPE fi - if grep -q "$TEST_DIR" $TEST_HOME/ok_rerun.sh; then - echo "SKIP - FOUND in ok_rerun.sh: $TEST_DIR" - return + if [ "$OPTION_BUILD_HOST" != "terraform" ]; then + NAME=${NAME}-bh + fi + if [ "$OPTION_INFRA_AS_CODE" == "resource_manager" ]; then + NAME=${NAME}-rm + elif [ "$OPTION_INFRA_AS_CODE" == "from_resource_manager" ]; then + NAME=${NAME}-frm fi - if [ "$TEST_ERRORS_ONLY" = "" ]; then - if [ -f $TEST_HOME/errors_rerun.sh ]; then - if grep -q "$TEST_DIR" $TEST_HOME/errors_rerun.sh; then - echo "SKIP - FOUND in errors_rerun.sh: $TEST_DIR" - return + NAME=${NAME/_/-} + NAME=${NAME/_/-} + NAME=${NAME/_/-} + start_test $NAME + if [ "$TEST_DIRECTORY_ONLY" != "" ]; then + if [ "$TEST_DIRECTORY_ONLY" == "$TEST_DIR" ]; then + echo "FOUND TEST_DIRECTORY_ONLY: $TEST_DIR" + else + echo "SKIP: $TEST_DIR" + return + fi + else + if grep -q "$TEST_DIR" $TEST_HOME/inprogress_rerun.sh; then + echo "SKIP - FOUND in inprogress_rerun.sh: $TEST_DIR" + return + fi + if grep -q "$TEST_DIR" $TEST_HOME/ok_rerun.sh; then + echo "SKIP - FOUND in ok_rerun.sh: $TEST_DIR" + return + fi + if [ "$TEST_ERRORS_ONLY" = "" ]; then + if [ -f $TEST_HOME/errors_rerun.sh ]; then + if grep -q "$TEST_DIR" $TEST_HOME/errors_rerun.sh; then + echo "SKIP - FOUND in errors_rerun.sh: $TEST_DIR" + return + fi + fi fi - fi fi - fi - add_inprogress_rerun - - # Prevent to have undeleted resource when rerunning the test_suite - if [ -d $TEST_DIR/target ]; then - cd $TEST_DIR - ./starter.sh destroy --auto-approve > destroy_before_refresh.log 2>&1 - if [ -d $TEST_DIR/target ]; then - echo "ERROR: Existing target directory detected. Destroy failed." - exit 1 - fi - fi - - # Prevent to start test build if the group_common was not finished - if [ ! -f $TEST_HOME/group_common_env.sh ]; then - echo "ERROR: $TEST_HOME/group_common_env.sh not found" - exit 1 - fi - - # Avoid 2 parallel creations of code - while [ -f $TEST_HOME/oci_starter_busy ]; do - echo "FOUND oci_starter_busy - Waiting" - sleep 5 - done - touch $TEST_HOME/oci_starter_busy - - cd $TEST_HOME/oci-starter - if [ "$OPTION_GROUP_NAME" == "dummy" ]; then - PREFIX=$NAME - echo ./oci_starter.sh\ - -prefix $PREFIX \ - -deploy $OPTION_DEPLOY \ - -ui $OPTION_UI \ - -language $OPTION_LANG \ - -build_host $OPTION_BUILD_HOST \ - -java_framework $OPTION_JAVA_FRAMEWORK \ - -java_vm $OPTION_JAVA_VM \ - -python_framework $OPTION_PYTHON_FRAMEWORK \ - -database $OPTION_DB \ - -db_password $TEST_DB_PASSWORD \ - -db_install $OPTION_DB_INSTALL \ - -group_common $OPTION_GROUP_NAME \ - -infra_as_code $OPTION_INFRA_AS_CODE \ - -shape $OPTION_SHAPE \ - -tls $OPTION_TLS \ - -compartment_ocid $EX_COMPARTMENT_OCID \ - -vcn_ocid $TF_VAR_vcn_ocid \ - -web_subnet_ocid $TF_VAR_web_subnet_ocid \ - -app_subnet_ocid $TF_VAR_app_subnet_ocid \ - -db_subnet_ocid $TF_VAR_db_subnet_ocid \ - -oke_ocid $OKE_OCID \ - -atp_ocid $TF_VAR_atp_ocid \ - -db_ocid $TF_VAR_db_ocid \ - -mysql_ocid $TF_VAR_mysql_ocid \ - -psql_ocid $TF_VAR_psql_ocid \ - -opensearch_ocid $TF_VAR_opensearch_ocid \ - -nosql_ocid $TF_VAR_nosql_ocid \ - -apigw_ocid $TF_VAR_apigw_ocid \ - -bastion_ocid $TF_VAR_bastion_ocid \ - -fnapp_ocid $TF_VAR_fnapp_ocid > ${TEST_DIR}.log 2>&1 - ./oci_starter.sh \ - -prefix $PREFIX \ - -deploy $OPTION_DEPLOY \ - -ui $OPTION_UI \ - -language $OPTION_LANG \ - -build_host $OPTION_BUILD_HOST \ - -java_framework $OPTION_JAVA_FRAMEWORK \ - -java_vm $OPTION_JAVA_VM \ - -python_framework $OPTION_PYTHON_FRAMEWORK \ - -database $OPTION_DB \ - -db_password $TEST_DB_PASSWORD \ - -db_install $OPTION_DB_INSTALL \ - -group_common $OPTION_GROUP_NAME \ - -infra_as_code $OPTION_INFRA_AS_CODE \ - -shape $OPTION_SHAPE \ - -tls $OPTION_TLS \ - -compartment_ocid $EX_COMPARTMENT_OCID \ - -vcn_ocid $TF_VAR_vcn_ocid \ - -web_subnet_ocid $TF_VAR_web_subnet_ocid \ - -app_subnet_ocid $TF_VAR_app_subnet_ocid \ - -db_subnet_ocid $TF_VAR_db_subnet_ocid \ - -oke_ocid $OKE_OCID \ - -atp_ocid $TF_VAR_atp_ocid \ - -db_ocid $TF_VAR_db_ocid \ - -mysql_ocid $TF_VAR_mysql_ocid \ - -psql_ocid $TF_VAR_psql_ocid \ - -opensearch_ocid $TF_VAR_opensearch_ocid \ - -nosql_ocid $TF_VAR_nosql_ocid \ - -apigw_ocid $TF_VAR_apigw_ocid \ - -bastion_ocid $TF_VAR_bastion_ocid \ - -fnapp_ocid $TF_VAR_fnapp_ocid >> ${TEST_DIR}.log 2>&1 - else - # Unique name to allow more generations of TLS certificates. The prefix is used as hostname for TLS http_01. - OPTION_TSONE_ID=$((OPTION_TSONEID+1)) - PREFIX=tsone${OPTION_TSONE_ID} - ./oci_starter.sh \ - -prefix $PREFIX \ - -deploy $OPTION_DEPLOY \ - -ui $OPTION_UI \ - -language $OPTION_LANG \ - -java_framework $OPTION_JAVA_FRAMEWORK \ - -java_vm $OPTION_JAVA_VM \ - -database $OPTION_DB \ - -db_password $TEST_DB_PASSWORD \ - -db_install $OPTION_DB_INSTALL \ - -group_common $OPTION_GROUP_NAME \ - -infra_as_code $OPTION_INFRA_AS_CODE \ - -shape $OPTION_SHAPE \ - -tls $OPTION_TLS \ - -compartment_ocid $EX_COMPARTMENT_OCID > ${TEST_DIR}.log 2>&1 - fi -# -db_compartment_ocid $EX_COMPARTMENT_OCID \ - rm $TEST_HOME/oci_starter_busy - - RESULT=$? - if [ $RESULT -eq 0 ] && [ -d output ]; then - mkdir output/target - cp $TEST_HOME/group_common/target/ssh* output/target/. - rm -Rf $TEST_DIR - if [ -f ${TEST_DIR}_time.txt ]; then - rm ${TEST_DIR}_* + add_inprogress_rerun + + # Prevent to have undeleted resource when rerunning the test_suite + if [ -d $TEST_DIR/target ]; then + if [ "$TEST_RERUN_REFRESH" == "" ]; then + echo "target directory found. Destroying." + cd $TEST_DIR + ./starter.sh destroy --auto-approve > destroy_before_refresh.log 2>&1 + if [ -d $TEST_DIR/target ]; then + echo "ERROR: Existing target directory detected. Destroy failed." + exit 1 + fi + else + echo "TEST_RERUN_REFRESH=$TEST_RERUN_REFRESH - backup up directory." + if [ -d /tmp/$TEST_DIR/target ]; then + echo "ERROR: Existing target directory detected (/tmp/$TEST_DIR/target). Refresh failed." + exit 1 + else + rm -Rf /tmp/$TEST_DIR + mv $TEST_DIR /tmp/$TEST_DIR + fi + fi + fi + + # Prevent to start test build if the group_common was not finished + if [ ! -f $TEST_HOME/group_common_env.sh ]; then + echo "ERROR: $TEST_HOME/group_common_env.sh not found" + exit 1 + fi + + # Avoid 2 parallel creations of code + while [ -f $TEST_HOME/oci_starter_busy ]; do + echo "FOUND oci_starter_busy - Waiting" + sleep 5 + done + touch $TEST_HOME/oci_starter_busy + + cd $TEST_HOME/oci-starter + if [ "$OPTION_GROUP_NAME" == "dummy" ]; then + PREFIX=$NAME + echo ./oci_starter.sh\ + -prefix $PREFIX \ + -deploy $OPTION_DEPLOY \ + -ui $OPTION_UI \ + -language $OPTION_LANG \ + -build_host $OPTION_BUILD_HOST \ + -java_framework $OPTION_JAVA_FRAMEWORK \ + -java_vm $OPTION_JAVA_VM \ + -python_framework $OPTION_PYTHON_FRAMEWORK \ + -database $OPTION_DB \ + -db_password $TEST_DB_PASSWORD \ + -db_install $OPTION_DB_INSTALL \ + -group_common $OPTION_GROUP_NAME \ + -infra_as_code $OPTION_INFRA_AS_CODE \ + -shape $OPTION_SHAPE \ + -tls $OPTION_TLS \ + -compartment_ocid $EX_COMPARTMENT_OCID \ + -vcn_ocid $TF_VAR_vcn_ocid \ + -web_subnet_ocid $TF_VAR_web_subnet_ocid \ + -app_subnet_ocid $TF_VAR_app_subnet_ocid \ + -db_subnet_ocid $TF_VAR_db_subnet_ocid \ + -oke_ocid $OKE_OCID \ + -atp_ocid $TF_VAR_atp_ocid \ + -db_ocid $TF_VAR_db_ocid \ + -mysql_ocid $TF_VAR_mysql_ocid \ + -psql_ocid $TF_VAR_psql_ocid \ + -opensearch_ocid $TF_VAR_opensearch_ocid \ + -nosql_ocid $TF_VAR_nosql_ocid \ + -apigw_ocid $TF_VAR_apigw_ocid \ + -bastion_ocid $TF_VAR_bastion_ocid \ + -fnapp_ocid $TF_VAR_fnapp_ocid \ + -test_name $TEST_NAME > ${TEST_DIR}.log 2>&1 + ./oci_starter.sh \ + -prefix $PREFIX \ + -deploy $OPTION_DEPLOY \ + -ui $OPTION_UI \ + -language $OPTION_LANG \ + -build_host $OPTION_BUILD_HOST \ + -java_framework $OPTION_JAVA_FRAMEWORK \ + -java_vm $OPTION_JAVA_VM \ + -python_framework $OPTION_PYTHON_FRAMEWORK \ + -database $OPTION_DB \ + -db_password $TEST_DB_PASSWORD \ + -db_install $OPTION_DB_INSTALL \ + -group_common $OPTION_GROUP_NAME \ + -infra_as_code $OPTION_INFRA_AS_CODE \ + -shape $OPTION_SHAPE \ + -tls $OPTION_TLS \ + -compartment_ocid $EX_COMPARTMENT_OCID \ + -vcn_ocid $TF_VAR_vcn_ocid \ + -web_subnet_ocid $TF_VAR_web_subnet_ocid \ + -app_subnet_ocid $TF_VAR_app_subnet_ocid \ + -db_subnet_ocid $TF_VAR_db_subnet_ocid \ + -oke_ocid $OKE_OCID \ + -atp_ocid $TF_VAR_atp_ocid \ + -db_ocid $TF_VAR_db_ocid \ + -mysql_ocid $TF_VAR_mysql_ocid \ + -psql_ocid $TF_VAR_psql_ocid \ + -opensearch_ocid $TF_VAR_opensearch_ocid \ + -nosql_ocid $TF_VAR_nosql_ocid \ + -apigw_ocid $TF_VAR_apigw_ocid \ + -bastion_ocid $TF_VAR_bastion_ocid \ + -fnapp_ocid $TF_VAR_fnapp_ocid \ + -test_name $TEST_NAME >> ${TEST_DIR}.log 2>&1 + else + # Unique name to allow more generations of TLS certificates. The prefix is used as hostname for TLS http_01. + OPTION_TSONE_ID=$((OPTION_TSONEID+1)) + PREFIX=tsone${OPTION_TSONE_ID} + ./oci_starter.sh \ + -prefix $PREFIX \ + -deploy $OPTION_DEPLOY \ + -ui $OPTION_UI \ + -language $OPTION_LANG \ + -java_framework $OPTION_JAVA_FRAMEWORK \ + -java_vm $OPTION_JAVA_VM \ + -database $OPTION_DB \ + -db_password $TEST_DB_PASSWORD \ + -db_install $OPTION_DB_INSTALL \ + -group_common $OPTION_GROUP_NAME \ + -infra_as_code $OPTION_INFRA_AS_CODE \ + -shape $OPTION_SHAPE \ + -tls $OPTION_TLS \ + -compartment_ocid $EX_COMPARTMENT_OCID > ${TEST_DIR}.log 2>&1 + fi + # -db_compartment_ocid $EX_COMPARTMENT_OCID \ + rm $TEST_HOME/oci_starter_busy + + RESULT=$? + if [ $RESULT -eq 0 ] && [ -d output ]; then + mkdir output/target + cp $TEST_HOME/group_common/target/ssh* output/target/. + rm -Rf $TEST_DIR + if [ -f ${TEST_DIR}_time.txt ]; then + rm ${TEST_DIR}_* + fi + mv output $TEST_DIR + mv $TEST_DIR/src/done.sh $TEST_DIR/src/done_orig.sh + cp $SCRIPT_DIR/test_done.sh $TEST_DIR/src/done.sh + if [ "$TEST_RERUN_REFRESH" != "" ]; then + mv /tmp/$TEST_DIR/target $TEST_DIR/. + echo "Refresh done" + exit 0 + fi + if [ -z $GENERATE_ONLY ]; then + build_test_destroy + fi + else + echo -e "\u274C ERROR ./oci_starter.sh failed." + echo "Check ${TEST_DIR}.log" + add_errors_rerun + fi + + # Stop after finding the TEST_DIRECTORY_ONLY + if [ "$TEST_DIRECTORY_ONLY" != "" ]; then + exit fi - mv output $TEST_DIR - mv $TEST_DIR/src/done.sh $TEST_DIR/src/done_orig.sh - cp $SCRIPT_DIR/test_done.sh $TEST_DIR/src/done.sh - if [ -z $GENERATE_ONLY ]; then - build_test_destroy - fi - else - echo -e "\u274C ERROR ./oci_starter.sh failed." - echo "Check ${TEST_DIR}.log" - add_errors_rerun - fi - - # Stop after finding the TEST_DIRECTORY_ONLY - if [ "$TEST_DIRECTORY_ONLY" != "" ]; then - exit - fi } # Create the $OPTION_DEPLOY directory mkdir_deploy() { - if [ ! -d $TEST_HOME/$OPTION_DEPLOY ]; then - mkdir $TEST_HOME/$OPTION_DEPLOY - echo '. $PROJECT_DIR/../../group_common_env.sh' > $TEST_HOME/$OPTION_DEPLOY/group_common_env.sh - chmod +x $TEST_HOME/$OPTION_DEPLOY/group_common_env.sh - fi + if [ ! -d $TEST_HOME/$OPTION_DEPLOY ]; then + mkdir $TEST_HOME/$OPTION_DEPLOY + echo '. $PROJECT_DIR/../../group_common_env.sh' > $TEST_HOME/$OPTION_DEPLOY/group_common_env.sh + chmod +x $TEST_HOME/$OPTION_DEPLOY/group_common_env.sh + fi } pre_test_suite() { - if [ -d $TEST_HOME ]; then - echo "$TEST_HOME directory already exists" - exit; - fi - - - # Avoid already set variables - unset "${!TF_VAR@}" - - mkdir $TEST_HOME - cd $TEST_HOME - git clone https://github.com/mgueury/oci-starter - touch inprogress_rerun.sh - touch ok_rerun.sh - - SHAPE_GROUP="amd" - if [[ `arch` == "aarch64" ]]; then - SHAPE_GROUP="arm" - fi - GROUP_NAME="ts${SHAPE_GROUP}" - - cd $TEST_HOME/oci-starter - ./oci_starter.sh -group_name $GROUP_NAME -group_common atp,mysql,psql,opensearch,nosql,database,fnapp,apigw,oke -compartment_ocid $EX_COMPARTMENT_OCID -db_password $TEST_DB_PASSWORD -shape $SHAPE_GROUP - exit_on_error "oci_starter.sh" - mv output/group_common ../group_common - cd $TEST_HOME/group_common - echo "# Test Suite use 2 nodes to avoid error: Too Many Pods (110 pods/node K8s limit)" >> terraform.tfvars - echo "node_pool_size=2" >> terraform.tfvars - echo "" >> terraform.tfvars - ./starter.sh build --auto-approve - exit_on_error "starter.sh build" - date - echo "CSV_DATE,OPTION_DEPLOY,OPTION_LANG,OPTION_JAVA_FRAMEWORK,OPTION_JAVA_VM,OPTION_DB,OPTION_DB_INSTALL,OPTION_UI,OPTION_SHAPE,CSV_NAME,CSV_HTML_OK,CSV_JSON_OK,CSV_BUILD_SECOND,CSV_DESTROY_SECOND,CSV_RUN100_OK,CSV_RUN100_SECOND" > $TEST_HOME/result.csv + if [ -d $TEST_HOME ]; then + echo "$TEST_HOME directory already exists" + exit; + fi + + + # Avoid already set variables + unset "${!TF_VAR@}" + + mkdir $TEST_HOME + cd $TEST_HOME + git clone https://github.com/mgueury/oci-starter + touch inprogress_rerun.sh + touch ok_rerun.sh + + SHAPE_GROUP="amd" + if [[ `arch` == "aarch64" ]]; then + SHAPE_GROUP="arm" + fi + GROUP_NAME="ts${SHAPE_GROUP}" + + cd $TEST_HOME/oci-starter + ./oci_starter.sh -group_name $GROUP_NAME -group_common atp,mysql,psql,opensearch,nosql,database,fnapp,apigw,oke -compartment_ocid $EX_COMPARTMENT_OCID -db_password $TEST_DB_PASSWORD -shape $SHAPE_GROUP + exit_on_error "oci_starter.sh" + mv output/group_common ../group_common + cd $TEST_HOME/group_common + echo "# Test Suite use 2 nodes to avoid error: Too Many Pods (110 pods/node K8s limit)" >> terraform.tfvars + echo "node_pool_size=2" >> terraform.tfvars + echo "" >> terraform.tfvars + ./starter.sh build --auto-approve + exit_on_error "starter.sh build" + date + echo "CSV_DATE,OPTION_DEPLOY,OPTION_LANG,OPTION_JAVA_FRAMEWORK,OPTION_JAVA_VM,OPTION_DB,OPTION_DB_INSTALL,OPTION_UI,OPTION_SHAPE,CSV_NAME,CSV_HTML_OK,CSV_JSON_OK,CSV_BUILD_SECOND,CSV_DESTROY_SECOND,CSV_RUN100_OK,CSV_RUN100_SECOND" > $TEST_HOME/result.csv } pre_git_refresh() { - cd $TEST_HOME/oci-starter - git pull origin main - echo "----------------------------------------------------------------------------" >> $TEST_HOME/errors_rerun.sh + cd $TEST_HOME/oci-starter + git pull origin main + echo "----------------------------------------------------------------------------" >> $TEST_HOME/errors_rerun.sh } post_test_suite() { - date + date - cd $TEST_HOME/group_common - ./starter.sh destroy --auto-approve + cd $TEST_HOME/group_common + ./starter.sh destroy --auto-approve } diff --git a/todo_oci_bastion/deploy_compute.sh b/todo_oci_bastion/deploy_compute.sh index 52f23888..b2d3f9eb 100755 --- a/todo_oci_bastion/deploy_compute.sh +++ b/todo_oci_bastion/deploy_compute.sh @@ -20,5 +20,5 @@ eval "$(ssh-agent -s)" ssh-add $TF_VAR_ssh_private_path scp -r -o StrictHostKeyChecking=no -oProxyCommand="ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -W %h:%p $BASTION_USER_HOST" target/compute/* opc@$BASTION_IP:/home/opc/. -ssh -o StrictHostKeyChecking=no -oProxyCommand="ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -W %h:%p $BASTION_USER_HOST" opc@$BASTION_IP "export TF_VAR_java_version=\"$TF_VAR_java_version\";export TF_VAR_java_vm=\"$TF_VAR_java_vm\";export TF_VAR_language=\"$TF_VAR_language\";export JDBC_URL=\"$JDBC_URL\";export DB_URL=\"$DB_URL\";export DB_USER=\"$TF_VAR_db_user\";export DB_PASSWORD=\"$TF_VAR_db_password\";export TF_VAR_namespace=\"$TF_VAR_namespace\";export TF_VAR_prefix=\"$TF_VAR_prefix\";bash compute/compute_install.sh 2>&1 | tee -a compute/compute_install.log" +ssh -o StrictHostKeyChecking=no -oProxyCommand="ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -W %h:%p $BASTION_USER_HOST" opc@$BASTION_IP "export TF_VAR_java_version=\"$TF_VAR_java_version\";export TF_VAR_java_vm=\"$TF_VAR_java_vm\";export TF_VAR_language=\"$TF_VAR_language\";export JDBC_URL=\"$JDBC_URL\";export DB_URL=\"$DB_URL\";export DB_USER=\"$TF_VAR_db_user\";export DB_PASSWORD=\"$TF_VAR_db_password\";export TF_VAR_namespace=\"$TF_VAR_namespace\";export TF_VAR_prefix=\"$TF_VAR_prefix\";bash compute/compute_install.sh 2>&1 | tee compute/compute_install.log"