casperbox 0.2.1__tar.gz

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.
Files changed (26) hide show
  1. casperbox-0.2.1/.gitignore +10 -0
  2. casperbox-0.2.1/PKG-INFO +190 -0
  3. casperbox-0.2.1/README.md +182 -0
  4. casperbox-0.2.1/pyproject.toml +27 -0
  5. casperbox-0.2.1/src/casperbox/__init__.py +8 -0
  6. casperbox-0.2.1/src/casperbox/assets/common/packages/software.list +70 -0
  7. casperbox-0.2.1/src/casperbox/assets/common/rootfs/etc/profile.d/casper.sh +48 -0
  8. casperbox-0.2.1/src/casperbox/assets/common/rootfs/etc/ssh/sshd_config.d/casper.conf +8 -0
  9. casperbox-0.2.1/src/casperbox/assets/common/rootfs/usr/local/bin/entrypoint.sh +82 -0
  10. casperbox-0.2.1/src/casperbox/assets/common/scripts/config_mlib_devel.sh +54 -0
  11. casperbox-0.2.1/src/casperbox/assets/common/scripts/create_user.sh +39 -0
  12. casperbox-0.2.1/src/casperbox/assets/common/scripts/install_base.sh +27 -0
  13. casperbox-0.2.1/src/casperbox/assets/common/scripts/install_miniconda.sh +27 -0
  14. casperbox-0.2.1/src/casperbox/assets/common/scripts/install_scilab.sh +45 -0
  15. casperbox-0.2.1/src/casperbox/assets/common/scripts/setup_conda_env.sh +16 -0
  16. casperbox-0.2.1/src/casperbox/assets/common/vnc/xstartup +9 -0
  17. casperbox-0.2.1/src/casperbox/assets/versions/m2021a/Dockerfile +85 -0
  18. casperbox-0.2.1/src/casperbox/assets/versions/m2021a/toolflow.toml +32 -0
  19. casperbox-0.2.1/src/casperbox/cli.py +318 -0
  20. casperbox-0.2.1/src/casperbox/config.py +362 -0
  21. casperbox-0.2.1/src/casperbox/errors.py +2 -0
  22. casperbox-0.2.1/src/casperbox/podman.py +262 -0
  23. casperbox-0.2.1/src/casperbox/templates/casperbox.toml +46 -0
  24. casperbox-0.2.1/src/casperbox/versions.py +85 -0
  25. casperbox-0.2.1/tests/test_config.py +172 -0
  26. casperbox-0.2.1/uv.lock +150 -0
