Skip to content

Commit

Permalink
Merge pull request #319 from atheo89/vscode-ubi9
Browse files Browse the repository at this point in the history
Rebase VSCode to UBI9 instead on C9S
  • Loading branch information
openshift-merge-bot[bot] authored Nov 14, 2023
2 parents ffdce99 + 9851293 commit 50e11ac
Show file tree
Hide file tree
Showing 16 changed files with 464 additions and 4 deletions.
9 changes: 5 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ runtime-pytorch-ubi9-python-3.9: base-ubi9-python-3.9
runtime-cuda-tensorflow-ubi9-python-3.9: cuda-ubi9-python-3.9
$(call image,$@,runtimes/tensorflow/ubi9-python-3.9,$<)

.PHONY: codeserver-ubi9-python-3.9
codeserver-ubi9-python-3.9: base-ubi9-python-3.9
$(call image,$@,codeserver/ubi9-python-3.9,$<)


####################################### Buildchain for Python 3.9 using C9S #######################################

# Build and push base-c9s-python-3.9 image to the registry
Expand All @@ -194,10 +199,6 @@ base-c9s-python-3.9:
cuda-c9s-python-3.9: base-c9s-python-3.9
$(call image,$@,cuda/c9s-python-3.9,$<)

.PHONY: codeserver-c9s-python-3.9
codeserver-c9s-python-3.9: base-c9s-python-3.9
$(call image,$@,codeserver/c9s-python-3.9,$<)

.PHONY: rstudio-c9s-python-3.9
rstudio-c9s-python-3.9: base-c9s-python-3.9
$(call image,$@,rstudio/c9s-python-3.9,$<)
Expand Down
90 changes: 90 additions & 0 deletions codeserver/ubi9-python-3.9/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
ARG BASE_IMAGE
FROM ${BASE_IMAGE}

ARG CODESERVER_VERSION=v4.16.1

LABEL name="odh-notebook-code-server-ubi9-python-3.9" \
summary="Code Server (VS Code) image with python 3.9 based on UBI 9" \
description="Code Server (VS Code) image with python 3.9 based on UBI9" \
io.k8s.display-name="Code Server (VS Code) image with python 3.9 based on UBI9" \
io.k8s.description="Code Server (VS Code) image with python 3.9 based on UBI9" \
authoritative-source-url="https://github.com/opendatahub-io/notebooks" \
io.openshift.build.commit.ref="main" \
io.openshift.build.source-location="https://github.com/opendatahub-io/notebooks/tree/main/codeserver/ubi9-python-3.9" \
io.openshift.build.image="quay.io/opendatahub/workbench-images:codeserver-ubi9-python-3.9"

USER 0

WORKDIR /opt/app-root/bin

# Install Code Server
RUN yum install -y "https://github.com/coder/code-server/releases/download/${CODESERVER_VERSION}/code-server-${CODESERVER_VERSION/v/}-amd64.rpm" && \
yum -y clean all --enablerepo='*'

# Install NGINX to proxy VSCode and pass probes check
ENV NGINX_VERSION=1.22 \
NGINX_SHORT_VER=122 \
NGINX_CONFIGURATION_PATH=${APP_ROOT}/etc/nginx.d \
NGINX_CONF_PATH=/etc/nginx/nginx.conf \
NGINX_DEFAULT_CONF_PATH=${APP_ROOT}/etc/nginx.default.d \
NGINX_CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/nginx \
NGINX_APP_ROOT=${APP_ROOT} \
NGINX_LOG_PATH=/var/log/nginx \
NGINX_PERL_MODULE_PATH=${APP_ROOT}/etc/perl

# Modules does not exist
RUN yum install -y https://download.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm && \
INSTALL_PKGS="bind-utils nginx nginx-mod-stream nginx-mod-http-perl fcgiwrap initscripts chkconfig" && \
yum install -y --setopt=tsflags=nodocs $INSTALL_PKGS && \
rpm -V $INSTALL_PKGS && \
# spawn-fcgi is not in epel9 \
rpm -i --nodocs https://www.rpmfind.net/linux/fedora/linux/releases/37/Everything/x86_64/os/Packages/s/spawn-fcgi-1.6.3-23.fc37.x86_64.rpm && \
yum -y clean all --enablerepo='*'

# Copy extra files to the image.
COPY nginx/root/ /

