Skip to content

Instantly share code, notes, and snippets.

@twistedpair
Last active January 23, 2023 04:29
Show Gist options
  • Save twistedpair/d067fff02d96909b8e4876f9fa6249ed to your computer and use it in GitHub Desktop.
Save twistedpair/d067fff02d96909b8e4876f9fa6249ed to your computer and use it in GitHub Desktop.
Run an arbitrary script in a bash script via Docker containers. See `build_and_run_demo.sh` to build and run demo.
#!/bin/bash
set -e
docker build --build-arg=GCLOUD_VERSION=226.0.0 -t gcloud-bash -f Dockerfile-gcloud-bash .
docker build -t flask-bash -f Dockerfile-flask-bash .
PORT=5000
docker run -d --name flask-server -p ${PORT}:${PORT} -e PORT=${PORT} flask-bash
echo "3 second sleep for server warmup..."
sleep 3
curl -X POST "localhost:${PORT}/do"
# Cleanup
docker stop flask-server
docker container rm flask-server
FROM gcloud-bash
# Common utils also used with gcloud/bash
RUN apt-get update -qqy \
&& apt-get -qqy install python3-virtualenv python3-pip\
&& apt-get -qyy autoremove \
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/*
RUN pip3 install flask flask-api
# Copy server and example script
COPY server.py script.sh ./
RUN chmod +x script.sh
# Boot server
CMD ["python3","server.py"]
FROM buildpack-deps:jessie
ARG GCLOUD_VERSION
ARG GCLOUD_AUTO_UPGRADE
# Common utils also used with gcloud/bash
RUN apt-get update -qqy \
&& apt-get -qqy install jq \
&& apt-get -qyy autoremove \
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/*
COPY install_gcloud.sh ./
RUN chmod +x install_gcloud.sh && ./install_gcloud.sh ${GCLOUD_VERSION} ${GCLOUD_AUTO_UPGRADE}\
&& rm install_gcloud.sh
# Add to path
# See also /opt/gcloud/google-cloud-sdk/path.bash.inc
ENV PATH="/opt/gcloud/google-cloud-sdk/bin:${PATH}"
#!/bin/bash
set -e
GCLOUD_VERSION=$1
GCLOUD_AUTO_UPGRADE=$2 # use latest
if [ -x "/root/google-cloud-sdk" ]; then
echo "Skipping gcloud install, already installed"
else
echo "Installing gcloud [${GCLOUD_VERSION}] from installer.sh"
mkdir /opt/gcloud -p
cd /opt/gcloud
wget --quiet -O gcloud.tgz "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-${GCLOUD_VERSION}-linux-x86_64.tar.gz"
tar -xf gcloud.tgz
rm gcloud.tgz
./google-cloud-sdk/install.sh --quiet
source /opt/gcloud/google-cloud-sdk/path.bash.inc
gcloud components install --quiet kubectl alpha beta
if [ "${GCLOUD_AUTO_UPGRADE}" = 'true' ]; then
echo "Upgrade to latest gcloud version"
gcloud components update --quiet
fi
fi
gcloud --version # Sanity check
#!/bin/bash
set -e
echo "This is an EMPTY example script"
#!bin/python3
import os
from flask import Flask, jsonify
from flask_api.status import HTTP_200_OK, HTTP_500_INTERNAL_SERVER_ERROR
from subprocess import Popen, PIPE, TimeoutExpired
from signal import SIGTERM
app = Flask(__name__)
# Target script is assumed to be in the same directory
TARGET_COMMAND='./script.sh'
TIMEOUT_SECONDS=60
@app.route('/do', methods=['POST'])
def index():
# Make all children in same process group so we can clean up things spawned by bash script
process = Popen(['bash', '-c', TARGET_COMMAND], stdout=PIPE, stderr=PIPE, preexec_fn=os.setsid)
try:
out, err = process.communicate(timeout=TIMEOUT_SECONDS)
if err:
return prepare_json(err.decode("utf-8"), success=False), HTTP_500_INTERNAL_SERVER_ERROR
return prepare_json(out.decode("utf-8")), HTTP_200_OK
except TimeoutExpired as e:
os.killpg(os.getpgid(process.pid), SIGTERM) # Send term to bash and all process groups
return prepare_json('Process timedout in [%d] seconds' % (TIMEOUT_SECONDS,), success=False), HTTP_500_INTERNAL_SERVER_ERROR
except Exception as e:
os.killpg(os.getpgid(process.pid), SIGTERM) # Send term to bash and all process groups
return prepare_json('Process exception', success=False), HTTP_500_INTERNAL_SERVER_ERROR
def prepare_json(message, success=True):
result = {
'success': success,
'message': message.strip()
}
return jsonify(result)
if __name__ == '__main__':
port=os.environ['PORT']
app.run(debug=False,host='0.0.0.0',port=port)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment