Our data portal is currently in maintenance, please try in a while.
- - diff --git a/images/ckan/2.7/setup/app/maintenance/index.html b/images/ckan/2.7/setup/app/maintenance/index.html deleted file mode 100644 index 50276ec..0000000 --- a/images/ckan/2.7/setup/app/maintenance/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - -Our data portal is currently in maintenance, please try in a while.
- - diff --git a/images/ckan/2.7/setup/app/maintenance/serve.py b/images/ckan/2.7/setup/app/maintenance/serve.py deleted file mode 100644 index 96c0a15..0000000 --- a/images/ckan/2.7/setup/app/maintenance/serve.py +++ /dev/null @@ -1,38 +0,0 @@ -""" -Copyright (c) 2016 Keitaro AB - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -from SimpleHTTPServer import SimpleHTTPRequestHandler -from BaseHTTPServer import HTTPServer -from SocketServer import ThreadingMixIn -import os - -PORT = 5000 - -web_dir = os.path.join(os.path.dirname(__file__)) -os.chdir(web_dir) - -Handler = SimpleHTTPRequestHandler - - -class MaintenanceServer(ThreadingMixIn, HTTPServer): - """Handle requests in a separate thread.""" - - -if __name__ == "__main__": - httpd = MaintenanceServer(("0.0.0.0", PORT), Handler) - print("Starting maintenance mode") - httpd.serve_forever() - diff --git a/images/ckan/2.7/setup/app/prerun.py b/images/ckan/2.7/setup/app/prerun.py deleted file mode 100644 index 4065df5..0000000 --- a/images/ckan/2.7/setup/app/prerun.py +++ /dev/null @@ -1,200 +0,0 @@ -""" -Copyright (c) 2016 Keitaro AB - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -import os -import sys -import subprocess -import psycopg2 -import urllib2 -import re - -import time - -ckan_ini = os.environ.get('CKAN_INI', '/srv/app/production.ini') - -RETRY = 5 - -def check_db_connection(retry=None): - - print('[prerun] Start check_db_connection...') - - if retry is None: - retry = RETRY - elif retry == 0: - print('[prerun] Giving up after 5 tries...') - sys.exit(1) - - conn_str = os.environ.get('CKAN_SQLALCHEMY_URL', '') - try: - connection = psycopg2.connect(conn_str) - - except psycopg2.Error as e: - print((str(e))) - print('[prerun] Unable to connect to the database...try again in a while.') - import time - time.sleep(10) - check_db_connection(retry = retry - 1) - else: - connection.close() - -def check_solr_connection(retry=None): - - print('[prerun] Start check_solr_connection...') - - if retry is None: - retry = RETRY - elif retry == 0: - print('[prerun] Giving up after 5 tries...') - sys.exit(1) - - url = os.environ.get('CKAN_SOLR_URL', '') - search_url = '{url}/select/?q=*&wt=json'.format(url=url) - - try: - connection = urllib2.urlopen(search_url) - except urllib2.URLError as e: - print('[prerun] Unable to connect to solr...try again in a while.') - import time - time.sleep(10) - check_solr_connection(retry = retry - 1) - else: - import re - conn_info = connection.read() - # SolrCloud - conn_info = re.sub(r'"zkConnected":true', '"zkConnected":True', conn_info) - eval(conn_info) - -def init_db(): - - print('[prerun] Start init_db...') - - db_command = ['paster', '--plugin=ckan', 'db', 'init', '-c', ckan_ini] - - print('[prerun] Initializing or upgrading db - start using paster db init') - try: - # run init scripts - subprocess.check_output(db_command, stderr=subprocess.STDOUT) - - print('[prerun] Initializing or upgrading db - end') - except subprocess.CalledProcessError as e: - if 'OperationalError' in e.output: - print('[prerun] Database not ready, waiting a bit before exit...') - import time - time.sleep(5) - sys.exit(1) - else: - print((e.output)) - raise e - print('[prerun] Initializing or upgrading db - finish') - - -def init_datastore(): - - conn_str = os.environ.get('CKAN_DATASTORE_WRITE_URL') - if not conn_str: - print('[prerun] Skipping datastore initialization') - return - - datastore_perms_command = ['paster', '--plugin=ckan', 'datastore', - 'set-permissions', '-c', ckan_ini] - - connection = psycopg2.connect(conn_str) - cursor = connection.cursor() - - print('[prerun] Initializing datastore db - start') - try: - datastore_perms = subprocess.Popen( - datastore_perms_command, - stdout=subprocess.PIPE) - - perms_sql = datastore_perms.stdout.read() - # Remove internal pg command as psycopg2 does not like it - perms_sql = re.sub('\\\\connect \"(.*)\"', '', perms_sql.decode('utf-8')) - cursor.execute(perms_sql) - for notice in connection.notices: - print(notice) - - connection.commit() - - print('[prerun] Initializing datastore db - end') - print((datastore_perms.stdout.read())) - except psycopg2.Error as e: - print('[prerun] Could not initialize datastore') - print((str(e))) - - except subprocess.CalledProcessError as e: - if 'OperationalError' in e.output: - print((e.output)) - print('[prerun] Database not ready, waiting a bit before exit...') - time.sleep(5) - sys.exit(1) - else: - print((e.output)) - raise e - finally: - cursor.close() - connection.close() - - -def create_sysadmin(): - - print('[prerun] Start create_sysadmin...') - - name = os.environ.get('CKAN_SYSADMIN_NAME') - password = os.environ.get('CKAN_SYSADMIN_PASSWORD') - email = os.environ.get('CKAN_SYSADMIN_EMAIL') - - if name and password and email: - - # Check if user exists - command = ['paster', '--plugin=ckan', 'user', name, '-c', ckan_ini] - - out = subprocess.check_output(command) - if 'User:None' not in re.sub(r'\s', '', out.decode('utf-8')): - print('[prerun] Sysadmin user exists, skipping creation') - return - - # Create user - command = ['paster', '--plugin=ckan', 'user', 'add', - name, - 'password=' + password, - 'email=' + email, - '-c', ckan_ini] - - subprocess.call(command) - print(('[prerun] Created user {0}'.format(name))) - - # Make it sysadmin - command = ['paster', '--plugin=ckan', 'sysadmin', 'add', - name, - '-c', ckan_ini] - - subprocess.call(command) - print(('[prerun] Made user {0} a sysadmin'.format(name))) - -if __name__ == '__main__': - - maintenance = os.environ.get('MAINTENANCE_MODE', '').lower() == 'true' - - if maintenance: - print('[prerun] Maintenance mode, skipping setup...') - else: - check_db_connection() - check_solr_connection() - init_db() - if os.environ.get('CKAN_DATASTORE_WRITE_URL'): - init_datastore() - create_sysadmin() diff --git a/images/ckan/2.7/setup/app/start_ckan.sh b/images/ckan/2.7/setup/app/start_ckan.sh deleted file mode 100755 index 5486656..0000000 --- a/images/ckan/2.7/setup/app/start_ckan.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/bash -# Run any startup scripts provided by images extending this one -if [[ -d "${APP_DIR}/docker-entrypoint.d" ]] -then - for f in ${APP_DIR}/docker-entrypoint.d/*; do - case "$f" in - *.sh) echo "$0: Running init file $f"; . "$f" ;; - *.py) echo "$0: Running init file $f"; python "$f"; echo ;; - *) echo "$0: Ignoring $f (not an sh or py file)" ;; - esac - echo - done -fi - -# Add session secret from chart -if [[ -z $BEAKER_SESSION_SECRET || -v $BEAKER_SESSION_SECRET ]];then - echo "Not all environment variables are set. Generating sessions..." -else - echo "Setting session secrets from environment variables" - paster --plugin=ckan config-tool $APP_DIR/production.ini "beaker.session.secret=$BEAKER_SESSION_SECRET" -fi - -if grep -E "beaker.session.secret ?= ?$" $APP_DIR/production.ini -then - echo "Setting beaker.session.secret in ini file" - paster --plugin=ckan config-tool $APP_DIR/production.ini "beaker.session.secret=$(python -c 'import secrets; print(secrets.token_urlsafe())')" -fi - -# Set the common uwsgi options -echo "Starting UWSGI with '${UWSGI_PROC_NO:-2}' workers" - -UWSGI_OPTS="--socket /tmp/uwsgi.sock --uid 92 --gid 92 --http :5000 --master --enable-threads --paste config:/srv/app/production.ini --paste-logger /srv/app/production.ini --lazy-apps --gevent 2000 -p ${UWSGI_PROC_NO:-2} -L --gevent-early-monkey-patch" - -# Run the prerun script to init CKAN and create the default admin user -python prerun.py || { echo '[CKAN prerun] FAILED. Exiting...' ; exit 1; } - -# Check if we are in maintenance mode and if yes serve the maintenance pages -if [ "$MAINTENANCE_MODE" = true ]; then PYTHONUNBUFFERED=1 python maintenance/serve.py; fi - -# Run any after prerun/init scripts provided by images extending this one -if [[ -d "${APP_DIR}/docker-afterinit.d" ]] -then - for f in ${APP_DIR}/docker-afterinit.d/*; do - case "$f" in - *.sh) echo "$0: Running after prerun init file $f"; . "$f" ;; - *.py) echo "$0: Running after prerun init file $f"; python "$f"; echo ;; - *) echo "$0: Ignoring $f (not an sh or py file)" ;; - esac - echo - done -fi - -# Check whether http basic auth password protection is enabled and enable basicauth routing on uwsgi respecfully -if [ $? -eq 0 ] -then - if [ "$PASSWORD_PROTECT" = true ] - then - if [ "$HTPASSWD_USER" ] || [ "$HTPASSWD_PASSWORD" ] - then - # Generate htpasswd file for basicauth - htpasswd -d -b -c /srv/app/.htpasswd $HTPASSWD_USER $HTPASSWD_PASSWORD - # Start uwsgi with basicauth - uwsgi --ini /srv/app/uwsgi.conf --pcre-jit $UWSGI_OPTS - else - echo "Missing HTPASSWD_USER or HTPASSWD_PASSWORD environment variables. Exiting..." - exit 1 - fi - else - # Start uwsgi - uwsgi $UWSGI_OPTS - fi -else - echo "[prerun] failed...not starting CKAN." -fi diff --git a/images/ckan/2.7/setup/app/uwsgi.conf b/images/ckan/2.7/setup/app/uwsgi.conf deleted file mode 100644 index 6321d6d..0000000 --- a/images/ckan/2.7/setup/app/uwsgi.conf +++ /dev/null @@ -1,2 +0,0 @@ -[uwsgi] -route = ^(?!/api).*$ basicauth:Restricted,/srv/app/.htpasswd diff --git a/images/ckan/2.7/setup/bin/ckan b/images/ckan/2.7/setup/bin/ckan deleted file mode 100755 index f2e03dd..0000000 --- a/images/ckan/2.7/setup/bin/ckan +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -# CKAN <2.9 uses paster and the ckan plugin for paster which expects the configuration to be passed -# to a subcommand, example: paster --plugin=ckan datastore -c /srv/app/production.ini set-permissions -# CKAN >2.9 ckan CLI command expects the configuration option as the second and third parameter -# Example: ckan -c /srv/app/production.ini datastore set-permissions -# -# Shift three arguments so that we can reorder the argument list -# ckan -c /srv/app/production.ini datastore set-permissions -# becomes -# paster --plugin=ckan datastore -c /srv/app/production.ini set-permissions -config_switch=$1 -config_file=$2 -subcommand=$3 -shift 3 -paster --plugin=ckan "$subcommand" "$config_switch" "$config_file" "$@" diff --git a/images/ckan/2.8/Dockerfile b/images/ckan/2.8/Dockerfile deleted file mode 100644 index 3588a75..0000000 --- a/images/ckan/2.8/Dockerfile +++ /dev/null @@ -1,189 +0,0 @@ -################## -### Build CKAN ### -################## -FROM alpine:3.14.2 as ckanbuild - -# Used by Github Actions to tag the image with -ENV IMAGE_TAG=2.8.12 - -# Set CKAN version to build -ENV GIT_URL=https://github.com/ckan/ckan.git -ENV GIT_BRANCH=ckan-2.8.12 - -# Set src dirs -ENV SRC_DIR=/srv/app/src -ENV PIP_SRC=${SRC_DIR} - -WORKDIR ${SRC_DIR} - -# Packages to build CKAN requirements and plugins -RUN apk add --no-cache \ - git \ - curl \ - python2 \ - postgresql-dev \ - linux-headers \ - gcc \ - make \ - g++ \ - autoconf \ - automake \ - patch \ - libtool \ - musl-dev \ - pcre-dev \ - pcre \ - python2-dev \ - libffi-dev \ - libxml2-dev \ - libxslt-dev - -# Create the src directory -RUN mkdir -p ${SRC_DIR} - -# Install pip -RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py && \ - python ${SRC_DIR}/get-pip.py 'pip==20.3.3' - -# Fetch and build CKAN and requirements -RUN pip install -e git+${GIT_URL}@${GIT_BRANCH}#egg=ckan -# Copy patches and apply patches script -COPY ./patches ${SRC_DIR}/patches -COPY ./scripts/apply_ckan_patches.sh ${SRC_DIR}/apply_ckan_patches.sh -# Apply patches -RUN ${SRC_DIR}/apply_ckan_patches.sh -RUN rm -rf /srv/app/src/ckan/.git -RUN pip wheel --wheel-dir=/wheels -r ckan/requirements.txt -RUN pip wheel --wheel-dir=/wheels uwsgi==2.0.19.1 gevent==21.12.0 greenlet==1.1.3 - - -########################### -### Default-Extensions #### -########################### -FROM alpine:3.14.2 as extbuild - -# Set src dirs -ENV SRC_DIR=/srv/app/src -ENV PIP_SRC=${SRC_DIR} - -# List of default extensions -ENV DEFAULT_EXTENSIONS envvars - -# Locations and tags, please use specific tags or revisions -ENV ENVVARS_GIT_URL=https://github.com/okfn/ckanext-envvars -ENV ENVVARS_GIT_BRANCH=0.0.1 - -RUN apk add --no-cache \ - git \ - curl \ - python2 \ - python2-dev - -# Create the src directory -RUN mkdir -p ${SRC_DIR} - -# Install pip -RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py && \ - python ${SRC_DIR}/get-pip.py 'pip==20.3.3' - -# Fetch and build the default CKAN extensions -RUN pip wheel --wheel-dir=/wheels git+${ENVVARS_GIT_URL}@${ENVVARS_GIT_BRANCH}#egg=ckanext-envvars - -############ -### MAIN ### -############ -FROM alpine:3.14.2 - -LABEL maintainer="Keitaro IncOur data portal is currently in maintenance, please try in a while.
- - diff --git a/images/ckan/2.8/setup/app/maintenance/index.html b/images/ckan/2.8/setup/app/maintenance/index.html deleted file mode 100644 index 50276ec..0000000 --- a/images/ckan/2.8/setup/app/maintenance/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - -Our data portal is currently in maintenance, please try in a while.
- - diff --git a/images/ckan/2.8/setup/app/maintenance/serve.py b/images/ckan/2.8/setup/app/maintenance/serve.py deleted file mode 100644 index 96c0a15..0000000 --- a/images/ckan/2.8/setup/app/maintenance/serve.py +++ /dev/null @@ -1,38 +0,0 @@ -""" -Copyright (c) 2016 Keitaro AB - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -from SimpleHTTPServer import SimpleHTTPRequestHandler -from BaseHTTPServer import HTTPServer -from SocketServer import ThreadingMixIn -import os - -PORT = 5000 - -web_dir = os.path.join(os.path.dirname(__file__)) -os.chdir(web_dir) - -Handler = SimpleHTTPRequestHandler - - -class MaintenanceServer(ThreadingMixIn, HTTPServer): - """Handle requests in a separate thread.""" - - -if __name__ == "__main__": - httpd = MaintenanceServer(("0.0.0.0", PORT), Handler) - print("Starting maintenance mode") - httpd.serve_forever() - diff --git a/images/ckan/2.8/setup/app/prerun.py b/images/ckan/2.8/setup/app/prerun.py deleted file mode 100644 index 4065df5..0000000 --- a/images/ckan/2.8/setup/app/prerun.py +++ /dev/null @@ -1,200 +0,0 @@ -""" -Copyright (c) 2016 Keitaro AB - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -import os -import sys -import subprocess -import psycopg2 -import urllib2 -import re - -import time - -ckan_ini = os.environ.get('CKAN_INI', '/srv/app/production.ini') - -RETRY = 5 - -def check_db_connection(retry=None): - - print('[prerun] Start check_db_connection...') - - if retry is None: - retry = RETRY - elif retry == 0: - print('[prerun] Giving up after 5 tries...') - sys.exit(1) - - conn_str = os.environ.get('CKAN_SQLALCHEMY_URL', '') - try: - connection = psycopg2.connect(conn_str) - - except psycopg2.Error as e: - print((str(e))) - print('[prerun] Unable to connect to the database...try again in a while.') - import time - time.sleep(10) - check_db_connection(retry = retry - 1) - else: - connection.close() - -def check_solr_connection(retry=None): - - print('[prerun] Start check_solr_connection...') - - if retry is None: - retry = RETRY - elif retry == 0: - print('[prerun] Giving up after 5 tries...') - sys.exit(1) - - url = os.environ.get('CKAN_SOLR_URL', '') - search_url = '{url}/select/?q=*&wt=json'.format(url=url) - - try: - connection = urllib2.urlopen(search_url) - except urllib2.URLError as e: - print('[prerun] Unable to connect to solr...try again in a while.') - import time - time.sleep(10) - check_solr_connection(retry = retry - 1) - else: - import re - conn_info = connection.read() - # SolrCloud - conn_info = re.sub(r'"zkConnected":true', '"zkConnected":True', conn_info) - eval(conn_info) - -def init_db(): - - print('[prerun] Start init_db...') - - db_command = ['paster', '--plugin=ckan', 'db', 'init', '-c', ckan_ini] - - print('[prerun] Initializing or upgrading db - start using paster db init') - try: - # run init scripts - subprocess.check_output(db_command, stderr=subprocess.STDOUT) - - print('[prerun] Initializing or upgrading db - end') - except subprocess.CalledProcessError as e: - if 'OperationalError' in e.output: - print('[prerun] Database not ready, waiting a bit before exit...') - import time - time.sleep(5) - sys.exit(1) - else: - print((e.output)) - raise e - print('[prerun] Initializing or upgrading db - finish') - - -def init_datastore(): - - conn_str = os.environ.get('CKAN_DATASTORE_WRITE_URL') - if not conn_str: - print('[prerun] Skipping datastore initialization') - return - - datastore_perms_command = ['paster', '--plugin=ckan', 'datastore', - 'set-permissions', '-c', ckan_ini] - - connection = psycopg2.connect(conn_str) - cursor = connection.cursor() - - print('[prerun] Initializing datastore db - start') - try: - datastore_perms = subprocess.Popen( - datastore_perms_command, - stdout=subprocess.PIPE) - - perms_sql = datastore_perms.stdout.read() - # Remove internal pg command as psycopg2 does not like it - perms_sql = re.sub('\\\\connect \"(.*)\"', '', perms_sql.decode('utf-8')) - cursor.execute(perms_sql) - for notice in connection.notices: - print(notice) - - connection.commit() - - print('[prerun] Initializing datastore db - end') - print((datastore_perms.stdout.read())) - except psycopg2.Error as e: - print('[prerun] Could not initialize datastore') - print((str(e))) - - except subprocess.CalledProcessError as e: - if 'OperationalError' in e.output: - print((e.output)) - print('[prerun] Database not ready, waiting a bit before exit...') - time.sleep(5) - sys.exit(1) - else: - print((e.output)) - raise e - finally: - cursor.close() - connection.close() - - -def create_sysadmin(): - - print('[prerun] Start create_sysadmin...') - - name = os.environ.get('CKAN_SYSADMIN_NAME') - password = os.environ.get('CKAN_SYSADMIN_PASSWORD') - email = os.environ.get('CKAN_SYSADMIN_EMAIL') - - if name and password and email: - - # Check if user exists - command = ['paster', '--plugin=ckan', 'user', name, '-c', ckan_ini] - - out = subprocess.check_output(command) - if 'User:None' not in re.sub(r'\s', '', out.decode('utf-8')): - print('[prerun] Sysadmin user exists, skipping creation') - return - - # Create user - command = ['paster', '--plugin=ckan', 'user', 'add', - name, - 'password=' + password, - 'email=' + email, - '-c', ckan_ini] - - subprocess.call(command) - print(('[prerun] Created user {0}'.format(name))) - - # Make it sysadmin - command = ['paster', '--plugin=ckan', 'sysadmin', 'add', - name, - '-c', ckan_ini] - - subprocess.call(command) - print(('[prerun] Made user {0} a sysadmin'.format(name))) - -if __name__ == '__main__': - - maintenance = os.environ.get('MAINTENANCE_MODE', '').lower() == 'true' - - if maintenance: - print('[prerun] Maintenance mode, skipping setup...') - else: - check_db_connection() - check_solr_connection() - init_db() - if os.environ.get('CKAN_DATASTORE_WRITE_URL'): - init_datastore() - create_sysadmin() diff --git a/images/ckan/2.8/setup/app/start_ckan.sh b/images/ckan/2.8/setup/app/start_ckan.sh deleted file mode 100755 index 5486656..0000000 --- a/images/ckan/2.8/setup/app/start_ckan.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/bash -# Run any startup scripts provided by images extending this one -if [[ -d "${APP_DIR}/docker-entrypoint.d" ]] -then - for f in ${APP_DIR}/docker-entrypoint.d/*; do - case "$f" in - *.sh) echo "$0: Running init file $f"; . "$f" ;; - *.py) echo "$0: Running init file $f"; python "$f"; echo ;; - *) echo "$0: Ignoring $f (not an sh or py file)" ;; - esac - echo - done -fi - -# Add session secret from chart -if [[ -z $BEAKER_SESSION_SECRET || -v $BEAKER_SESSION_SECRET ]];then - echo "Not all environment variables are set. Generating sessions..." -else - echo "Setting session secrets from environment variables" - paster --plugin=ckan config-tool $APP_DIR/production.ini "beaker.session.secret=$BEAKER_SESSION_SECRET" -fi - -if grep -E "beaker.session.secret ?= ?$" $APP_DIR/production.ini -then - echo "Setting beaker.session.secret in ini file" - paster --plugin=ckan config-tool $APP_DIR/production.ini "beaker.session.secret=$(python -c 'import secrets; print(secrets.token_urlsafe())')" -fi - -# Set the common uwsgi options -echo "Starting UWSGI with '${UWSGI_PROC_NO:-2}' workers" - -UWSGI_OPTS="--socket /tmp/uwsgi.sock --uid 92 --gid 92 --http :5000 --master --enable-threads --paste config:/srv/app/production.ini --paste-logger /srv/app/production.ini --lazy-apps --gevent 2000 -p ${UWSGI_PROC_NO:-2} -L --gevent-early-monkey-patch" - -# Run the prerun script to init CKAN and create the default admin user -python prerun.py || { echo '[CKAN prerun] FAILED. Exiting...' ; exit 1; } - -# Check if we are in maintenance mode and if yes serve the maintenance pages -if [ "$MAINTENANCE_MODE" = true ]; then PYTHONUNBUFFERED=1 python maintenance/serve.py; fi - -# Run any after prerun/init scripts provided by images extending this one -if [[ -d "${APP_DIR}/docker-afterinit.d" ]] -then - for f in ${APP_DIR}/docker-afterinit.d/*; do - case "$f" in - *.sh) echo "$0: Running after prerun init file $f"; . "$f" ;; - *.py) echo "$0: Running after prerun init file $f"; python "$f"; echo ;; - *) echo "$0: Ignoring $f (not an sh or py file)" ;; - esac - echo - done -fi - -# Check whether http basic auth password protection is enabled and enable basicauth routing on uwsgi respecfully -if [ $? -eq 0 ] -then - if [ "$PASSWORD_PROTECT" = true ] - then - if [ "$HTPASSWD_USER" ] || [ "$HTPASSWD_PASSWORD" ] - then - # Generate htpasswd file for basicauth - htpasswd -d -b -c /srv/app/.htpasswd $HTPASSWD_USER $HTPASSWD_PASSWORD - # Start uwsgi with basicauth - uwsgi --ini /srv/app/uwsgi.conf --pcre-jit $UWSGI_OPTS - else - echo "Missing HTPASSWD_USER or HTPASSWD_PASSWORD environment variables. Exiting..." - exit 1 - fi - else - # Start uwsgi - uwsgi $UWSGI_OPTS - fi -else - echo "[prerun] failed...not starting CKAN." -fi diff --git a/images/ckan/2.8/setup/app/uwsgi.conf b/images/ckan/2.8/setup/app/uwsgi.conf deleted file mode 100644 index 6321d6d..0000000 --- a/images/ckan/2.8/setup/app/uwsgi.conf +++ /dev/null @@ -1,2 +0,0 @@ -[uwsgi] -route = ^(?!/api).*$ basicauth:Restricted,/srv/app/.htpasswd diff --git a/images/ckan/2.8/setup/bin/ckan b/images/ckan/2.8/setup/bin/ckan deleted file mode 100755 index f2e03dd..0000000 --- a/images/ckan/2.8/setup/bin/ckan +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -# CKAN <2.9 uses paster and the ckan plugin for paster which expects the configuration to be passed -# to a subcommand, example: paster --plugin=ckan datastore -c /srv/app/production.ini set-permissions -# CKAN >2.9 ckan CLI command expects the configuration option as the second and third parameter -# Example: ckan -c /srv/app/production.ini datastore set-permissions -# -# Shift three arguments so that we can reorder the argument list -# ckan -c /srv/app/production.ini datastore set-permissions -# becomes -# paster --plugin=ckan datastore -c /srv/app/production.ini set-permissions -config_switch=$1 -config_file=$2 -subcommand=$3 -shift 3 -paster --plugin=ckan "$subcommand" "$config_switch" "$config_file" "$@" diff --git a/images/ckan/2.9/Dockerfile b/images/ckan/2.9/Dockerfile deleted file mode 100644 index 7c872d2..0000000 --- a/images/ckan/2.9/Dockerfile +++ /dev/null @@ -1,203 +0,0 @@ -################## -### Build CKAN ### -################## -FROM alpine:3.13.7 as ckanbuild - -# Used by Github Actions to tag the image with -ENV IMAGE_TAG=2.9.11 - -# Set CKAN version to build -ENV GIT_URL=https://github.com/ckan/ckan.git -ENV GIT_BRANCH=ckan-2.9.11 - -# Set src dirs -ENV SRC_DIR=/srv/app/src -ENV PIP_SRC=${SRC_DIR} - -WORKDIR ${SRC_DIR} - -# Packages to build CKAN requirements and plugins -RUN apk add --no-cache \ - python3 \ - python3-dev \ - git \ - curl \ - postgresql-dev \ - linux-headers \ - gcc \ - make \ - g++ \ - autoconf \ - automake \ - libtool \ - patch \ - musl-dev \ - pcre-dev \ - pcre \ - libffi-dev \ - libxml2-dev \ - libxslt-dev - -# Link python to python3 -RUN ln -s /usr/bin/python3 /usr/bin/python - -# Create the src directory -RUN mkdir -p ${SRC_DIR} - -# Install pip -RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/get-pip.py && \ - python ${SRC_DIR}/get-pip.py - -# Downgrade setuptools so that CKAN requirements can be built -RUN pip install setuptools==44.1.0 - -# Fetch and build CKAN and requirements -RUN pip install -e git+${GIT_URL}@${GIT_BRANCH}#egg=ckan -# Copy patches and apply patches script -COPY ./patches ${SRC_DIR}/patches -COPY ./scripts/apply_ckan_patches.sh ${SRC_DIR}/apply_ckan_patches.sh -# Apply patches -RUN cd ${SRC_DIR} && ls -lah ${SRC_DIR} && ash ${SRC_DIR}/apply_ckan_patches.sh -RUN rm -rf /srv/app/src/ckan/.git - -# Create a constraint file that limits the Cython version to a compatible one, see https://github.com/yaml/pyyaml/issues/736 -RUN echo 'Cython < 3.0' > /tmp/constraint.txt -RUN PIP_CONSTRAINT=/tmp/constraint.txt pip wheel --wheel-dir=/wheels PyYAML==5.4.1 - -# RUN pip-compile ckan/requirements.in -RUN pip wheel --wheel-dir=/wheels -r ckan/requirements.txt -RUN pip wheel --wheel-dir=/wheels uWSGI==2.0.20 gevent==21.12.0 greenlet==1.1.3 - -########################### -### Default-Extensions #### -########################### -FROM alpine:3.13.7 as extbuild - -# Set src dirs -ENV SRC_DIR=/srv/app/src -ENV PIP_SRC=${SRC_DIR} - -# List of default extensions -ENV DEFAULT_EXTENSIONS envvars - -# Locations and tags, please use specific tags or revisions -ENV ENVVARS_GIT_URL=https://github.com/okfn/ckanext-envvars -ENV ENVVARS_GIT_BRANCH=0.0.1 - -RUN apk add --no-cache \ - python3 \ - python3-dev \ - git \ - curl - -# Link python to python3 -RUN ln -s /usr/bin/python3 /usr/bin/python - -# Create the src directory -RUN mkdir -p ${SRC_DIR} - -# Install pip -RUN curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/get-pip.py && \ - python ${SRC_DIR}/get-pip.py - -# Fetch and build the default CKAN extensions -RUN pip wheel --wheel-dir=/wheels git+${ENVVARS_GIT_URL}@${ENVVARS_GIT_BRANCH}#egg=ckanext-envvars - -############ -### MAIN ### -############ -FROM alpine:3.13.7 - -LABEL maintainer="Keitaro IncOur data portal is currently in maintenance, please try in a while.
- - diff --git a/images/ckan/2.9/setup/app/maintenance/index.html b/images/ckan/2.9/setup/app/maintenance/index.html deleted file mode 100644 index 50276ec..0000000 --- a/images/ckan/2.9/setup/app/maintenance/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - -Our data portal is currently in maintenance, please try in a while.
- - diff --git a/images/ckan/2.9/setup/app/maintenance/serve.py b/images/ckan/2.9/setup/app/maintenance/serve.py deleted file mode 100644 index 77f3bd4..0000000 --- a/images/ckan/2.9/setup/app/maintenance/serve.py +++ /dev/null @@ -1,35 +0,0 @@ -""" -Copyright (c) 2016 Keitaro AB - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -from http.server import ThreadingHTTPServer, SimpleHTTPRequestHandler -import os - -PORT = 5000 - -web_dir = os.path.join(os.path.dirname(__file__)) -os.chdir(web_dir) - - -def run(server_class=ThreadingHTTPServer, handler_class=SimpleHTTPRequestHandler): - server_address = ("0.0.0.0", PORT) - httpd = server_class(server_address, handler_class) - print("Starting maintenance mode") - httpd.serve_forever() - - -if __name__ == "__main__": - run() - diff --git a/images/ckan/2.9/setup/app/prerun.py b/images/ckan/2.9/setup/app/prerun.py deleted file mode 100644 index cd95b16..0000000 --- a/images/ckan/2.9/setup/app/prerun.py +++ /dev/null @@ -1,228 +0,0 @@ -""" -Copyright (c) 2016 Keitaro AB -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - https://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -from multiprocessing import connection -import os -import sys -import subprocess -import psycopg2 -from sqlalchemy.engine.url import make_url -import urllib.request, urllib.error, urllib.parse, base64 -import re -import json - -import time - -ckan_ini = os.environ.get('CKAN_INI', '/srv/app/production.ini') - -RETRY = 5 - -def check_db_connection(retry=None): - - print('[prerun] Start check_db_connection...') - - if retry is None: - retry = RETRY - elif retry == 0: - print('[prerun] Giving up after 5 tries...') - sys.exit(1) - - conn_str = os.environ.get('CKAN_SQLALCHEMY_URL', '') - try: - db_user = make_url(conn_str).username - db_passwd = make_url(conn_str).password - db_host = make_url(conn_str).host - db_name = make_url(conn_str).database - connection = psycopg2.connect(user=db_user, - host=db_host, - password=db_passwd, - database=db_name) - - except psycopg2.Error as e: - print((str(e))) - print('[prerun] Unable to connect to the database...try again in a while.') - import time - time.sleep(10) - check_db_connection(retry = retry - 1) - else: - connection.close() - -def check_solr_connection(retry=None): - - print('[prerun] Start check_solr_connection...') - - if retry is None: - retry = RETRY - elif retry == 0: - print('[prerun] Giving up after 5 tries...') - sys.exit(1) - - url = os.environ.get('CKAN_SOLR_URL', '') - username = os.environ.get('CKAN_SOLR_USER', '') - password = os.environ.get('CKAN_SOLR_PASSWORD', '') - search_url = '{url}/schema/name?wt=json'.format(url=url) - - - - try: - if not username: - connection = urllib.request.urlopen(search_url) - else: - request = urllib.request.Request(search_url) - base64string = base64.b64encode(bytes('%s:%s' % (username, password),'ascii')) - request.add_header("Authorization", "Basic %s" % base64string.decode('utf-8')) - connection = urllib.request.urlopen(request) - except urllib.error.URLError as e: - print('[prerun] Unable to connect to solr...try again in a while.') - import time - time.sleep(10) - check_solr_connection(retry = retry - 1) - else: - import re - conn_info = connection.read() - schema_name = json.loads(conn_info) - if 'ckan' in schema_name['name']: - print('[prerun] Succesfully connected to solr and CKAN schema loaded') - else: - print('[prerun] Succesfully connected to solr, but CKAN schema not found') - sys.exit(1) - -def init_db(): - - print('[prerun] Start init_db...') - - db_command = ['ckan', '-c', ckan_ini, 'db', 'init'] - - print('[prerun] Initializing or upgrading db - start using ckan db init') - try: - # run init scripts - subprocess.check_output(db_command, stderr=subprocess.STDOUT) - - print('[prerun] Initializing or upgrading db - end') - except subprocess.CalledProcessError as e: - if 'OperationalError' in str(e.output): - print(e.output.decode('utf-8')) - print('[prerun] Database not ready, waiting a bit before exit...') - import time - time.sleep(5) - sys.exit(1) - else: - print(e.output.decode('utf-8')) - raise e - print('[prerun] Initializing or upgrading db - finish') - - -def init_datastore(): - - conn_str = os.environ.get('CKAN_DATASTORE_WRITE_URL') - if not conn_str: - print('[prerun] Skipping datastore initialization') - return - - datastore_perms_command = ['ckan', '-c', ckan_ini, 'datastore', - 'set-permissions'] - - db_user = make_url(conn_str).username - db_passwd = make_url(conn_str).password - db_host = make_url(conn_str).host - db_name = make_url(conn_str).database - connection = psycopg2.connect(user=db_user, - host=db_host, - password=db_passwd, - database=db_name) - cursor = connection.cursor() - - print('[prerun] Initializing datastore db - start') - try: - datastore_perms = subprocess.Popen( - datastore_perms_command, - stdout=subprocess.PIPE) - - perms_sql = datastore_perms.stdout.read() - perms_sql = perms_sql.decode('utf-8') - perms_sql = perms_sql.replace("@"+db_host, "") - # Remove internal pg command as psycopg2 does not like it - perms_sql = re.sub('\\\\connect \"(.*)\"', '', perms_sql) - cursor.execute(perms_sql) - for notice in connection.notices: - print(notice) - - connection.commit() - - print('[prerun] Initializing datastore db - end') - print((datastore_perms.stdout.read())) - except psycopg2.Error as e: - print('[prerun] Could not initialize datastore') - print(e.decode('utf-8')) - - except subprocess.CalledProcessError as e: - if 'OperationalError' in str(e.output): - print(e.output.decode('utf-8')) - print('[prerun] Database not ready, waiting a bit before exit...') - time.sleep(5) - sys.exit(1) - else: - print(e.output.decode('utf-8')) - raise e - finally: - cursor.close() - connection.close() - - -def create_sysadmin(): - - print('[prerun] Start create_sysadmin...') - - name = os.environ.get('CKAN_SYSADMIN_NAME') - password = os.environ.get('CKAN_SYSADMIN_PASSWORD') - email = os.environ.get('CKAN_SYSADMIN_EMAIL') - - if name and password and email: - - # Check if user exists - command = ['ckan', '-c', ckan_ini, 'user', 'show', name] - - out = subprocess.check_output(command) - if 'User:None' not in re.sub(r'\s', '', out.decode('utf-8')): - print('[prerun] Sysadmin user exists, skipping creation') - return - - # Create user - command = ['ckan', '-c', ckan_ini, 'user', 'add', - name, - 'password=' + password, - 'email=' + email] - - subprocess.call(command) - print(('[prerun] Created user {0}'.format(name))) - - # Make it sysadmin - command = ['ckan', '-c', ckan_ini, 'sysadmin', 'add', - name] - - subprocess.call(command) - print(('[prerun] Made user {0} a sysadmin'.format(name))) - -if __name__ == '__main__': - - maintenance = os.environ.get('MAINTENANCE_MODE', '').lower() == 'true' - - if maintenance: - print('[prerun] Maintenance mode, skipping setup...') - else: - check_db_connection() - check_solr_connection() - init_db() - if os.environ.get('CKAN_DATASTORE_WRITE_URL'): - init_datastore() - create_sysadmin() \ No newline at end of file diff --git a/images/ckan/2.9/setup/app/start_ckan.sh b/images/ckan/2.9/setup/app/start_ckan.sh deleted file mode 100755 index 99f09db..0000000 --- a/images/ckan/2.9/setup/app/start_ckan.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash -# Run any startup scripts provided by images extending this one -if [[ -d "${APP_DIR}/docker-entrypoint.d" ]] -then - for f in ${APP_DIR}/docker-entrypoint.d/*; do - case "$f" in - *.sh) echo "$0: Running init file $f"; . "$f" ;; - *.py) echo "$0: Running init file $f"; python "$f"; echo ;; - *) echo "$0: Ignoring $f (not an sh or py file)" ;; - esac - echo - done -fi - -# Add session secret from chart -if [[ -z $BEAKER_SESSION_SECRET || -v $BEAKER_SESSION_SECRET || -z $JWT_ENCODE_SECRET || -v $JWT_ENCODE_SECRET || -z $JWT_DECODE_SECRET || -v $JWT_DECODE_SECRET ]];then - echo "Not all environment variables are set. Generating sessions..." -else - echo "Setting session secrets from environment variables" - ckan config-tool $APP_DIR/production.ini "beaker.session.secret=$BEAKER_SESSION_SECRET" - ckan config-tool $APP_DIR/production.ini "api_token.jwt.encode.secret=$JWT_ENCODE_SECRET" - ckan config-tool $APP_DIR/production.ini "api_token.jwt.decode.secret=$JWT_DECODE_SECRET" -fi - -if grep -E "beaker.session.secret ?= ?$" $APP_DIR/production.ini -then - echo "Setting secrets in ini file" - ckan config-tool $APP_DIR/production.ini "beaker.session.secret=$(python3 -c 'import secrets; print(secrets.token_urlsafe())')" - ckan config-tool $APP_DIR/production.ini "WTF_CSRF_SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_urlsafe())')" - JWT_SECRET=$(python3 -c 'import secrets; print("string:" + secrets.token_urlsafe())') - ckan config-tool $APP_DIR/production.ini "api_token.jwt.encode.secret=$JWT_SECRET" - ckan config-tool $APP_DIR/production.ini "api_token.jwt.decode.secret=$JWT_SECRET" -fi - -# Run the prerun script to init CKAN and create the default admin user -python prerun.py || { echo '[CKAN prerun] FAILED. Exiting...' ; exit 1; } - -# Check if we are in maintenance mode and if yes serve the maintenance pages -if [ "$MAINTENANCE_MODE" = true ]; then PYTHONUNBUFFERED=1 python maintenance/serve.py; fi - -# Run any after prerun/init scripts provided by images extending this one -if [[ -d "${APP_DIR}/docker-afterinit.d" ]] -then - for f in ${APP_DIR}/docker-afterinit.d/*; do - case "$f" in - *.sh) echo "$0: Running after prerun init file $f"; . "$f" ;; - *.py) echo "$0: Running after prerun init file $f"; python "$f"; echo ;; - *) echo "$0: Ignoring $f (not an sh or py file)" ;; - esac - echo - done -fi - -# Check whether http basic auth password protection is enabled and enable basicauth routing on uwsgi respecfully -if [ $? -eq 0 ] -then - if [ "$PASSWORD_PROTECT" = true ] - then - if [ "$HTPASSWD_USER" ] || [ "$HTPASSWD_PASSWORD" ] - then - # Generate htpasswd file for basicauth - htpasswd -d -b -c /srv/app/.htpasswd $HTPASSWD_USER $HTPASSWD_PASSWORD - # Start uwsgi with basicauth - uwsgi --ini /srv/app/basic-auth-uwsgi.conf -p ${UWSGI_PROC_NO:-2} --pcre-jit - else - echo "Missing HTPASSWD_USER or HTPASSWD_PASSWORD environment variables. Exiting..." - exit 1 - fi - else - # Start uwsgi - echo "Starting UWSGI with '${UWSGI_PROC_NO:-2}' workers" - uwsgi --ini /srv/app/uwsgi.conf -p ${UWSGI_PROC_NO:-2} - fi -else - echo "[prerun] failed...not starting CKAN." -fi diff --git a/images/ckan/2.9/setup/app/uwsgi.conf b/images/ckan/2.9/setup/app/uwsgi.conf deleted file mode 100644 index c0974de..0000000 --- a/images/ckan/2.9/setup/app/uwsgi.conf +++ /dev/null @@ -1,37 +0,0 @@ -[uwsgi] -socket = /tmp/uwsgi.sock -uid = ckan -gid = ckan -http = :5000 - -master = true -enable-threads = true -lazy-apps = true -gevent-early-monkey-patch = true -vacuum = true -single-interpreter= true -die-on-term = true -need-app = true -auto-procname = true - -wsgi-file = /srv/app/wsgi.py -module = wsgi:application -gevent = 2000 -callable = application -paste = config:/srv/app/production.ini -paste-logger = /srv/app/production.ini - -post-buffering = 1 -buffer-size= 12288 -max-requests = 3000 -max-worker-lifetime = 3600 -reload-on-rss = 4096 -worker-reload-mercy = 60 -socket-timeout = 300 -queue = 1000 -queue-blocksize = 204800 -static-gzip-all = true -listen = 1000 -http-timeout = 1000 -http-headers-timeout = 1000 -http-connect-timeout = 1000 \ No newline at end of file diff --git a/images/ckan/2.9/setup/app/wsgi.py b/images/ckan/2.9/setup/app/wsgi.py deleted file mode 100644 index 63f3a7c..0000000 --- a/images/ckan/2.9/setup/app/wsgi.py +++ /dev/null @@ -1,28 +0,0 @@ -""" -Copyright (c) 2016 Keitaro AB - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -# -*- coding: utf-8 -*- - -import os -from ckan.config.middleware import make_app -from ckan.cli import CKANConfigLoader -from logging.config import fileConfig as loggingFileConfig -config_filepath = os.path.join( - os.path.dirname(os.path.abspath(__file__)), u'production.ini') -abspath = os.path.join(os.path.dirname(os.path.abspath(__file__))) -loggingFileConfig(config_filepath) -config = CKANConfigLoader(config_filepath).get_config() -application = make_app(config)