# Changing ownership and user rights to support following use-cases:
# 1) running container on OpenShift, whose default security model
# is to run the container under random UID, but GID=0
# 2) for working root-less container with UID=1001, which does not have
# to have GID=0
# 3) for default use-case, that is running container directly on operating system,
# with default UID and GID (1001:0)
# Supported combinations of UID:GID are thus following:
# UID=1001 && GID=0
# UID=<any>&& GID=0
# UID=1001 && GID=<any>
RUN sed -i -f ${NGINX_APP_ROOT}/nginxconf.sed ${NGINX_CONF_PATH} && \
mkdir -p ${NGINX_APP_ROOT}/etc/nginx.d/ && \
mkdir -p ${NGINX_APP_ROOT}/etc/nginx.default.d/ && \
mkdir -p ${NGINX_APP_ROOT}/api/ && \
mkdir -p ${NGINX_CONTAINER_SCRIPTS_PATH}/nginx-start && \
mkdir -p ${NGINX_LOG_PATH} && \
mkdir -p ${NGINX_PERL_MODULE_PATH} && \
chown -R 1001:0 ${NGINX_CONF_PATH} && \
chown -R 1001:0 ${NGINX_APP_ROOT}/etc && \
chown -R 1001:0 ${NGINX_CONTAINER_SCRIPTS_PATH}/nginx-start && \
chown -R 1001:0 /var/lib/nginx /var/log/nginx /run && \
chmod ug+rw ${NGINX_CONF_PATH} && \
chmod -R ug+rwX ${NGINX_APP_ROOT}/etc && \
chmod -R ug+rwX ${NGINX_CONTAINER_SCRIPTS_PATH}/nginx-start && \
chmod -R ug+rwX /var/lib/nginx /var/log/nginx /run && \
rpm-file-permissions

## Configure nginx
COPY nginx/serverconf/ /opt/app-root/etc/nginx.default.d/
COPY nginx/httpconf/ /opt/app-root/etc/nginx.d/
COPY nginx/api/ /opt/app-root/api/

# Launcher
COPY utils utils/
COPY run-code-server.sh run-nginx.sh ./

ENV SHELL /bin/bash

WORKDIR /opt/app-root/src

USER 1001

