Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Additions, amendments and contributions for additional workflows are most welcom

The easiest way to launch a new environment is to use Docker Compose.

```
```sh
cd docker
docker compose up
```
Expand All @@ -35,7 +35,7 @@ The following environment variables are available when using Docker Compose:

| Environment Variable | Default |
| -------------------- |----------|
| `OS_VERSION` | bullseye |
| `OS_VERSION` | trixie |
| `WEB_HTTP_PORT` | 8080 |
| `BACKEND_HOST` | backend |
| `BACKEND_PORT` | 6868 |
Expand All @@ -46,17 +46,18 @@ The following environment variables are available when using Docker Compose:

**Examples:**

Run Debian "bullseye":
```
OS_VERSION=bullseye docker compose up
Run Debian "trixie":

```sh
OS_VERSION=trixie docker compose up
```

The Docker entrypoint generates an ephemeral session key for local development.
Set `SESSION_KEY` yourself if browser sessions must survive a container restart.

Run the Go web-client test suite with:

```
```sh
docker compose --profile webui-tests run --rm go-test
```

Expand All @@ -66,9 +67,8 @@ When using Docker Compose the following volumes will be mounted automatically:

| Local Path | Container Path |
| ----------------------- | ------------------------ |
| docker/volumes/images/ | /home/pi/images/ |
| docker/volumes/config/ | /home/pi/.config/piscsi/ |

| docker/volumes/images/ | /var/lib/piscsi/images/ |
| docker/volumes/config/ | /var/lib/piscsi/config/ |

## How To

Expand All @@ -77,15 +77,15 @@ When using Docker Compose the following volumes will be mounted automatically:
You should rebuild the container images after checking out a different version of
PiSCSI or making changes to the Go web client or its runtime dependencies.

```
```sh
docker compose up --build
```

### Open a Shell on a Running Container

Run the following command, replacing `[CONTAINER]` with `backend` or `web`.

```
```sh
docker compose exec [CONTAINER] bash
```

Expand All @@ -98,7 +98,8 @@ The web binary embeds templates and static assets, so rebuild and restart the
`web` service after editing Go web-client files.

**Example:**
```

```yaml
services:
go-test:
volumes:
Expand All @@ -110,6 +111,6 @@ services:
This can be useful for testing, but there are some caveats, e.g. the PiSCSI and the
web UI will be accessing separate `images` directories.

```
```sh
BACKEND_HOST=foo BACKEND_PASSWORD=bar docker compose up
```
8 changes: 4 additions & 4 deletions docker/backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ARG DEBIAN_FRONTEND=noninteractive

FROM debian:bullseye AS build
FROM debian:trixie AS build
RUN apt-get update && apt-get install --assume-yes --no-install-recommends sudo
RUN groupadd pi \
&& useradd --create-home --shell /bin/bash -g pi pi \
Expand All @@ -15,14 +15,14 @@ COPY --chown=pi:pi doc doc
COPY --chown=pi:pi proto proto
RUN ./easyinstall.sh --run_choice=15 --cores=`nproc`

FROM debian:bullseye-slim AS runner
FROM debian:trixie-slim AS runner
USER root
WORKDIR /home/pi

