casperbox 0.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- casperbox/__init__.py +8 -0
- casperbox/assets/common/packages/software.list +70 -0
- casperbox/assets/common/rootfs/etc/profile.d/casper.sh +48 -0
- casperbox/assets/common/rootfs/etc/ssh/sshd_config.d/casper.conf +8 -0
- casperbox/assets/common/rootfs/usr/local/bin/entrypoint.sh +82 -0
- casperbox/assets/common/scripts/config_mlib_devel.sh +54 -0
- casperbox/assets/common/scripts/create_user.sh +39 -0
- casperbox/assets/common/scripts/install_base.sh +27 -0
- casperbox/assets/common/scripts/install_miniconda.sh +27 -0
- casperbox/assets/common/scripts/install_scilab.sh +45 -0
- casperbox/assets/common/scripts/setup_conda_env.sh +16 -0
- casperbox/assets/common/vnc/xstartup +9 -0
- casperbox/assets/versions/m2021a/Dockerfile +85 -0
- casperbox/assets/versions/m2021a/toolflow.toml +32 -0
- casperbox/cli.py +318 -0
- casperbox/config.py +362 -0
- casperbox/errors.py +2 -0
- casperbox/podman.py +262 -0
- casperbox/templates/casperbox.toml +46 -0
- casperbox/versions.py +85 -0
- casperbox-0.2.1.dist-info/METADATA +190 -0
- casperbox-0.2.1.dist-info/RECORD +24 -0
- casperbox-0.2.1.dist-info/WHEEL +4 -0
- casperbox-0.2.1.dist-info/entry_points.txt +2 -0
casperbox/__init__.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""casperbox: build and run CASPER toolflow development containers with rootless podman."""
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
__version__ = version("casperbox")
|
|
7
|
+
except PackageNotFoundError: # running from a source tree without installation
|
|
8
|
+
__version__ = "0+unknown"
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# apt packages installed into the image by common/scripts/install_base.sh
|
|
2
|
+
# One package per line; text after # is ignored.
|
|
3
|
+
|
|
4
|
+
# ---- basic tools ----
|
|
5
|
+
ca-certificates
|
|
6
|
+
curl
|
|
7
|
+
wget
|
|
8
|
+
git
|
|
9
|
+
sudo
|
|
10
|
+
locales
|
|
11
|
+
tzdata
|
|
12
|
+
bzip2
|
|
13
|
+
xz-utils
|
|
14
|
+
unzip
|
|
15
|
+
file
|
|
16
|
+
less
|
|
17
|
+
vim
|
|
18
|
+
nano
|
|
19
|
+
procps
|
|
20
|
+
psmisc
|
|
21
|
+
iproute2
|
|
22
|
+
iputils-ping
|
|
23
|
+
net-tools
|
|
24
|
+
lsb-release
|
|
25
|
+
|
|
26
|
+
# ---- build tools ----
|
|
27
|
+
build-essential
|
|
28
|
+
make
|
|
29
|
+
gcc
|
|
30
|
+
g++
|
|
31
|
+
device-tree-compiler
|
|
32
|
+
|
|
33
|
+
# ---- ssh / vnc / desktop ----
|
|
34
|
+
openssh-server
|
|
35
|
+
tigervnc-standalone-server
|
|
36
|
+
tigervnc-common
|
|
37
|
+
xfce4
|
|
38
|
+
xfce4-terminal
|
|
39
|
+
dbus-x11
|
|
40
|
+
x11-xserver-utils
|
|
41
|
+
x11-utils
|
|
42
|
+
xfonts-base
|
|
43
|
+
fonts-dejavu
|
|
44
|
+
firefox
|
|
45
|
+
|
|
46
|
+
# ---- Vivado runtime dependencies ----
|
|
47
|
+
libtinfo5
|
|
48
|
+
libncurses5
|
|
49
|
+
libx11-6
|
|
50
|
+
libxext6
|
|
51
|
+
libxrender1
|
|
52
|
+
libxtst6
|
|
53
|
+
libxi6
|
|
54
|
+
libxft2
|
|
55
|
+
libxrandr2
|
|
56
|
+
libxcursor1
|
|
57
|
+
libxinerama1
|
|
58
|
+
libsm6
|
|
59
|
+
libice6
|
|
60
|
+
libfreetype6
|
|
61
|
+
libfontconfig1
|
|
62
|
+
libglib2.0-0
|
|
63
|
+
libgtk2.0-0
|
|
64
|
+
libgtk-3-0
|
|
65
|
+
libcanberra-gtk-module
|
|
66
|
+
libcanberra-gtk3-module
|
|
67
|
+
libasound2
|
|
68
|
+
libgl1
|
|
69
|
+
libglu1-mesa
|
|
70
|
+
graphviz
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# shellcheck shell=bash
|
|
2
|
+
# CASPER toolflow environment: Vivado, mlib_devel (startsg.local), conda env
|
|
3
|
+
# Sourced by /etc/profile (login shells) and ~/.bashrc (interactive shells); safe to source repeatedly.
|
|
4
|
+
|
|
5
|
+
# Vivado settings64.sh etc. require bash
|
|
6
|
+
[ -n "${BASH_VERSION:-}" ] || return 0
|
|
7
|
+
[ -r /etc/casper/toolflow.env ] || return 0
|
|
8
|
+
|
|
9
|
+
set -a
|
|
10
|
+
# shellcheck disable=SC1091
|
|
11
|
+
. /etc/casper/toolflow.env
|
|
12
|
+
# Generated at container startup: VIVADO_DIR / XILINX_PATH / COMPOSER_PATH
|
|
13
|
+
# shellcheck disable=SC1091
|
|
14
|
+
[ -r /etc/casper/runtime.env ] && . /etc/casper/runtime.env
|
|
15
|
+
set +a
|
|
16
|
+
|
|
17
|
+
export MLIB_DEVEL_PATH="${CASPER_TOOLFLOW_DIR}/mlib_devel"
|
|
18
|
+
|
|
19
|
+
# ~/.local/bin (scilab etc. are linked here)
|
|
20
|
+
case ":${PATH}:" in
|
|
21
|
+
*":${HOME}/.local/bin:"*) ;;
|
|
22
|
+
*) export PATH="${HOME}/.local/bin:${PATH}" ;;
|
|
23
|
+
esac
|
|
24
|
+
|
|
25
|
+
# mlib_devel local config (XILINX_PATH / JASPER_BACKEND / XLNX_DT_REPO_PATH etc.)
|
|
26
|
+
if [ -r "${MLIB_DEVEL_PATH}/startsg.local" ]; then
|
|
27
|
+
# shellcheck disable=SC1091
|
|
28
|
+
. "${MLIB_DEVEL_PATH}/startsg.local"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Vivado (load once to avoid growing PATH repeatedly)
|
|
32
|
+
_casper_vivado_settings="${XILINX_PATH:-}/settings64.sh"
|
|
33
|
+
if [ -z "${CASPER_VIVADO_LOADED:-}" ] && [ -n "${XILINX_PATH:-}" ] && [ -r "${_casper_vivado_settings}" ]; then
|
|
34
|
+
# shellcheck disable=SC1090
|
|
35
|
+
. "${_casper_vivado_settings}" >/dev/null
|
|
36
|
+
export CASPER_VIVADO_LOADED=1
|
|
37
|
+
fi
|
|
38
|
+
unset _casper_vivado_settings
|
|
39
|
+
|
|
40
|
+
# conda: activate the toolflow python env by default (CONDA_ENV_NAME, e.g. casper)
|
|
41
|
+
# Every shell must define the conda function and run activate:
|
|
42
|
+
# - environment variables are inherited from the parent, but the conda function and PS1 are not;
|
|
43
|
+
# - if the env is already active, conda only reactivates (no stacking) and restores the "(casper)" prompt.
|
|
44
|
+
if [ -r /opt/conda/etc/profile.d/conda.sh ]; then
|
|
45
|
+
# shellcheck disable=SC1091
|
|
46
|
+
. /opt/conda/etc/profile.d/conda.sh
|
|
47
|
+
conda activate "${CONDA_ENV_NAME}"
|
|
48
|
+
fi
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Container entrypoint (runs as root):
|
|
3
|
+
# 1. Set the user password from CONTAINER_PWD and the VNC password from VNC_PASSWORD
|
|
4
|
+
# 2. Start sshd (22) and vncserver :1 (5901)
|
|
5
|
+
# 3. Stay in the foreground and clean up on stop signals
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
log() { echo "[entrypoint] $*"; }
|
|
9
|
+
|
|
10
|
+
# shellcheck disable=SC1091
|
|
11
|
+
. /etc/casper/toolflow.env
|
|
12
|
+
user="${CASPER_USER}"
|
|
13
|
+
group="$(id -gn "${user}")"
|
|
14
|
+
home_dir="/home/${user}"
|
|
15
|
+
|
|
16
|
+
: "${CONTAINER_PWD:?CONTAINER_PWD is not set}"
|
|
17
|
+
VNC_PASSWORD="${VNC_PASSWORD:-${CONTAINER_PWD}}"
|
|
18
|
+
VNC_GEOMETRY="${VNC_GEOMETRY:-1920x1080}"
|
|
19
|
+
if [[ ! "${VNC_GEOMETRY}" =~ ^[0-9]+x[0-9]+$ ]]; then
|
|
20
|
+
log "Invalid VNC_GEOMETRY: ${VNC_GEOMETRY}, using 1920x1080"
|
|
21
|
+
VNC_GEOMETRY=1920x1080
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# ---- Passwords ----
|
|
25
|
+
log "Setting password for user ${user}"
|
|
26
|
+
printf '%s:%s\n' "${user}" "${CONTAINER_PWD}" | chpasswd
|
|
27
|
+
|
|
28
|
+
log "Setting VNC password"
|
|
29
|
+
install -d -m 700 -o "${user}" -g "${group}" "${home_dir}/.vnc"
|
|
30
|
+
printf '%s\n' "${VNC_PASSWORD}" | vncpasswd -f > "${home_dir}/.vnc/passwd"
|
|
31
|
+
chown "${user}:${group}" "${home_dir}/.vnc/passwd"
|
|
32
|
+
chmod 600 "${home_dir}/.vnc/passwd"
|
|
33
|
+
if [[ ! -f "${home_dir}/.vnc/xstartup" ]]; then
|
|
34
|
+
install -m 755 -o "${user}" -g "${group}" /opt/casper/vnc/xstartup "${home_dir}/.vnc/xstartup"
|
|
35
|
+
fi
|
|
36
|
+
unset CONTAINER_PWD VNC_PASSWORD
|
|
37
|
+
|
|
38
|
+
# ---- Vivado paths (mounted at the same path as on the host) ----
|
|
39
|
+
# Two layouts are supported: <VIVADO_DIR>/Vivado/<version>/settings64.sh or <VIVADO_DIR>/settings64.sh
|
|
40
|
+
: "${VIVADO_DIR:?VIVADO_DIR is not set}"
|
|
41
|
+
xilinx_path=""
|
|
42
|
+
composer_path=""
|
|
43
|
+
if [[ -r "${VIVADO_DIR}/Vivado/${VIVADO_VERSION}/settings64.sh" ]]; then
|
|
44
|
+
xilinx_path="${VIVADO_DIR}/Vivado/${VIVADO_VERSION}"
|
|
45
|
+
[[ -d "${VIVADO_DIR}/Model_Composer/${VIVADO_VERSION}" ]] \
|
|
46
|
+
&& composer_path="${VIVADO_DIR}/Model_Composer/${VIVADO_VERSION}"
|
|
47
|
+
elif [[ -r "${VIVADO_DIR}/settings64.sh" ]]; then
|
|
48
|
+
xilinx_path="${VIVADO_DIR}"
|
|
49
|
+
else
|
|
50
|
+
log "Warning: settings64.sh for Vivado ${VIVADO_VERSION} not found under ${VIVADO_DIR}, please check VIVADO_DIR"
|
|
51
|
+
fi
|
|
52
|
+
log "Vivado: ${xilinx_path:-<not found>}"
|
|
53
|
+
{
|
|
54
|
+
echo "# Generated by the entrypoint at container startup"
|
|
55
|
+
printf "VIVADO_DIR='%s'\n" "${VIVADO_DIR}"
|
|
56
|
+
printf "XILINX_PATH='%s'\n" "${xilinx_path}"
|
|
57
|
+
printf "COMPOSER_PATH='%s'\n" "${composer_path}"
|
|
58
|
+
} > /etc/casper/runtime.env
|
|
59
|
+
chmod 644 /etc/casper/runtime.env
|
|
60
|
+
|
|
61
|
+
# ---- sshd ----
|
|
62
|
+
ssh-keygen -A >/dev/null
|
|
63
|
+
mkdir -p /run/sshd
|
|
64
|
+
log "Starting sshd"
|
|
65
|
+
/usr/sbin/sshd
|
|
66
|
+
|
|
67
|
+
# ---- vncserver ----
|
|
68
|
+
rm -f /tmp/.X1-lock /tmp/.X11-unix/X1
|
|
69
|
+
log "Starting vncserver :1 (${VNC_GEOMETRY})"
|
|
70
|
+
su - "${user}" -c "vncserver :1 -geometry ${VNC_GEOMETRY} -depth 24 -localhost no -SecurityTypes VncAuth"
|
|
71
|
+
|
|
72
|
+
cleanup() {
|
|
73
|
+
log "Stopping services"
|
|
74
|
+
su - "${user}" -c "vncserver -kill :1" >/dev/null 2>&1 || true
|
|
75
|
+
pkill -TERM -x sshd 2>/dev/null || true
|
|
76
|
+
exit 0
|
|
77
|
+
}
|
|
78
|
+
trap cleanup TERM INT
|
|
79
|
+
|
|
80
|
+
log "Container ready (toolflow ${TOOLFLOW_VERSION})"
|
|
81
|
+
sleep infinity &
|
|
82
|
+
wait $!
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Configure mlib_devel (runs as the container user):
|
|
3
|
+
# 1. Clone mlib_devel and device-tree-xlnx into ~/toolflow
|
|
4
|
+
# 2. Install mlib_devel's python dependencies into the conda env
|
|
5
|
+
# 3. Generate mlib_devel/startsg.local
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
: "${MLIB_DEVEL_REPO:?}" "${MLIB_DEVEL_BRANCH:?}"
|
|
9
|
+
: "${DEVICE_TREE_XLNX_REPO:?}" "${DEVICE_TREE_XLNX_BRANCH:?}"
|
|
10
|
+
: "${CONDA_ENV_NAME:?}" "${VIVADO_VERSION:?}"
|
|
11
|
+
CONDA_DIR="${CONDA_DIR:-/opt/conda}"
|
|
12
|
+
GIT_CLONE_DEPTH="${GIT_CLONE_DEPTH:-1}"
|
|
13
|
+
|
|
14
|
+
toolflow_dir="${HOME}/toolflow"
|
|
15
|
+
mlib_dir="${toolflow_dir}/mlib_devel"
|
|
16
|
+
dt_dir="${toolflow_dir}/device-tree-xlnx"
|
|
17
|
+
|
|
18
|
+
depth_args=()
|
|
19
|
+
if [[ "${GIT_CLONE_DEPTH}" != "0" ]]; then
|
|
20
|
+
depth_args=(--depth "${GIT_CLONE_DEPTH}")
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
mkdir -p "${toolflow_dir}"
|
|
24
|
+
|
|
25
|
+
echo ">>> Cloning mlib_devel (${MLIB_DEVEL_BRANCH})"
|
|
26
|
+
git clone "${depth_args[@]}" --single-branch --branch "${MLIB_DEVEL_BRANCH}" \
|
|
27
|
+
"${MLIB_DEVEL_REPO}" "${mlib_dir}"
|
|
28
|
+
|
|
29
|
+
echo ">>> Cloning device-tree-xlnx (${DEVICE_TREE_XLNX_BRANCH})"
|
|
30
|
+
git clone "${depth_args[@]}" --single-branch --branch "${DEVICE_TREE_XLNX_BRANCH}" \
|
|
31
|
+
"${DEVICE_TREE_XLNX_REPO}" "${dt_dir}"
|
|
32
|
+
|
|
33
|
+
echo ">>> Installing mlib_devel dependencies into conda env ${CONDA_ENV_NAME}"
|
|
34
|
+
# shellcheck disable=SC1091
|
|
35
|
+
source "${CONDA_DIR}/etc/profile.d/conda.sh"
|
|
36
|
+
conda activate "${CONDA_ENV_NAME}"
|
|
37
|
+
python -m pip install --no-cache-dir --upgrade pip
|
|
38
|
+
# requirements.txt has -e git+... dependencies; put their sources in ~/toolflow/src
|
|
39
|
+
(cd "${mlib_dir}" && python -m pip install --no-cache-dir --src "${toolflow_dir}/src" -r requirements.txt)
|
|
40
|
+
|
|
41
|
+
echo ">>> Generating ${mlib_dir}/startsg.local"
|
|
42
|
+
cat > "${mlib_dir}/startsg.local" <<EOF
|
|
43
|
+
# Generated by casperbox at image build time
|
|
44
|
+
# Vivado is mounted at the host path; the entrypoint writes /etc/casper/runtime.env at container startup
|
|
45
|
+
[ -r /etc/casper/runtime.env ] && . /etc/casper/runtime.env
|
|
46
|
+
export XILINX_PATH COMPOSER_PATH
|
|
47
|
+
export PLATFORM=lin64
|
|
48
|
+
export JASPER_BACKEND=vivado
|
|
49
|
+
export XLNX_DT_REPO_PATH=${dt_dir}
|
|
50
|
+
#export MATLAB_PATH=/path/to/matlab
|
|
51
|
+
# python: shells activate conda env ${CONDA_ENV_NAME} automatically via /etc/profile.d/casper.sh
|
|
52
|
+
EOF
|
|
53
|
+
|
|
54
|
+
echo "mlib_devel configured: ${mlib_dir}"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Create the container user: UID/GID match the host user, member of the sudo group.
|
|
3
|
+
# The password is not set at build time; the entrypoint sets it from CONTAINER_PWD at startup.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
: "${CONTAINER_USER:?CONTAINER_USER is not set}"
|
|
7
|
+
: "${USER_UID:?USER_UID is not set}"
|
|
8
|
+
: "${USER_GID:?USER_GID is not set}"
|
|
9
|
+
|
|
10
|
+
# Group: reuse the GID if it already exists, otherwise create it
|
|
11
|
+
if getent group "${USER_GID}" >/dev/null; then
|
|
12
|
+
group_name="$(getent group "${USER_GID}" | cut -d: -f1)"
|
|
13
|
+
else
|
|
14
|
+
groupadd -g "${USER_GID}" "${CONTAINER_USER}"
|
|
15
|
+
group_name="${CONTAINER_USER}"
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
# If another user in the base image owns the UID (e.g. the ubuntu user), remove it
|
|
19
|
+
if existing="$(getent passwd "${USER_UID}" | cut -d: -f1)" && [[ -n "${existing}" ]] \
|
|
20
|
+
&& [[ "${existing}" != "${CONTAINER_USER}" ]]; then
|
|
21
|
+
echo "UID ${USER_UID} is used by ${existing}, removing that user"
|
|
22
|
+
userdel -r "${existing}" 2>/dev/null || userdel "${existing}"
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
useradd -m -u "${USER_UID}" -g "${group_name}" -G sudo -s /bin/bash "${CONTAINER_USER}"
|
|
26
|
+
|
|
27
|
+
home_dir="/home/${CONTAINER_USER}"
|
|
28
|
+
|
|
29
|
+
# Pre-create mount points and work directories with correct ownership
|
|
30
|
+
mkdir -p "${home_dir}/work" "${home_dir}/.Xilinx" "${home_dir}/toolflow" "${home_dir}/.vnc"
|
|
31
|
+
chown -R "${USER_UID}:${USER_GID}" "${home_dir}"
|
|
32
|
+
|
|
33
|
+
# Non-login shells (e.g. terminals opened in VNC) also load the toolflow environment
|
|
34
|
+
cat >> "${home_dir}/.bashrc" <<'EOF'
|
|
35
|
+
|
|
36
|
+
# CASPER toolflow environment (Vivado / conda / mlib_devel)
|
|
37
|
+
[ -r /etc/profile.d/casper.sh ] && . /etc/profile.d/casper.sh
|
|
38
|
+
EOF
|
|
39
|
+
chown "${USER_UID}:${USER_GID}" "${home_dir}/.bashrc"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Install the system packages listed in common/packages/software.list
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
export DEBIAN_FRONTEND=noninteractive
|
|
6
|
+
|
|
7
|
+
# Package list: one package per line, # starts a comment
|
|
8
|
+
pkg_list="${1:-/opt/casper/packages/software.list}"
|
|
9
|
+
[[ -r "${pkg_list}" ]] || { echo "Error: package list not found: ${pkg_list}" >&2; exit 1; }
|
|
10
|
+
mapfile -t packages < <(sed -e 's/#.*//' -e 's/[[:space:]]//g' -e '/^$/d' "${pkg_list}")
|
|
11
|
+
(( ${#packages[@]} > 0 )) || { echo "Error: no packages in ${pkg_list}" >&2; exit 1; }
|
|
12
|
+
echo "Installing ${#packages[@]} packages from ${pkg_list}"
|
|
13
|
+
|
|
14
|
+
apt-get update
|
|
15
|
+
apt-get install -y --no-install-recommends "${packages[@]}"
|
|
16
|
+
|
|
17
|
+
# locale
|
|
18
|
+
sed -i 's/^# *\(en_US.UTF-8 UTF-8\)/\1/' /etc/locale.gen
|
|
19
|
+
locale-gen
|
|
20
|
+
update-locale LANG=en_US.UTF-8
|
|
21
|
+
|
|
22
|
+
# sshd: no auditd in the container, make pam_loginuid optional to avoid login failures
|
|
23
|
+
mkdir -p /run/sshd
|
|
24
|
+
sed -i 's/^\(session\s\+\)required\(\s\+pam_loginuid.so\)/\1optional\2/' /etc/pam.d/sshd
|
|
25
|
+
|
|
26
|
+
apt-get clean
|
|
27
|
+
rm -rf /var/lib/apt/lists/*
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Install Miniconda to ${CONDA_DIR} (default /opt/conda) and hand ownership to the container user
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
: "${MINICONDA_INSTALLER:?MINICONDA_INSTALLER is not set}"
|
|
6
|
+
: "${CONTAINER_USER:?CONTAINER_USER is not set}"
|
|
7
|
+
CONDA_DIR="${CONDA_DIR:-/opt/conda}"
|
|
8
|
+
|
|
9
|
+
tmp_dir="$(mktemp -d)"
|
|
10
|
+
trap 'rm -rf "${tmp_dir}"' EXIT
|
|
11
|
+
|
|
12
|
+
curl -fL --retry 3 -o "${tmp_dir}/miniconda.sh" \
|
|
13
|
+
"https://repo.anaconda.com/miniconda/${MINICONDA_INSTALLER}"
|
|
14
|
+
bash "${tmp_dir}/miniconda.sh" -b -p "${CONDA_DIR}"
|
|
15
|
+
|
|
16
|
+
# Use conda-forge only, avoiding the Terms of Service restrictions of the Anaconda defaults channel
|
|
17
|
+
cat > "${CONDA_DIR}/.condarc" <<'EOF'
|
|
18
|
+
channels:
|
|
19
|
+
- conda-forge
|
|
20
|
+
channel_priority: strict
|
|
21
|
+
auto_activate_base: false
|
|
22
|
+
EOF
|
|
23
|
+
|
|
24
|
+
"${CONDA_DIR}/bin/conda" clean -afy
|
|
25
|
+
|
|
26
|
+
# Let the container user install/upgrade packages
|
|
27
|
+
chown -R "${CONTAINER_USER}:$(id -gn "${CONTAINER_USER}")" "${CONDA_DIR}"
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Install Scilab:
|
|
3
|
+
# 1. Download the .tar.gz / .tar.xz archive at SCILAB_URL
|
|
4
|
+
# 2. Extract it to /opt/scilab (stripping the top-level scilab-<version>/ directory)
|
|
5
|
+
# 3. Link the executable to the container user's ~/.local/bin/scilab
|
|
6
|
+
# Runs as root, after create_user.sh.
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
: "${SCILAB_VERSION:?SCILAB_VERSION is not set}"
|
|
10
|
+
: "${SCILAB_URL:?SCILAB_URL is not set}"
|
|
11
|
+
: "${CONTAINER_USER:?CONTAINER_USER is not set}"
|
|
12
|
+
|
|
13
|
+
install_dir=/opt/scilab
|
|
14
|
+
user_group="$(id -gn "${CONTAINER_USER}")"
|
|
15
|
+
user_bin="/home/${CONTAINER_USER}/.local/bin"
|
|
16
|
+
|
|
17
|
+
case "${SCILAB_URL}" in
|
|
18
|
+
*.tar.gz|*.tgz|*.tar.xz) ;;
|
|
19
|
+
*) echo "Error: SCILAB_URL must point to a .tar.gz or .tar.xz archive: ${SCILAB_URL}" >&2; exit 1 ;;
|
|
20
|
+
esac
|
|
21
|
+
|
|
22
|
+
tmp_dir="$(mktemp -d)"
|
|
23
|
+
trap 'rm -rf "${tmp_dir}"' EXIT
|
|
24
|
+
archive="${tmp_dir}/$(basename "${SCILAB_URL}")"
|
|
25
|
+
|
|
26
|
+
echo "Downloading Scilab ${SCILAB_VERSION}: ${SCILAB_URL}"
|
|
27
|
+
curl -fL --retry 3 -o "${archive}" "${SCILAB_URL}"
|
|
28
|
+
|
|
29
|
+
# Extract to /opt/scilab (tar detects gz / xz automatically)
|
|
30
|
+
rm -rf "${install_dir}"
|
|
31
|
+
mkdir -p "${install_dir}"
|
|
32
|
+
tar -xf "${archive}" -C "${install_dir}" --strip-components=1
|
|
33
|
+
|
|
34
|
+
if [[ ! -x "${install_dir}/bin/scilab" ]]; then
|
|
35
|
+
echo "Error: ${install_dir}/bin/scilab not found after extraction, please check the archive" >&2
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# Link to the user's ~/.local/bin/scilab (owned by the container user, so pip --user etc. work)
|
|
40
|
+
install -d -m 755 -o "${CONTAINER_USER}" -g "${user_group}" \
|
|
41
|
+
"/home/${CONTAINER_USER}/.local" "${user_bin}"
|
|
42
|
+
ln -sfn "${install_dir}/bin/scilab" "${user_bin}/scilab"
|
|
43
|
+
chown -h "${CONTAINER_USER}:${user_group}" "${user_bin}/scilab"
|
|
44
|
+
|
|
45
|
+
echo "Scilab ${SCILAB_VERSION} installed to ${install_dir}, linked at ${user_bin}/scilab"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Create conda env CONDA_ENV_NAME with PYTHON_VERSION (runs as the container user)
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
: "${PYTHON_VERSION:?PYTHON_VERSION is not set}"
|
|
6
|
+
: "${CONDA_ENV_NAME:?CONDA_ENV_NAME is not set}"
|
|
7
|
+
CONDA_DIR="${CONDA_DIR:-/opt/conda}"
|
|
8
|
+
|
|
9
|
+
# shellcheck disable=SC1091
|
|
10
|
+
source "${CONDA_DIR}/etc/profile.d/conda.sh"
|
|
11
|
+
|
|
12
|
+
conda create -y -n "${CONDA_ENV_NAME}" --override-channels -c conda-forge \
|
|
13
|
+
"python=${PYTHON_VERSION}" pip
|
|
14
|
+
conda clean -afy
|
|
15
|
+
|
|
16
|
+
echo "conda env ${CONDA_ENV_NAME} (python ${PYTHON_VERSION}) created"
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# CASPER toolflow m2021a image
|
|
2
|
+
# Built by `casper build`: build args come from versions/m2021a/toolflow.toml and the
|
|
3
|
+
# user's casper.toml; the build context is the package's assets/ directory.
|
|
4
|
+
# Do not change the defaults here to switch versions.
|
|
5
|
+
|
|
6
|
+
ARG BASE_IMAGE=docker.io/library/ubuntu:20.04
|
|
7
|
+
FROM ${BASE_IMAGE}
|
|
8
|
+
|
|
9
|
+
# ---- toolflow version args (from toolflow.toml) ----
|
|
10
|
+
ARG TOOLFLOW_VERSION
|
|
11
|
+
ARG VIVADO_VERSION
|
|
12
|
+
ARG MINICONDA_INSTALLER
|
|
13
|
+
ARG PYTHON_VERSION
|
|
14
|
+
ARG CONDA_ENV_NAME
|
|
15
|
+
ARG MLIB_DEVEL_REPO
|
|
16
|
+
ARG MLIB_DEVEL_BRANCH
|
|
17
|
+
ARG DEVICE_TREE_XLNX_REPO
|
|
18
|
+
ARG DEVICE_TREE_XLNX_BRANCH
|
|
19
|
+
ARG GIT_CLONE_DEPTH=1
|
|
20
|
+
ARG SCILAB_VERSION
|
|
21
|
+
ARG SCILAB_URL
|
|
22
|
+
|
|
23
|
+
# ---- user args (from casper.toml / host) ----
|
|
24
|
+
ARG CONTAINER_USER=casper
|
|
25
|
+
ARG USER_UID=1000
|
|
26
|
+
ARG USER_GID=1000
|
|
27
|
+
|
|
28
|
+
LABEL casper.toolflow.version="${TOOLFLOW_VERSION}" \
|
|
29
|
+
casper.user="${CONTAINER_USER}" \
|
|
30
|
+
casper.uid="${USER_UID}" \
|
|
31
|
+
casper.gid="${USER_GID}"
|
|
32
|
+
|
|
33
|
+
ENV DEBIAN_FRONTEND=noninteractive \
|
|
34
|
+
LANG=en_US.UTF-8 \
|
|
35
|
+
LC_ALL=en_US.UTF-8 \
|
|
36
|
+
CONDA_DIR=/opt/conda
|
|
37
|
+
|
|
38
|
+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
|
39
|
+
|
|
40
|
+
# 1. System packages: openssh-server / tigervnc / firefox / desktop / Vivado dependencies
|
|
41
|
+
COPY common/packages/software.list /opt/casper/packages/
|
|
42
|
+
COPY common/scripts/install_base.sh /opt/casper/scripts/
|
|
43
|
+
RUN bash /opt/casper/scripts/install_base.sh
|
|
44
|
+
|
|
45
|
+
# 2. Create the user (UID/GID match the host, for userns keep-id)
|
|
46
|
+
COPY common/scripts/create_user.sh /opt/casper/scripts/
|
|
47
|
+
RUN bash /opt/casper/scripts/create_user.sh
|
|
48
|
+
|
|
49
|
+
# 3. Scilab: extract to /opt/scilab, link to ~/.local/bin/scilab (requires the user)
|
|
50
|
+
COPY common/scripts/install_scilab.sh /opt/casper/scripts/
|
|
51
|
+
RUN bash /opt/casper/scripts/install_scilab.sh
|
|
52
|
+
|
|
53
|
+
# 4. Miniconda
|
|
54
|
+
COPY common/scripts/install_miniconda.sh /opt/casper/scripts/
|
|
55
|
+
RUN bash /opt/casper/scripts/install_miniconda.sh
|
|
56
|
+
|
|
57
|
+
# 5. conda env + mlib_devel (run as the regular user so file ownership is correct)
|
|
58
|
+
COPY common/scripts/setup_conda_env.sh common/scripts/config_mlib_devel.sh /opt/casper/scripts/
|
|
59
|
+
USER ${CONTAINER_USER}
|
|
60
|
+
RUN HOME="/home/${CONTAINER_USER}" bash /opt/casper/scripts/setup_conda_env.sh
|
|
61
|
+
RUN HOME="/home/${CONTAINER_USER}" bash /opt/casper/scripts/config_mlib_devel.sh
|
|
62
|
+
USER root
|
|
63
|
+
|
|
64
|
+
# 6. Runtime files: sshd config, profile, entrypoint, VNC xstartup
|
|
65
|
+
COPY common/rootfs/ /
|
|
66
|
+
COPY common/vnc/xstartup /opt/casper/vnc/xstartup
|
|
67
|
+
RUN chmod 755 /usr/local/bin/entrypoint.sh /opt/casper/vnc/xstartup \
|
|
68
|
+
&& chmod 644 /etc/profile.d/casper.sh /etc/ssh/sshd_config.d/casper.conf \
|
|
69
|
+
&& mkdir -p /etc/casper \
|
|
70
|
+
&& { \
|
|
71
|
+
echo "CASPER_USER=${CONTAINER_USER}"; \
|
|
72
|
+
echo "CASPER_TOOLFLOW_DIR=/home/${CONTAINER_USER}/toolflow"; \
|
|
73
|
+
echo "TOOLFLOW_VERSION=${TOOLFLOW_VERSION}"; \
|
|
74
|
+
echo "VIVADO_VERSION=${VIVADO_VERSION}"; \
|
|
75
|
+
echo "PYTHON_VERSION=${PYTHON_VERSION}"; \
|
|
76
|
+
echo "CONDA_ENV_NAME=${CONDA_ENV_NAME}"; \
|
|
77
|
+
echo "MLIB_DEVEL_BRANCH=${MLIB_DEVEL_BRANCH}"; \
|
|
78
|
+
echo "DEVICE_TREE_XLNX_BRANCH=${DEVICE_TREE_XLNX_BRANCH}"; \
|
|
79
|
+
echo "SCILAB_VERSION=${SCILAB_VERSION}"; \
|
|
80
|
+
} > /etc/casper/toolflow.env \
|
|
81
|
+
&& chmod 644 /etc/casper/toolflow.env
|
|
82
|
+
|
|
83
|
+
EXPOSE 22 5901
|
|
84
|
+
|
|
85
|
+
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# CASPER toolflow m2021a version definition
|
|
2
|
+
#
|
|
3
|
+
# Managed by the maintainers and shipped with the casper tool; users do not edit it.
|
|
4
|
+
# Every key is passed to the Dockerfile as a build arg of the same name.
|
|
5
|
+
|
|
6
|
+
TOOLFLOW_VERSION = "m2021a"
|
|
7
|
+
|
|
8
|
+
# Base image (fully qualified name to avoid podman short-name prompts)
|
|
9
|
+
BASE_IMAGE = "docker.io/library/ubuntu:20.04"
|
|
10
|
+
|
|
11
|
+
# Vivado version: vivado.dir must contain Vivado/<VIVADO_VERSION>/settings64.sh
|
|
12
|
+
VIVADO_VERSION = "2021.1"
|
|
13
|
+
|
|
14
|
+
# Python / conda
|
|
15
|
+
MINICONDA_INSTALLER = "Miniconda3-latest-Linux-x86_64.sh"
|
|
16
|
+
PYTHON_VERSION = "3.14"
|
|
17
|
+
CONDA_ENV_NAME = "casper"
|
|
18
|
+
|
|
19
|
+
# mlib_devel
|
|
20
|
+
MLIB_DEVEL_REPO = "https://github.com/liuweiseu/mlib_devel.git"
|
|
21
|
+
MLIB_DEVEL_BRANCH = "scilab-dev-ai"
|
|
22
|
+
|
|
23
|
+
# device-tree-xlnx (used by mlib_devel via XLNX_DT_REPO_PATH)
|
|
24
|
+
DEVICE_TREE_XLNX_REPO = "https://github.com/Xilinx/device-tree-xlnx.git"
|
|
25
|
+
DEVICE_TREE_XLNX_BRANCH = "xlnx_rel_v2021.1"
|
|
26
|
+
|
|
27
|
+
# git clone depth (0 = full history)
|
|
28
|
+
GIT_CLONE_DEPTH = "1"
|
|
29
|
+
|
|
30
|
+
# Scilab
|
|
31
|
+
SCILAB_VERSION = "2024.1.0"
|
|
32
|
+
SCILAB_URL = "https://www.scilab.org/download/2024.1.0/scilab-2024.1.0.bin.x86_64-linux-gnu.tar.xz"
|