CMD /opt/app-root/bin/run-code-server.sh
10 changes: 10 additions & 0 deletions codeserver/ubi9-python-3.9/kustomize/base/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: codeserver-
resources:
- pod.yaml
images:
- name: codeserver-workbench
newName: quay.io/opendatahub/workbench-images
newTag: codeserver-ubi9-python-3.9
22 changes: 22 additions & 0 deletions codeserver/ubi9-python-3.9/kustomize/base/pod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
apiVersion: v1
kind: Pod
metadata:
name: pod
labels:
app: codeserver-image
spec:
containers:
- name: codeserver
image: codeserver-workbench
command: ["/bin/sh", "-c", "while true ; do date; sleep 5; done;"]
imagePullPolicy: Always
ports:
- containerPort: 8585
resources:
limits:
cpu: 500m
memory: 500Mi
requests:
cpu: 500m
memory: 500Mi
14 changes: 14 additions & 0 deletions codeserver/ubi9-python-3.9/nginx/api/kernels/access.cgi
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash
echo "Status: 200"
echo "Content-type: application/json"
echo
# Query the heartbeat endpoint
HEALTHZ=$(curl -s http://127.0.0.1:8888/vscode/healthz)
# Extract last_activity | remove milliseconds
LAST_ACTIVITY_EPOCH=$(echo $HEALTHZ | grep -Po 'lastHeartbeat":\K.*?(?=})' | awk '{ print substr( $0, 1, length($0)-3 ) }')
# Convert to ISO8601 date format
LAST_ACTIVITY=$(date -d @$LAST_ACTIVITY_EPOCH -Iseconds)
# Extract status and replace with terms expected by culler
STATUS=$(sed 's/alive/busy/;s/expired/idle/' <<< $(echo $HEALTHZ | grep -Po 'status":"\K.*?(?=")'))
# Export in format expected by the culling engine
echo '[{"id":"code-server","name":"code-server","last_activity":"'$LAST_ACTIVITY'","execution_state":"'$STATUS'","connections":1}]'
39 changes: 39 additions & 0 deletions codeserver/ubi9-python-3.9/nginx/httpconf/http.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Make WebSockets working
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

###
# Custom logging for direct last_activity based culling, brace yourself!
###

# Exclude heartbeat from logging for culling purposes
map $request $loggable {
~\/vscode\/healthz 0;
default 1;
}

# iso8601 with millisecond precision transformer (mimicking Jupyter output)
map $time_iso8601 $time_iso8601_p1 {
~([^+]+) $1;
}
map $time_iso8601 $time_iso8601_p2 {
~\+([0-9:]+)$ $1;
}
map $msec $millisec {
~\.([0-9]+)$ $1;
}

log_format json escape=json '[{'
'"id":"code-server",'
'"name":"code-server",'
'"last_activity":"$time_iso8601_p1.$millisec+$time_iso8601_p2",'
'"execution_state":"busy",'
'"connections": 1'
'}]';

map $http_x_forwarded_proto $custom_scheme {
default $scheme;
https https;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Set current user in nss_wrapper
PASSWD_DIR="/opt/app-root/etc"

export USER_ID=$(id -u)
export GROUP_ID=$(id -g)
envsubst < ${PASSWD_DIR}/passwd.template > ${PASSWD_DIR}/passwd
export LD_PRELOAD=libnss_wrapper.so
export NSS_WRAPPER_PASSWD=${PASSWD_DIR}/passwd
export NSS_WRAPPER_GROUP=/etc/group
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
default:x:${USER_ID}:${GROUP_ID}:Default Application User:${HOME}:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# This will make scl collection binaries work out of box.
unset BASH_ENV PROMPT_COMMAND ENV
source scl_source enable rh-nginx$NGINX_SHORT_VER
21 changes: 21 additions & 0 deletions codeserver/ubi9-python-3.9/nginx/root/opt/app-root/nginxconf.sed
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Change port
/listen/s%80%8888 default_server%

# Remove listening on IPv6
/\[::\]/d

# One worker only
/worker_processes/s%auto%1%

s/^user *nginx;//
s%/etc/nginx/conf.d/%/opt/app-root/etc/nginx.d/%
s%/etc/nginx/default.d/%/opt/app-root/etc/nginx.default.d/%
s%/usr/share/nginx/html%/opt/app-root/src%

# See: https://github.com/sclorg/nginx-container/pull/69
/error_page/d
/40x.html/,+1d
/50x.html/,+1d

# Addition for RStudio
/server_name/s%server_name _%server_name ${BASE_URL}%
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/sh

# get_matched_files finds file for image extending
function get_matched_files() {
local custom_dir default_dir
custom_dir="$1"
default_dir="$2"
files_matched="$3"
find "$default_dir" -maxdepth 1 -type f -name "$files_matched" -printf "%f\n"
[ -d "$custom_dir" ] && find "$custom_dir" -maxdepth 1 -type f -name "$files_matched" -printf "%f\n"
}

# process_extending_files process extending files in $1 and $2 directories
# - source all *.sh files
# (if there are files with same name source only file from $1)
function process_extending_files() {
local custom_dir default_dir
custom_dir=$1
default_dir=$2
while read filename ; do
if [ $filename ]; then
echo "=> sourcing $filename ..."
# Custom file is prefered
if [ -f $custom_dir/$filename ]; then
source $custom_dir/$filename
elif [ -f $default_dir/$filename ]; then
source $default_dir/$filename
fi
fi
done <<<"$(get_matched_files "$custom_dir" "$default_dir" '*.sh' | sort -u)"
}
64 changes: 64 additions & 0 deletions codeserver/ubi9-python-3.9/nginx/serverconf/proxy.conf.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
###############
# api calls from probes get to VSCode /healthz endpoint
###############
location = /api {
return 302 /vscode/healthz/;
access_log off;
}

location /api/ {
return 302 /vscode/healthz/;
access_log off;
}
###############

###############
# api calls from culler get to CGI processing
###############
location = /api/kernels {
return 302 $custom_scheme://$http_host/api/kernels/;
access_log off;
}

location /api/kernels/ {
index access.cgi;
fastcgi_index access.cgi;
gzip off;
access_log off;
root /opt/app-root;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /opt/app-root$fastcgi_script_name;
}
###############

###############
# root and prefix get to VSCode endpoint
###############
location = / {
return 302 $custom_scheme://$http_host/vscode/;
}

location = /vscode {
return 302 $custom_scheme://$http_host/vscode/;
}

location /vscode/ {
# Standard Code-Server/NGINX configuration
proxy_pass http://127.0.0.1:8787/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 20d;

# Needed to make it work properly
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $custom_scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;

access_log /var/log/nginx/vscode.access.log json if=$loggable;
}
###############
Loading

0 comments on commit 50e11ac

Please sign in to comment.