Skip to content

Commit

Permalink
added saspy and sas_kernel to jupyterlab image (#649)
Browse files Browse the repository at this point in the history
* added saspy and sas_kernel to jupyterlab image

* partially added sas to jupyter image for saspy

* updated copied sas path

* updated sas in jupyter

* fix sas home rm path + update trivy output

* removing some dirs from sas

* fixed path of removed sas dirs

* removed rm commands from sas + added skip-dirs to trivy scan

* removed if condition on trivy scan step

---------

Co-authored-by: Mathis Marcotte <[email protected]>
  • Loading branch information
mathis-marcotte and Mathis Marcotte authored Aug 19, 2024
1 parent b52966f commit c4d8fb0
Show file tree
Hide file tree
Showing 45 changed files with 1,654 additions and 29 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/build_push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,10 @@ jobs:

# Scan image for vulnerabilities
- name: Aqua Security Trivy image scan
# see https://github.com/StatCan/aaw-private/issues/11 -- should be re-enabled
if: steps.notebook-name.outputs.NOTEBOOK_NAME != 'sas'
run: |
printf ${{ secrets.CVE_ALLOWLIST }} > .trivyignore
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin ${{ env.TRIVY_VERSION }}
trivy image ${{ steps.build-image.outputs.full_image_name }} --exit-code 1 --timeout=20m --security-checks vuln --severity CRITICAL
trivy image ${{ steps.build-image.outputs.full_image_name }} --exit-code 1 --timeout=20m --security-checks vuln --severity CRITICAL --skip-dirs /usr/local/SASHome
# Push image to ACR
# Pushes if this is a push to master or an update to a PR that has auto-deploy label
Expand Down
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,9 @@ sas:
$(SRC)/5_DB-Drivers.Dockerfile \
$(SRC)/6_jupyterlab.Dockerfile \
$(SRC)/6_rstudio-server.Dockerfile \
$(SRC)/6_rstudio.Dockerfile\
$(SRC)/6_rstudio.Dockerfile \
$(SRC)/6_$(@).Dockerfile \
$(SRC)/6_sas-studio.Dockerfile \
$(SRC)/7_remove_vulnerabilities.Dockerfile \
$(SRC)/∞_CMD.Dockerfile \
> $(OUT)/$@/Dockerfile
Expand All @@ -153,6 +154,7 @@ jupyterlab: pytorch tensorflow cpu
$(SRC)/6_rstudio-server.Dockerfile \
$(SRC)/6_rstudio.Dockerfile \
$(SRC)/6_$(@).Dockerfile \
$(SRC)/6_sas.Dockerfile \
$(SRC)/7_remove_vulnerabilities.Dockerfile \
$(SRC)/8_platform.Dockerfile \
$(SRC)/∞_CMD.Dockerfile \
Expand Down
1 change: 1 addition & 0 deletions docker-bits/0_cpu.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

ARG BASE_VERSION=2024-06-17

FROM k8scc01covidacr.azurecr.io/sas4c:0.0.3 as SASHome
FROM quay.io/jupyter/datascience-notebook:$BASE_VERSION

USER root
Expand Down
9 changes: 9 additions & 0 deletions docker-bits/6_sas-studio.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Jupyter SASStudio Proxy
COPY jupyter-sasstudio-proxy/ /opt/jupyter-sasstudio-proxy/
RUN pip install /opt/jupyter-sasstudio-proxy/

# Adds default workspace shortcut to sasstudio
COPY SWE.folderShortcuts.key /etc/sasstudio/preferences/SWE.folderShortcuts.key

# Enable X command on SAS Studio
COPY spawner_usermods.sh /usr/local/SASHome/studioconfig/spawner/
15 changes: 1 addition & 14 deletions docker-bits/6_sas.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
# Install Quarto
ARG QUARTO_VERSION=1.4.176
ARG QUARTO_SHA=c06edd8930903a1018a27eb9f70fb9037b28a3cd8a7eb6299e8136876b4e11b3
ARG QUARTO_URL=https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz

ENV SASSTUDIO_TEMP_HOME=/etc/sasstudio
ARG QUARTO_URL=https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz

RUN wget -q ${QUARTO_URL} -O /tmp/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz && \
echo "${QUARTO_SHA} /tmp/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz" | sha256sum -c - && \
Expand All @@ -30,9 +28,6 @@ RUN ln -s /usr/local/SASHome/SASFoundation/9.4/bin/sas_en /usr/local/bin/sas &&

WORKDIR /home/jovyan

# Adds default workspace shortcut to sasstudio
COPY SWE.folderShortcuts.key $SASSTUDIO_TEMP_HOME/preferences/SWE.folderShortcuts.key

ENV PATH=$PATH:/usr/local/SASHome/SASFoundation/9.4/bin

ENV PATH=$PATH:/usr/local/SASHome/SASPrivateJavaRuntimeEnvironment/9.4/jre/bin
Expand All @@ -58,18 +53,10 @@ RUN jupyter nbextension install --py sas_kernel.showSASLog && \
jupyter nbextension enable sas_kernel.theme --py && \
jupyter nbextension list

# Jupyter SASStudio Proxy

COPY jupyter-sasstudio-proxy/ /opt/jupyter-sasstudio-proxy/
RUN pip install /opt/jupyter-sasstudio-proxy/

# Must be set in deepest image
ENV DEFAULT_JUPYTER_URL=/lab

# SAS GConfid

COPY G-CONFID107003ELNX6494M7/ /usr/local/SASHome/gensys/G-CONFID107003ELNX6494M7/
COPY sasv9_local.cfg /usr/local/SASHome/SASFoundation/9.4/

# Enable X command on SAS Studio
COPY spawner_usermods.sh /usr/local/SASHome/studioconfig/spawner/
File renamed without changes.
File renamed without changes.
68 changes: 68 additions & 0 deletions output/jupyterlab-cpu/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

ARG BASE_VERSION=2024-06-17

FROM k8scc01covidacr.azurecr.io/sas4c:0.0.3 as SASHome
FROM quay.io/jupyter/datascience-notebook:$BASE_VERSION

USER root
Expand Down Expand Up @@ -386,6 +387,73 @@ COPY jupyterlab-overrides.json /opt/conda/share/jupyter/lab/settings/overrides.j
ENV DEFAULT_JUPYTER_URL=/lab
ENV GIT_EXAMPLE_NOTEBOOKS=https://gitlab.k8s.cloud.statcan.ca/business-transformation/aaw/aaw-contrib-jupyter-notebooks

###############################
### docker-bits/6_sas.Dockerfile
###############################

# SAS

# Install Quarto
ARG QUARTO_VERSION=1.4.176
ARG QUARTO_SHA=c06edd8930903a1018a27eb9f70fb9037b28a3cd8a7eb6299e8136876b4e11b3
ARG QUARTO_URL=https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz

RUN wget -q ${QUARTO_URL} -O /tmp/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz && \
echo "${QUARTO_SHA} /tmp/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz" | sha256sum -c - && \
tar -xzvf /tmp/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz -C /tmp/ && \
chmod +x /tmp/quarto-${QUARTO_VERSION} && \
ln -s /tmp/quarto-${QUARTO_VERSION}/bin/quarto /usr/bin/quarto

RUN groupadd -g 1002 sasstaff && \
usermod -a -G sasstaff jovyan && \
echo "jovyan:jovyan" | chpasswd

COPY --from=SASHome /usr/local/SASHome /usr/local/SASHome

COPY --from=minio/mc:RELEASE.2022-03-17T20-25-06Z /bin/mc /usr/local/bin/mc

RUN apt-get update && apt-get install -y --no-install-recommends \
libmagic1 \
&& rm -rf /var/lib/apt/lists/*

RUN ln -s /usr/local/SASHome/SASFoundation/9.4/bin/sas_en /usr/local/bin/sas && \
chmod -R 0775 /usr/local/SASHome/studioconfig

WORKDIR /home/jovyan

ENV PATH=$PATH:/usr/local/SASHome/SASFoundation/9.4/bin

ENV PATH=$PATH:/usr/local/SASHome/SASPrivateJavaRuntimeEnvironment/9.4/jre/bin

RUN /usr/local/SASHome/SASFoundation/9.4/utilities/bin/setuid.sh

ENV SAS_HADOOP_JAR_PATH=/opt/hadoop

EXPOSE 8561 8591 38080

# SASPY

ENV SASPY_VERSION="5.4.0"

RUN pip install sas_kernel

# TODO: make Python version ENV var.
COPY sascfg.py /opt/conda/lib/python3.11/site-packages/saspy/sascfg.py

RUN jupyter nbextension install --py sas_kernel.showSASLog && \
jupyter nbextension enable sas_kernel.showSASLog --py && \
jupyter nbextension install --py sas_kernel.theme && \
jupyter nbextension enable sas_kernel.theme --py && \
jupyter nbextension list

# Must be set in deepest image
ENV DEFAULT_JUPYTER_URL=/lab

# SAS GConfid

COPY G-CONFID107003ELNX6494M7/ /usr/local/SASHome/gensys/G-CONFID107003ELNX6494M7/
COPY sasv9_local.cfg /usr/local/SASHome/SASFoundation/9.4/

###############################
### docker-bits/7_remove_vulnerabilities.Dockerfile
###############################
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
HOST=NONE
Binary file not shown.
Binary file not shown.
218 changes: 218 additions & 0 deletions output/jupyterlab-cpu/sascfg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
#
# Copyright SAS Institute
#
# 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
#
# http://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.
#

# THIS IS AN EXAMPLE CONFIG FILE. PLEASE CREATE YOUR OWN sascfg_personal.py FILE USING THE APPROPRIATE TEMPLATES FROM BELOW
# SEE THE CONFIGURATION DOC AT https://sassoftware.github.io/saspy/install.html#configuration


# Configuration Names for SAS - python List
# This is the list of allowed configuration definitions that can be used. The definition are defined below.
# if there is more than one name in the list, and cfgname= is not specified in SASsession(), then the user
# will be prompted to choose which configuration to use.
#
# The various options for the different access methods can be specified on the SASsession() i.e.:
# sas = SASsession(cfgname='default', options='-fullstimer', user='me')
#
# Based upon the lock_down configuration option below, you may or may not be able to override option
# that are defined already. Any necessary option (like user, pw for IOM or HTTP) that are not defined will be
# prompted for at run time. To dissallow overrides of as OPTION, when you don't have a value, simply
# specify options=''. This way it's specified so it can't be overridden, even though you don't have any
# specific value you want applied.
#
#SAS_config_names = ['default', 'ssh', 'iomlinux', 'iomwin', 'winlocal', 'winiomlinux', 'winiomwin', 'httpsviya', 'httpviya', 'iomcom']
#

SAS_config_names=['default']



# Configuration options for saspy - python Dict # not required unless changing any of the defaults
# valid key are:
#
# 'lock_down' - True | False. True = Prevent runtime overrides of SAS_Config values below
#
# 'verbose' - True | False. True = Allow print statements for debug type messages
#
# 'prompt' - True | False. True = Allow prompting as necessary
#
SAS_config_options = {'lock_down': False,
'verbose' : True,
'prompt' : True
}



# Configuration options for SAS output. By default output is HTML 5.0 (using "ods html5" statement) but certain templates might not work
# properly with HTML 5.0 so it can also be set to HTML 4.0 instead (using "ods html" statement). This option will only work when using IOM
# in local mode. Note that HTML 4.0 will generate images separately which clutters the workspace and if you download the notebook as HTML,
# the HTML file will need to be put in the same folder as the images for them to appear.
# valid key are:
#
# 'output' = ['html5', 'html']
#
SAS_output_options = {'output' : 'html5'} # not required unless changing any of the default



# Configuration Definitions
#
# For STDIO and STDIO over SSH access methods
# These need path to SASHome and optional startup options - python Dict
# The default path to the sas start up script is: /usr/local/SASHome/SASFoundation/9.4/sas
# A usual install path is: /usr/local/SASHome
#
# The encoding is figured out by saspy. You don't need to specify it, unless you just want to get rid of the message about which encoding was determined.
#
# valid keys are:
# 'saspath' - [REQUIRED] path to SAS startup script i.e.: /usr/local/SASHome/SASFoundation/9.4/sas
# 'options' - SAS options to include in the start up command line - Python List
# 'encoding' - This is the python encoding value that matches the SAS session encoding your SAS session is using
#
# For passwordless ssh connection, the following are also reuqired:
# 'ssh' - [REQUIRED] the ssh command to run
# 'host' - [REQUIRED] the host to connect to
#
# Additional valid keys for ssh:
# 'port' - [integer] the remote ssh port
# 'tunnel' - [integer] local port to open via reverse tunnel, if remote host cannot otherwise reach this client
#
default = {'saspath' : '/usr/local/SASHome/SASFoundation/9.4/bin/sas_u8'
}

ssh = {'saspath' : '/usr/local/SASHome/SASFoundation/9.4/bin/sas_en',
'ssh' : '/usr/bin/ssh',
'host' : 'remote.linux.host',
'encoding': 'latin1',
'options' : ["-fullstimer"]
}


# For IOM (Grid Manager or any IOM) and Local Windows via IOM access method
# These configuration definitions are for connecting over IOM. This is designed to be used to connect to any Workspace server, including SAS Grid, via Grid Manager
# and also to connect to a local Windows SAS session. The client side (python and java) for this access method can be either Linux or Windows.
# The STDIO access method above is only for Linux. PC SAS requires this IOM interface.
#
# The absence of the iomhost option triggers local Windows SAS mode. In this case none of 'iomhost', 'iomport', 'omruser', 'omrpw' are needed.
# a local SAS session is started up and connected to.
#
# The encoding is figured out by saspy. You don't need to specify it, unless you just want to get rid of the message about which encoding was determined.

# NONE OF THE PATHS IN THESE EAMPLES ARE RIGHT FOR YOUT INSTALL. YOU HAVE TO CHANGE THE PATHS TO BE CORRECT FOR YOUR INSTALLATION
#
# valid keys are:
# 'java' - [REQUIRED] the path to the java executable to use
# 'iomhost' - [REQUIRED for remote IOM case, Don't specify to use a local Windows Session] the resolvable host name, or ip to the IOM server to connect to
# 'iomport' - [REQUIRED for remote IOM case, Don't specify to use a local Windows Session] the port IOM is listening on
# 'authkey' - identifier for user/password credentials to read from .authinfo file. Eliminates prompting for credentials.
# 'omruser' - not suggested [REQUIRED for remote IOM case but PROMPTED for at runtime] Don't specify to use a local Windows Session
# 'omrpw' - really not suggested [REQUIRED for remote IOM case but PROMPTED for at runtime] Don't specify to use a local Windows Session
# 'encoding' - This is the python encoding value that matches the SAS session encoding of the IOM server you are connecting to
# 'appserver' - name of physical workspace server (when more than one app server defined in OMR) i.e.: 'SASApp - Workspace Server'
# 'sspi' - boolean. use IWA instead of user/pw to connect to the IOM workspace server


iomlinux = {'java' : '/usr/bin/java',
'iomhost' : 'linux.iom.host',
'iomport' : 8591,
}

iomwin = {'java' : '/usr/bin/java',
'iomhost' : 'windows.iom.host',
'iomport' : 8591,
}

winlocal = {'java' : 'java',
'encoding' : 'windows-1252',
}

winiomlinux = {'java' : 'java',
'iomhost' : 'linux.iom.host',
'iomport' : 8591,
}

winiomwin = {'java' : 'java',
'iomhost' : 'windows.iom.host',
'iomport' : 8591,
}

winiomIWA = {'java' : 'java',
'iomhost' : 'windows.iom.host',
'iomport' : 8591,
'sspi' : True
}


# For Remote and Local IOM access methods using COM interface
# These configuration definitions are for connecting over IOM using COM. This
# access method is for Windows clients connecting to remote hosts. Local
# SAS instances may also be supported.
#
# This access method does not require a Java dependency.
#
# Valid Keys:
# iomhost - Required for remote connections only. The Resolvable SAS
# server dns name.
# iomport - Required for remote connections only. The SAS workspace
# server port. Generally 8591 on standard remote
# installations. For local connections, 0 is the default.
# class_id - Required for remote connections only. The IOM workspace
# server class identifier. Use `PROC IOMOPERATE` to identify
# the correct value. This option is ignored on local connections.
# provider - [REQUIRED] IOM provider. "sas.iomprovider" is recommended.
# encoding - This is the python encoding value that matches the SAS
# session encoding of the IOM server.
# omruser - SAS user. This option is ignored on local connections.
# omrpw - SAS password. This option is ignored on local connections.
# authkey - Identifier for credentials to read from .authinfo file.

iomcom = {
'iomhost' : 'mynode.mycompany.org',
'iomport' : 8591,
'class_id': '440196d4-90f0-11d0-9f41-00a024bb830c',
'provider': 'sas.iomprovider',
'encoding': 'windows-1252'}


# HTTP access method to connect to the Compute Service
# These need ip addr, other values will be prompted for - python Dict
# valid keys are:
# 'url' - (Required if ip not specified) The URL to Viya, of the form "http[s]://host.idenifier[:port]".
# When this is specified, ip= will not be used, as the host's ip is retrieved from the url. Also, ssl= is
# set based upon http or https and port= is also parsed from the url, if provided, else defaulted based
# upon the derived ssl= value. So neither ip, port nor ssl are needed when url= is used.
# 'ip' - (Required if url not specified) The resolvable host name, or IP address to the Viya Compute Service
# 'port' - port; the code Defaults this to based upon the 'ssl' key; 443 default else 80
# 'ssl' - whether to use HTTPS or just HTTP protocal. Default is True, using ssl and poort 443
# 'context' - context name defined on the compute service [PROMTED for at runtime if more than one defined]
# 'authkey' - identifier for user/password credentials to read from .authinfo file. Eliminates prompting for credentials.
# 'options' - SAS options to include (no '-' (dashes), just option names and values)
# 'user' - not suggested [REQUIRED but PROMTED for at runtime]
# 'pw' - really not suggested [REQUIRED but PROMTED for at runtime]
#
#

httpsviya = {'ip' : 'sastpw.rndk8s.openstack.sas.com',
'context' : 'Data Mining compute context',
'authkey' : 'viya_user-pw',
'options' : ["fullstimer", "memsize=1G"]
}

httpviya = {'ip' : 'sastpw.rndk8s.openstack.sas.com',
'ssl' : False, # this will use port 80
'context' : 'Data Mining compute context',
'authkey' : 'viya_user-pw',
'options' : ["fullstimer", "memsize=1G"]
}
Loading

0 comments on commit c4d8fb0

Please sign in to comment.