@@ -0,0 +1,10 @@
1
+ # casperbox configs (contain local paths and passwords)
2
+ /casperbox.toml
3
+
4
+ # Python
5
+ __pycache__/
6
+ *.egg-info/
7
+ .venv/
8
+ dist/
9
+ build/
10
+ .pytest_cache/
@@ -0,0 +1,190 @@
1
+ Metadata-Version: 2.5
2
+ Name: casperbox
3
+ Version: 0.2.1
4
+ Summary: Build and run CASPER toolflow development containers with rootless podman
5
+ Requires-Python: >=3.11
6
+ Requires-Dist: typer>=0.12
7
+ Description-Content-Type: text/markdown
8
+
9
+ # casperbox
10
+
11
+ `casperbox` builds and runs CASPER toolflow development containers with rootless podman.
12
+
13
+ The image includes openssh-server, TigerVNC (XFCE desktop), Firefox, Miniconda (conda env),
14
+ mlib_devel, device-tree-xlnx and Scilab. Vivado and the license are mounted from the host.
15
+
16
+ ## Supported versions
17
+
18
+ | Version | Base image | Vivado | Python | mlib_devel | device-tree-xlnx | Scilab |
19
+ |---|---|---|---|---|---|---|
20
+ | m2021a | Ubuntu 20.04 | 2021.1 | 3.14 | [liuweiseu/mlib_devel](https://github.com/liuweiseu/mlib_devel) `scilab-dev-ai` | xlnx_rel_v2021.1 | 2024.1.0 |
21
+
22
+ ## Host requirements
23
+
24
+ - [uv](https://docs.astral.sh/uv/) (installs without sudo)
25
+ - rootless podman >= 4.4 (run as a regular user) and the passt package (provides pasta)
26
+ - An installed Vivado (version in the table above) and a Xilinx license
27
+
28
+ ## Host setup
29
+
30
+ Log in directly (SSH or desktop) as the user that runs podman (do not switch with `su`), then run:
31
+
32
+ ```bash
33
+ loginctl enable-linger "$(id -un)" # keep the user's systemd running, also after logout
34
+ grep "^$(id -un):" /etc/subuid /etc/subgid # should print one line each; otherwise ask an admin
35
+ podman system migrate
36
+ ls /run/user/$(id -u)/bus # the user's systemd bus must exist
37
+ podman run --rm docker.io/library/ubuntu:20.04 true # must succeed with no WARN/ERROR
38
+ ```
39
+
40
+ If the last command fails with `sd-bus call: Access denied` (no user systemd session, e.g. after `su`),
41
+ either point the shell at the user's bus:
42
+
43
+ ```bash
44
+ export XDG_RUNTIME_DIR=/run/user/$(id -u)
45
+ export DBUS_SESSION_BUS_ADDRESS=unix:path=$XDG_RUNTIME_DIR/bus
46
+ ```
47
+
48
+ or stop podman from using systemd for cgroups:
49
+
50
+ ```bash
51
+ mkdir -p ~/.config/containers
52
+ printf '[engine]\ncgroup_manager = "cgroupfs"\nevents_logger = "file"\n' >> ~/.config/containers/containers.conf
53
+ podman system migrate
54
+ ```
55
+
56
+ ## Install
57
+
58
+ ```bash
59
+ uv tool install git+https://github.com/<owner>/casperbox
60
+ # or from a local clone
61
+ uv tool install ./casperbox
62
+ ```
63
+
64
+ Upgrade with `uv tool upgrade casperbox`.
65
+
66
+ ## Quick start
67
+
68
+ ```bash
69
+ mkdir ~/casper-a && cd ~/casper-a
70
+ casperbox init # creates casperbox.toml
71
+ vi casperbox.toml # set vivado.dir / paths.license_dir / ports
72
+ casperbox up # builds the image on first use, then starts the container
73
+ ```
74
+
75
+ Connect:
76
+
77
+ - SSH: `ssh -p <ports.ssh> casper@<host>`, password `container.password` (default `casper`)
78
+ - VNC: `<host>:<ports.vnc>`, password `container.vnc_password` (default `casper`)
79
+ - Local: `casperbox shell`
80
+
81
+ ## Configuration
82
+
83
+ `casperbox init` writes a commented `casperbox.toml` (permissions 600, it holds passwords).
84
+ Relative paths in it are relative to the file's directory.
85
+
86
+ | Key | Default | Description |
87
+ |---|---|---|
88
+ | `version` | | Toolflow version (`casperbox list`) |
89
+ | `container.name` | `casper-<version>` | Container name and hostname |
90
+ | `container.user` | `casper` | Container user |
91
+ | `container.password` / `vnc_password` | `casper` | SSH/sudo and VNC (6-8 chars) passwords |
92
+ | `container.mac` | random | MAC of `eth0` |
93
+ | `container.shm_size` / `tz` | `2g` / `UTC` | |
94
+ | `vivado.dir` / `vivado.mount` | / `ro` | Vivado install, mounted at the same path |
95
+ | `paths.license_dir` | `~/.Xilinx` | Mounted at `~/.Xilinx` |
96
+ | `paths.work_dir` | `./work` | Mounted at `~/work` (created if missing) |
97
+ | `ports.bind_address` | `0.0.0.0` | |
98
+ | `ports.ssh` / `ports.vnc` | `2222` / `5901` | Host ports for container 22 / 5901 |
99
+ | `vnc.geometry` | `1920x1080` | |
100
+ | `[[mounts]]` | | Extra mounts: `host`, `container` (`~/` = home), `mode` |
101
+ | `[[extra_ports]]` | | Extra ports: `host`, `container`, `protocol` |
102
+
103
+ Unknown keys and wrong types (e.g. a port written as a string) are reported as errors.
104
+
105
+ ### Several containers
106
+
107
+ Each config file is one container. Use another directory or file, and give it its own
108
+ `container.name` and ports:
109
+
110
+ ```bash
111
+ casperbox init lab.toml # edit container.name, ports.ssh, ports.vnc
112
+ casperbox -c lab.toml up
113
+ casperbox ps # all casperbox containers, from any directory
114
+ ```
115
+
116
+ `casperbox` refuses to recreate or remove a container that was created from a different config file.
117
+
118
+ ## Commands
119
+
120
+ | Command | Description |
121
+ |---|---|
122
+ | `casperbox list` | List supported toolflow versions |
123
+ | `casperbox init [FILE] [--toolflow VER] [--force]` | Create a config file (default `casperbox.toml`) |
124
+ | `casperbox build [--no-cache]` | Build the image |
125
+ | `casperbox up` | Start (recreate) the container; builds the image if missing |
126
+ | `casperbox down` | Stop and remove the container |
127
+ | `casperbox restart` | `down` + `up` |
128
+ | `casperbox shell` | Open a login shell as the container user |
129
+ | `casperbox status` | Container status and ports |
130
+ | `casperbox logs [-f]` | Container logs |
131
+ | `casperbox config` | Resolved config and podman commands (passwords masked) |
132
+ | `casperbox ps` | List all casperbox containers |
133
+
134
+ `-c FILE` selects the config file (before or after the command); the default is `./casperbox.toml`.
135
+
136
+ ## Inside the container
137
+
138
+ ```
139
+ ~/toolflow/
140
+ ├── mlib_devel/ # includes the generated startsg.local
141
+ ├── device-tree-xlnx/
142
+ └── src/ # -e dependencies from requirements.txt
143
+ ```
144
+
145
+ Shells automatically load Vivado `settings64.sh` and the variables in `startsg.local`, and activate the conda env `casper`.
146
+ Scilab is in `/opt/scilab`; run `scilab` (linked in `~/.local/bin`).
147
+
148
+ > `~/toolflow` is part of the image, not a mount. `down`/`up` recreate the container and
149
+ > discard changes made there; keep your projects under `~/work`.
150
+
151
+ ## Networking (pasta)
152
+
153
+ The container uses pasta networking (no bridge network). Ports are forwarded with `-p`,
154
+ the interface is named `eth0`, and the container sees the same IP as the host.
155
+ `container.mac` is applied with pasta's `--ns-mac-addr` (e.g. for a MAC-locked node-locked license);
156
+ the interface exists only in the container's network namespace, so reusing the host NIC's MAC is safe.
157
+
158
+ ## After changing the config
159
+
160
+ | Change | Action |
161
+ |---|---|
162
+ | Directories, ports, passwords, MAC, mounts | `casperbox up` |
163
+ | `container.user`, or a different host user (UID/GID changed) | `casperbox build`, then `casperbox up` |
164
+
165
+ ## Development
166
+
167
+ ```
168
+ src/casperbox/
169
+ ├── cli.py Typer commands
170
+ ├── config.py casperbox.toml parsing and validation
171
+ ├── podman.py podman build/run arguments and container queries
172
+ ├── versions.py toolflow versions in assets/versions
173
+ ├── templates/ casperbox.toml template
174
+ └── assets/ build context: Dockerfiles, build scripts, rootfs, software.list
175
+ tests/ pytest tests
176
+ ```
177
+
178
+ ```bash
179
+ uv sync
180
+ uv run pytest
181
+ uv run casperbox --help
182
+ uv tool install -e . # installed casperbox uses this source tree
183
+ ```
184
+
185
+ Adding apt packages: add one per line to `assets/common/packages/software.list`, then `casperbox build`.
186
+
187
+ Adding a toolflow version: copy `assets/versions/m2021a` to `assets/versions/<new>`, edit
188
+ `toolflow.toml` (`TOOLFLOW_VERSION` must match the directory name) and the Dockerfile as needed.
189
+
190
+ The shell-based tool (`casper.sh`) is available at tag `v0.1.0`.
@@ -0,0 +1,182 @@
1
+ # casperbox
2
+
3
+ `casperbox` builds and runs CASPER toolflow development containers with rootless podman.
4
+
5
+ The image includes openssh-server, TigerVNC (XFCE desktop), Firefox, Miniconda (conda env),
6
+ mlib_devel, device-tree-xlnx and Scilab. Vivado and the license are mounted from the host.
7
+
8
+ ## Supported versions
9
+
10
+ | Version | Base image | Vivado | Python | mlib_devel | device-tree-xlnx | Scilab |
11
+ |---|---|---|---|---|---|---|
12
+ | m2021a | Ubuntu 20.04 | 2021.1 | 3.14 | [liuweiseu/mlib_devel](https://github.com/liuweiseu/mlib_devel) `scilab-dev-ai` | xlnx_rel_v2021.1 | 2024.1.0 |
13
+
14
+ ## Host requirements
15
+
16
+ - [uv](https://docs.astral.sh/uv/) (installs without sudo)
17
+ - rootless podman >= 4.4 (run as a regular user) and the passt package (provides pasta)
18
+ - An installed Vivado (version in the table above) and a Xilinx license
19
+
20
+ ## Host setup
21
+
22
+ Log in directly (SSH or desktop) as the user that runs podman (do not switch with `su`), then run:
23
+
24
+ ```bash
25
+ loginctl enable-linger "$(id -un)" # keep the user's systemd running, also after logout
26
+ grep "^$(id -un):" /etc/subuid /etc/subgid # should print one line each; otherwise ask an admin
27
+ podman system migrate
28
+ ls /run/user/$(id -u)/bus # the user's systemd bus must exist
29
+ podman run --rm docker.io/library/ubuntu:20.04 true # must succeed with no WARN/ERROR
30
+ ```
31
+
32
+ If the last command fails with `sd-bus call: Access denied` (no user systemd session, e.g. after `su`),
33
+ either point the shell at the user's bus:
34
+
35
+ ```bash
36
+ export XDG_RUNTIME_DIR=/run/user/$(id -u)
37
+ export DBUS_SESSION_BUS_ADDRESS=unix:path=$XDG_RUNTIME_DIR/bus
38
+ ```
39
+
40
+ or stop podman from using systemd for cgroups:
41
+
42
+ ```bash
43
+ mkdir -p ~/.config/containers
44
+ printf '[engine]\ncgroup_manager = "cgroupfs"\nevents_logger = "file"\n' >> ~/.config/containers/containers.conf
45
+ podman system migrate
46
+ ```
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ uv tool install git+https://github.com/<owner>/casperbox
52
+ # or from a local clone
53
+ uv tool install ./casperbox
54
+ ```
55
+
56
+ Upgrade with `uv tool upgrade casperbox`.
57
+
58
+ ## Quick start
59
+
60
+ ```bash
61
+ mkdir ~/casper-a && cd ~/casper-a
62
+ casperbox init # creates casperbox.toml
63
+ vi casperbox.toml # set vivado.dir / paths.license_dir / ports
64
+ casperbox up # builds the image on first use, then starts the container
65
+ ```
66
+
67
+ Connect:
68
+
69
+ - SSH: `ssh -p <ports.ssh> casper@<host>`, password `container.password` (default `casper`)
70
+ - VNC: `<host>:<ports.vnc>`, password `container.vnc_password` (default `casper`)
71
+ - Local: `casperbox shell`
72
+
73
+ ## Configuration
74
+
75
+ `casperbox init` writes a commented `casperbox.toml` (permissions 600, it holds passwords).
76
+ Relative paths in it are relative to the file's directory.
77
+
78
+ | Key | Default | Description |
79
+ |---|---|---|
80
+ | `version` | | Toolflow version (`casperbox list`) |
81
+ | `container.name` | `casper-<version>` | Container name and hostname |
82
+ | `container.user` | `casper` | Container user |
83
+ | `container.password` / `vnc_password` | `casper` | SSH/sudo and VNC (6-8 chars) passwords |
84
+ | `container.mac` | random | MAC of `eth0` |
85
+ | `container.shm_size` / `tz` | `2g` / `UTC` | |
86
+ | `vivado.dir` / `vivado.mount` | / `ro` | Vivado install, mounted at the same path |
87
+ | `paths.license_dir` | `~/.Xilinx` | Mounted at `~/.Xilinx` |
88
+ | `paths.work_dir` | `./work` | Mounted at `~/work` (created if missing) |
89
+ | `ports.bind_address` | `0.0.0.0` | |
90
+ | `ports.ssh` / `ports.vnc` | `2222` / `5901` | Host ports for container 22 / 5901 |
91
+ | `vnc.geometry` | `1920x1080` | |
92
+ | `[[mounts]]` | | Extra mounts: `host`, `container` (`~/` = home), `mode` |
93
+ | `[[extra_ports]]` | | Extra ports: `host`, `container`, `protocol` |
94
+
95
+ Unknown keys and wrong types (e.g. a port written as a string) are reported as errors.
96
+
97
+ ### Several containers
98
+
99
+ Each config file is one container. Use another directory or file, and give it its own
100
+ `container.name` and ports:
101
+
102
+ ```bash
103
+ casperbox init lab.toml # edit container.name, ports.ssh, ports.vnc
104
+ casperbox -c lab.toml up
105
+ casperbox ps # all casperbox containers, from any directory
106
+ ```
107
+
108
+ `casperbox` refuses to recreate or remove a container that was created from a different config file.
109
+
110
+ ## Commands
111
+
112
+ | Command | Description |
113
+ |---|---|
114
+ | `casperbox list` | List supported toolflow versions |
115
+ | `casperbox init [FILE] [--toolflow VER] [--force]` | Create a config file (default `casperbox.toml`) |
116
+ | `casperbox build [--no-cache]` | Build the image |
117
+ | `casperbox up` | Start (recreate) the container; builds the image if missing |
118
+ | `casperbox down` | Stop and remove the container |
119
+ | `casperbox restart` | `down` + `up` |
120
+ | `casperbox shell` | Open a login shell as the container user |
121
+ | `casperbox status` | Container status and ports |
122
+ | `casperbox logs [-f]` | Container logs |
123
+ | `casperbox config` | Resolved config and podman commands (passwords masked) |
124
+ | `casperbox ps` | List all casperbox containers |
125
+
126
+ `-c FILE` selects the config file (before or after the command); the default is `./casperbox.toml`.
127
+
128
+ ## Inside the container
129
+
130
+ ```
131
+ ~/toolflow/
132
+ ├── mlib_devel/ # includes the generated startsg.local
133
+ ├── device-tree-xlnx/
134
+ └── src/ # -e dependencies from requirements.txt
135
+ ```
136
+
137
+ Shells automatically load Vivado `settings64.sh` and the variables in `startsg.local`, and activate the conda env `casper`.
138
+ Scilab is in `/opt/scilab`; run `scilab` (linked in `~/.local/bin`).
139
+
140
+ > `~/toolflow` is part of the image, not a mount. `down`/`up` recreate the container and
141
+ > discard changes made there; keep your projects under `~/work`.
142
+
143
+ ## Networking (pasta)
144
+
145
+ The container uses pasta networking (no bridge network). Ports are forwarded with `-p`,
146
+ the interface is named `eth0`, and the container sees the same IP as the host.
147
+ `container.mac` is applied with pasta's `--ns-mac-addr` (e.g. for a MAC-locked node-locked license);
148
+ the interface exists only in the container's network namespace, so reusing the host NIC's MAC is safe.
149
+
150
+ ## After changing the config
151
+
152
+ | Change | Action |
153
+ |---|---|
154
+ | Directories, ports, passwords, MAC, mounts | `casperbox up` |
155
+ | `container.user`, or a different host user (UID/GID changed) | `casperbox build`, then `casperbox up` |
156
+
157
+ ## Development
158
+
159
+ ```
160
+ src/casperbox/
161
+ ├── cli.py Typer commands
162
+ ├── config.py casperbox.toml parsing and validation
163
+ ├── podman.py podman build/run arguments and container queries
164
+ ├── versions.py toolflow versions in assets/versions
165
+ ├── templates/ casperbox.toml template
166
+ └── assets/ build context: Dockerfiles, build scripts, rootfs, software.list
167
+ tests/ pytest tests
168
+ ```
169
+
170
+ ```bash
171
+ uv sync
172
+ uv run pytest
173
+ uv run casperbox --help
174
+ uv tool install -e . # installed casperbox uses this source tree
175
+ ```
176
+
177
+ Adding apt packages: add one per line to `assets/common/packages/software.list`, then `casperbox build`.
178
+
179
+ Adding a toolflow version: copy `assets/versions/m2021a` to `assets/versions/<new>`, edit
180
+ `toolflow.toml` (`TOOLFLOW_VERSION` must match the directory name) and the Dockerfile as needed.
181
+
182
+ The shell-based tool (`casper.sh`) is available at tag `v0.1.0`.
@@ -0,0 +1,27 @@
1
+ [project]
2
+ name = "casperbox"
3
+ version = "0.2.1"
4
+ description = "Build and run CASPER toolflow development containers with rootless podman"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ dependencies = [
8
+ "typer>=0.12",
9
+ ]
10
+
11
+ [project.scripts]
12
+ casperbox = "casperbox.cli:main"
13
+
14
+ [dependency-groups]
15
+ dev = [
16
+ "pytest>=8",
17
+ ]
18
+
19
+ [build-system]
20
+ requires = ["hatchling"]
21
+ build-backend = "hatchling.build"
22
+
23
+ [tool.hatch.build.targets.wheel]
24
+ packages = ["src/casperbox"]
25
+
26
+ [tool.pytest.ini_options]
27
+ testpaths = ["tests"]
@@ -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,8 @@
1
+ # casperbox: password login only, no root login
2
+ PasswordAuthentication yes
3
+ PubkeyAuthentication no
4
+ PermitRootLogin no
5
+ PermitEmptyPasswords no
6
+ UsePAM yes
7
+ X11Forwarding yes
8
+ PrintMotd no
@@ -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}"