COPY --from=build /home/pi/piscsi/cpp/bin/* /usr/local/bin/
COPY docker/backend/piscsi_wrapper.sh /usr/local/bin/piscsi_wrapper.sh
RUN chmod +x /usr/local/bin/*
RUN mkdir -p /home/pi/images
RUN mkdir -p /var/lib/piscsi/images /var/lib/piscsi/config

RUN apt-get update \
&& apt-get install --no-install-recommends --assume-yes libpcap-dev libprotobuf-dev \
Expand All @@ -31,7 +31,7 @@ RUN apt-get update \
&& rm -rf /var/lib/apt/lists/*

EXPOSE 6868
ENTRYPOINT ["/usr/local/bin/piscsi_wrapper.sh", "-r", "7", "-F", "/home/pi/images"]
ENTRYPOINT ["/usr/local/bin/piscsi_wrapper.sh", "-r", "7", "-F", "/var/lib/piscsi/images"]
CMD ["-L", "trace"]

HEALTHCHECK --interval=5m --timeout=1s CMD scsictl -v
4 changes: 2 additions & 2 deletions docker/backend/piscsi_wrapper.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/usr/bin/env bash

if [[ $BACKEND_PASSWORD ]]; then
TOKEN_FILE="/home/pi/.config/piscsi/piscsi_secret"
mkdir -p /home/pi/.config/piscsi || true
TOKEN_FILE="/var/lib/piscsi/config/piscsi_secret"
mkdir -p /var/lib/piscsi/config || true
echo $BACKEND_PASSWORD > $TOKEN_FILE
chmod 700 $TOKEN_FILE
/usr/local/bin/piscsi "$@" -P $TOKEN_FILE
Expand Down
12 changes: 6 additions & 6 deletions docker/docker-compose.ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ services:
dockerfile: docker/backend/Dockerfile
init: true
volumes:
- ./volumes/images:/home/pi/images:delegated
- ./volumes/images:/var/lib/piscsi/images:delegated
healthcheck:
interval: 5s
start_period: 5s
Expand All @@ -27,18 +27,18 @@ services:
context: ..
dockerfile: docker/web/Dockerfile
args:
- OS_VERSION=bullseye
- OS_VERSION=trixie
volumes:
- ./volumes/images:/home/pi/images:delegated
- ./volumes/images:/var/lib/piscsi/images:delegated
user: "${PISCSI_DOCKER_UID:-1000}:${PISCSI_DOCKER_GID:-1000}"
init: true
environment:
PISCSI_HOST: mock-backend
PISCSI_PORT: 6868
SERVER_PORT: 8080
BASE_DIR: /home/pi/images
SHARED_DIR: /home/pi/shared_files
CONFIG_DIR: /home/pi/.config/piscsi
BASE_DIR: /var/lib/piscsi/images
SHARED_DIR: /var/lib/piscsi/shared
CONFIG_DIR: /var/lib/piscsi/config
healthcheck:
interval: 5s
start_period: 5s
Expand Down
16 changes: 8 additions & 8 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ services:
context: ..
dockerfile: docker/backend/Dockerfile
volumes:
- ./volumes/images:/home/pi/images:delegated
- ./volumes/config:/home/pi/.config/piscsi:delegated
- ./volumes/images:/var/lib/piscsi/images:delegated
- ./volumes/config:/var/lib/piscsi/config:delegated
ports:
- "127.0.0.1:${BACKEND_PORT:-6868}:6868"
environment:
Expand All @@ -27,20 +27,20 @@ services:
context: ..
dockerfile: docker/web/Dockerfile
args:
- OS_VERSION=${OS_VERSION:-bullseye}
- OS_VERSION=${OS_VERSION:-trixie}
volumes:
- ./volumes/images:/home/pi/images:delegated
- ./volumes/config:/home/pi/.config/piscsi:delegated
- ./volumes/images:/var/lib/piscsi/images:delegated
- ./volumes/config:/var/lib/piscsi/config:delegated
ports:
- "127.0.0.1:${WEB_HTTP_PORT:-8080}:8080"
environment:
PISCSI_HOST: ${BACKEND_HOST:-backend}
PISCSI_PORT: ${BACKEND_PORT:-6868}
PISCSI_TOKEN: ${BACKEND_PASSWORD:-}
SERVER_PORT: 8080
BASE_DIR: /home/pi/images
SHARED_DIR: /home/pi/shared_files
CONFIG_DIR: /home/pi/.config/piscsi
BASE_DIR: /var/lib/piscsi/images
SHARED_DIR: /var/lib/piscsi/shared
CONFIG_DIR: /var/lib/piscsi/config
SESSION_KEY: ${SESSION_KEY:-}
user: "${PISCSI_DOCKER_UID:-1000}:${PISCSI_DOCKER_GID:-1000}"
init: true
Expand Down
2 changes: 1 addition & 1 deletion docker/go-test/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ARG GO_VERSION=1.25.13

FROM golang:${GO_VERSION}-bookworm
FROM golang:${GO_VERSION}-trixie

WORKDIR /src

Expand Down
22 changes: 9 additions & 13 deletions docker/web/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ARG GO_VERSION=1.25.13
ARG OS_VERSION=bullseye
ARG OS_VERSION=trixie

FROM golang:${GO_VERSION}-bookworm AS build
FROM golang:${GO_VERSION}-trixie AS build

WORKDIR /src

Expand Down Expand Up @@ -31,7 +31,6 @@ RUN apt-get update \
disktype \
dosfstools \
genisoimage \
hfsutils \
kpartx \
man2html \
openssl \
Expand All @@ -43,22 +42,19 @@ RUN apt-get update \
RUN groupadd --system pi \
&& useradd --system --create-home --home-dir /home/pi --shell /usr/sbin/nologin --gid pi pi \
&& install -d --owner=pi --group=pi --mode=0777 \
/home/pi/images \
/home/pi/shared_files \
/home/pi/.config/piscsi \
&& install -d --owner=pi --group=pi \
/home/pi/web/templates \
/home/pi/web/static
/var/lib/piscsi/images \
/var/lib/piscsi/shared \
/var/lib/piscsi/config \
&& install -d --mode=0755 /opt/piscsi-web

COPY --from=build /out/piscsi-web /usr/local/bin/piscsi-web
COPY --from=build /out/mock-piscsi /usr/local/bin/mock-piscsi
COPY --from=build /src/go/piscsi-web/drive_properties.json /home/pi/drive_properties.json
COPY --from=build /src/go/piscsi-web/drive_properties.json /opt/piscsi-web/drive_properties.json
COPY docker/web/web_start_wrapper.sh /usr/local/bin/web_start_wrapper.sh
RUN chown pi:pi /home/pi/drive_properties.json \
&& chmod 0755 /usr/local/bin/piscsi-web /usr/local/bin/mock-piscsi /usr/local/bin/web_start_wrapper.sh
RUN chmod 0755 /usr/local/bin/piscsi-web /usr/local/bin/mock-piscsi /usr/local/bin/web_start_wrapper.sh

USER pi
WORKDIR /home/pi
WORKDIR /opt/piscsi-web

EXPOSE 8080
ENTRYPOINT ["/usr/local/bin/web_start_wrapper.sh"]
Expand Down
8 changes: 4 additions & 4 deletions go/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,29 +59,29 @@ mock: proto
@echo "Run with: ./$(MOCK_BINARY)"

build-linux-arm64: proto
@echo "Building for ARM64 (Raspberry Pi 4/5)..."
@echo "Building for ARM64..."
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 \
$(GOBUILD) $(WEB_TAG_FLAGS) $(WEB_LDFLAGS) -o $(BINARY_NAME)-arm64 ./piscsi-web/cmd/piscsi-web
@echo "✅ ARM64 binary created"
@ls -lh $(BINARY_NAME)-arm64

build-linux-armv7: proto
@echo "Building for ARMv7 (Raspberry Pi 2/3)..."
@echo "Building for ARMv7..."
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 \
$(GOBUILD) $(WEB_TAG_FLAGS) $(WEB_LDFLAGS) -o $(BINARY_NAME)-armv7 ./piscsi-web/cmd/piscsi-web
@echo "✅ ARMv7 binary created"
@ls -lh $(BINARY_NAME)-armv7

build-linux-arm64-static: proto
@echo "Building static ARM64 binary (Raspberry Pi 4/5)..."
@echo "Building static ARM64 binary..."
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 \
$(GOBUILD) $(STATIC_WEB_TAG_FLAGS) $(STATIC_WEB_LDFLAGS) -o $(BINARY_NAME)-arm64-static ./piscsi-web/cmd/piscsi-web
@echo "✅ Static ARM64 binary created: $(BINARY_NAME)-arm64-static"
@file $(BINARY_NAME)-arm64-static
@ls -lh $(BINARY_NAME)-arm64-static

build-linux-armv7-static: proto
@echo "Building static ARMv7 binary (Raspberry Pi 2/3)..."
@echo "Building static ARMv7 binary..."
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 \
$(GOBUILD) $(STATIC_WEB_TAG_FLAGS) $(STATIC_WEB_LDFLAGS) -o $(BINARY_NAME)-armv7-static ./piscsi-web/cmd/piscsi-web

Expand Down
25 changes: 22 additions & 3 deletions go/piscsi-web/internal/server/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ func (s *Server) handleIndex(c *gin.Context) {
data["ShowUnits"] = showUnits
data["Files"] = files
data["FilesBySubdir"] = filesBySubdir
data["SharedFiles"] = sharedFiles(s.config.SharedDir)
data["ImageDir"] = s.config.BaseDir
data["ImageDirExists"] = imageDirExists
data["ImageRootDir"] = s.config.BaseDir
Expand Down Expand Up @@ -1308,7 +1309,7 @@ func (s *Server) handleFilesUpload(c *gin.Context) {

s.logger.Info("File uploaded", "filename", filename, "size", fileSize, "destination", filepath.Dir(fullPath))
s.respond(c, ResponseOptions{
Message: "File uploaded successfully",
Message: fmt.Sprintf("File %q uploaded successfully to %q", filename, filepath.Dir(fullPath)),
RedirectURL: "/upload",
})
}
Expand Down Expand Up @@ -3128,6 +3129,24 @@ func transferSubdirectories(root string) []string {
return subdirectories
}

// sharedFiles returns the visible regular files directly in the shared
// directory. These are available as sources when creating CD-ROM images.
func sharedFiles(root string) []string {
entries, err := os.ReadDir(root)
if err != nil {
return []string{}
}

files := make([]string, 0, len(entries))
for _, entry := range entries {
if strings.HasPrefix(entry.Name(), ".") || !entry.Type().IsRegular() {
continue
}
files = append(files, entry.Name())
}
return files
}

// displays disk image information
func (s *Server) handleFilesDiskinfo(c *gin.Context) {
fileName := c.PostForm("file_name")
Expand Down Expand Up @@ -3502,9 +3521,9 @@ func (s *Server) handleFilesCreateISO(c *gin.Context) {
isoPath, err = resolvePathWithin(s.config.BaseDir, fileName+".iso")
}
} else {
sourcePath, err = resolvePathWithin(s.config.BaseDir, localFile)
sourcePath, err = resolvePathWithin(s.config.SharedDir, localFile)
if err == nil {
isoPath, err = resolvePathWithin(s.config.BaseDir, localFile+".iso")
isoPath, err = resolvePathWithin(s.config.BaseDir, filepath.Base(localFile)+".iso")
}
}
if err != nil {
Expand Down
Loading