4 Commits

10 changed files with 194 additions and 61 deletions
+1
View File
@@ -48,6 +48,7 @@ piscal
# Credential files (SECURITY - never commit these)
credentials.txt
passwords.txt
.piscal-build.env
*.secrets
*.key
*.pem
+4
View File
@@ -0,0 +1,4 @@
# Copy to .piscal-build.env and set your production password.
# .piscal-build.env is gitignored - never commit it.
#
# PISCAL_SSH_PASSWORD=your_secure_password
+22 -23
View File
@@ -29,12 +29,12 @@ RUN make
# Stage 2: Runtime stage - Create minimal application container
FROM ubuntu:latest
# Build arguments for configurable credentials and paths
# Build arguments for configurable credentials and paths (v1 VM layout)
ARG SSH_USERNAME=piscaladmin
ARG SSH_PASSWORD=piscaladmin
ARG SSH_GROUP=piscaladmin
ARG STORAGE_PATH=/home/piscaladmin/LeafWeb_storage
ARG PISCAL_EXECUTABLE=/srv/piscal
ARG PISCAL_EXECUTABLE=/home/piscaladmin/piscal_executable/piscal
# Install runtime dependencies only
RUN set -xe \
@@ -68,12 +68,13 @@ RUN set -xe \
RUN set -xe \
&& mkdir /run/sshd
# Ensure the job/workspace base under /srv is writable.
# The client uses `/srv/${PiscalDirectoryName}/input` and `PiscalDirectoryName`
# can itself be prefixed with `LeafWeb/...`.
# v1 VM layout: LeafWeb contains scripts + project directories
# Create LeafWeb (scripts and job dirs), piscal_executable, and storage
RUN set -xe \
&& mkdir -p /srv/LeafWeb \
&& chown -R ${SSH_USERNAME}:${SSH_GROUP} /srv/LeafWeb
&& mkdir -p /home/${SSH_USERNAME}/LeafWeb \
&& mkdir -p /home/${SSH_USERNAME}/piscal_executable \
&& chown -R ${SSH_USERNAME}:${SSH_GROUP} /home/${SSH_USERNAME}/LeafWeb \
&& chown -R ${SSH_USERNAME}:${SSH_GROUP} /home/${SSH_USERNAME}/piscal_executable
# Create storage directory structure with proper ownership
RUN set -xe \
@@ -81,25 +82,23 @@ RUN set -xe \
&& mkdir -p ${STORAGE_PATH}/output \
&& chown -R ${SSH_USERNAME}:${SSH_GROUP} ${STORAGE_PATH}
# Copy compiled executable from builder stage
COPY --from=builder /build/leafres/testrun/piscal /srv/piscal
# Copy compiled executable and scripts to staging dir (COPY can't use ARG in dest)
COPY --from=builder /build/leafres/testrun/piscal /tmp/piscal
COPY piscal-manager/piscal_launcher.sh piscal-manager/piscal_manager.sh piscal-manager/subdir_year.sh piscal-manager/README.txt /tmp/leafweb/
# Copy piscal-manager scripts (excluding .cfg, we'll generate it)
COPY piscal-manager/*.sh /srv/
COPY piscal-manager/README.txt /srv/
# Generate piscal_launcher.cfg with build-time parameters
# Install to user's home (supports custom SSH_USERNAME)
RUN set -xe \
&& echo "piscal_executable=\"${PISCAL_EXECUTABLE}\"" > /srv/piscal_launcher.cfg \
&& echo "storage_directory=\"${STORAGE_PATH}\"" >> /srv/piscal_launcher.cfg \
&& chown ${SSH_USERNAME}:${SSH_GROUP} /srv/piscal_launcher.cfg
&& cp /tmp/piscal /home/${SSH_USERNAME}/piscal_executable/piscal \
&& chown ${SSH_USERNAME}:${SSH_GROUP} /home/${SSH_USERNAME}/piscal_executable/piscal \
&& cp /tmp/leafweb/* /home/${SSH_USERNAME}/LeafWeb/ \
&& echo "piscal_executable=\"${PISCAL_EXECUTABLE}\"" > /home/${SSH_USERNAME}/LeafWeb/piscal_launcher.cfg \
&& echo "storage_directory=\"${STORAGE_PATH}\"" >> /home/${SSH_USERNAME}/LeafWeb/piscal_launcher.cfg \
&& chown ${SSH_USERNAME}:${SSH_GROUP} /home/${SSH_USERNAME}/LeafWeb/* \
&& find /home/${SSH_USERNAME}/LeafWeb -name "*.sh" -type f -exec sed -i 's/\r$//' {} \; \
&& chmod +x /home/${SSH_USERNAME}/LeafWeb/*.sh || true \
&& rm -rf /tmp/piscal /tmp/leafweb
# Fix Windows line endings (CRLF -> LF) for scripts and make scripts executable
RUN set -xe \
&& find /srv -name "*.sh" -type f -exec sed -i 's/\r$//' {} \; \
&& chmod +x /srv/*.sh || true
WORKDIR /srv
WORKDIR /home/${SSH_USERNAME}/LeafWeb
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
+38 -13
View File
@@ -64,16 +64,26 @@ The Dockerfile accepts these build arguments if you need to customize:
| `SSH_PASSWORD` | `piscaladmin` | SSH password for container access |
| `SSH_GROUP` | `piscaladmin` | Primary group for SSH user |
| `STORAGE_PATH` | `/home/piscaladmin/LeafWeb_storage` | Storage directory for PISCAL data |
| `PISCAL_EXECUTABLE` | `/srv/piscal` | Path to PISCAL executable |
| `PISCAL_EXECUTABLE` | `/home/piscaladmin/piscal_executable/piscal` | Path to PISCAL executable |
### Storage Directory Structure
### v1 Directory Layout (VM-compatible)
The storage directory is automatically created with:
The image uses the v1 layout expected by the LeafWeb client:
```
/home/piscaladmin/LeafWeb_storage/
├── input/ # Input files for processing
└── output/ # Results from PISCAL processing
/home/piscaladmin/
├── LeafWeb/ # Scripts + project directories
│ ├── piscal_launcher.cfg
│ ├── piscal_launcher.sh
│ ├── piscal_manager.sh
│ ├── subdir_year.sh
│ ├── README.txt
│ └── <project_name>/ # Job dirs (e.g. 280_CinnamomumbodinieriLévl)
├── LeafWeb_storage/
│ ├── input/
│ └── output/
└── piscal_executable/
└── piscal
```
### Port Mapping
@@ -84,16 +94,31 @@ The storage directory is automatically created with:
## Advanced Usage
### Custom Credentials at Build Time
### Baking In a Production Password
If you need different credentials, use Docker build arguments:
To use a custom password without passing it on the command line:
**Option 1: `.piscal-build.env` (recommended)**
```bash
docker build \
--build-arg SSH_USERNAME=customuser \
--build-arg SSH_PASSWORD=custompass \
-t piscal:custom \
.
cp .piscal-build.env.example .piscal-build.env
# Edit .piscal-build.env and set: PISCAL_SSH_PASSWORD=your_secure_password
./build-docker.sh # or .\build-docker.ps1
```
The build scripts automatically load `.piscal-build.env` (gitignored) and pass the password to the Docker build.
**Option 2: Environment variable**
```bash
export PISCAL_SSH_PASSWORD="your_secure_password"
./build-docker.sh
```
**Option 3: Direct build-arg**
```bash
docker build --build-arg SSH_PASSWORD=custompass -t piscal:custom .
```
### Custom Storage Path
+59
View File
@@ -0,0 +1,59 @@
# v1 VM Deployment (LeafWeb Layout)
This branch configures PISCAL for deployment on a VM matching the layout used by `piscal.eastus.cloudapp.azure.com`, so the LeafWeb client can access jobs and storage at the expected paths.
## Directory Layout
```
/home/piscaladmin/
├── LeafWeb/ # Scripts + project directories
│ ├── piscal_launcher.cfg # Config (piscal_executable, storage paths)
│ ├── piscal_launcher.sh
│ ├── piscal_manager.sh
│ ├── subdir_year.sh
│ ├── README.txt
│ ├── 280_CinnamomumbodinieriLévl/ # Project dirs (input/, output/, run/, etc.)
│ ├── 311_AnnaAsaday3high/
│ └── ...
├── LeafWeb_storage/ # Shared storage for client
│ ├── input/
│ └── output/
├── piscal/ # Source (optional)
└── piscal_executable/ # Compiled binary
└── piscal
```
## Deployment
**Docker (recommended):** The Docker image uses this layout by default. See [README-Docker.md](README-Docker.md).
**Manual VM deployment:** Copy scripts to LeafWeb and the compiled `piscal` binary to `piscal_executable/`:
```bash
ssh piscaladmin@host 'mkdir -p ~/LeafWeb ~/piscal_executable ~/LeafWeb_storage/input ~/LeafWeb_storage/output'
scp piscal-manager/*.cfg piscal-manager/*.sh piscal-manager/README.txt piscaladmin@host:~/LeafWeb/
scp leafres/testrun/piscal piscaladmin@host:~/piscal_executable/
ssh piscaladmin@host 'chmod +x ~/LeafWeb/*.sh'
```
## Configuration
`piscal_launcher.cfg` uses VM paths:
- `piscal_executable="/home/piscaladmin/piscal_executable/piscal"`
- `storage_directory="/home/piscaladmin/LeafWeb_storage"`
Adjust if your VM uses different locations.
## Running Jobs
From `~/LeafWeb`:
```bash
cd ~/LeafWeb
./piscal_manager.sh -d 280_CinnamomumbodinieriLévl -s -p C3_photosynthesis_leafweb
./piscal_manager.sh -d 280_CinnamomumbodinieriLévl # status
./piscal_manager.sh -d 280_CinnamomumbodinieriLévl -c # cleanup
```
The `-d` argument is the project directory name (a subdir of LeafWeb).
+2
View File
@@ -27,6 +27,8 @@ ssh -p 2222 piscaladmin@localhost
# Password: piscaladmin
```
For production builds with a custom password, copy `.piscal-build.env.example` to `.piscal-build.env` and set `PISCAL_SSH_PASSWORD`. See [README-Docker.md](README-Docker.md).
### Full Docker Documentation
See [README-Docker.md](README-Docker.md) for complete Docker build and deployment documentation, including:
+3
View File
@@ -0,0 +1,3 @@
# TODO
- [ ] **LeafWeb_storage sunset** Migrate away from the LeafWeb_storage directory (input/output files) to SQL-backed storage. Data can be reconstituted from SQL as needed.
+28 -8
View File
@@ -3,6 +3,15 @@
$ErrorActionPreference = "Stop"
# Load password from .piscal-build.env if it exists (gitignored)
if (Test-Path .piscal-build.env) {
Get-Content .piscal-build.env | ForEach-Object {
if ($_ -match '^\s*([^#][^=]+)=(.*)$') {
[Environment]::SetEnvironmentVariable($matches[1].Trim(), $matches[2].Trim(), 'Process')
}
}
}
# Generate version tag: YYYYMMDD-gitsha
$DateTag = Get-Date -Format "yyyyMMdd"
$GitSha = (git rev-parse --short HEAD).Trim()
@@ -12,12 +21,15 @@ Write-Host "Building PISCAL Docker image..." -ForegroundColor Cyan
Write-Host "Version: $Version" -ForegroundColor Cyan
Write-Host ""
# Build with version tag and latest tag (using default ARGs for dev)
docker build `
-t "piscal:$Version" `
-t piscal:latest `
-t piscal:dev `
.
# Build args: use PISCAL_SSH_PASSWORD if set (from env or .piscal-build.env)
$BuildArgs = @("-t", "piscal:$Version", "-t", "piscal:latest", "-t", "piscal:dev")
if ($env:PISCAL_SSH_PASSWORD) {
$BuildArgs += "--build-arg", "SSH_PASSWORD=$($env:PISCAL_SSH_PASSWORD)"
}
if ($env:PISCAL_BUILD_NO_CACHE) {
$BuildArgs += "--no-cache"
}
docker build @BuildArgs .
if ($LASTEXITCODE -eq 0) {
Write-Host ""
@@ -26,13 +38,21 @@ if ($LASTEXITCODE -eq 0) {
Write-Host " - piscal:latest" -ForegroundColor Green
Write-Host " - piscal:dev" -ForegroundColor Green
Write-Host ""
Write-Host "Default credentials:" -ForegroundColor Cyan
if ($env:PISCAL_SSH_PASSWORD) {
Write-Host "Credentials (from PISCAL_SSH_PASSWORD / .piscal-build.env):" -ForegroundColor Cyan
Write-Host " Username: piscaladmin" -ForegroundColor Cyan
Write-Host " Password: (custom)" -ForegroundColor Cyan
} else {
Write-Host "Default credentials (v1 layout):" -ForegroundColor Cyan
Write-Host " Username: piscaladmin" -ForegroundColor Cyan
Write-Host " Password: piscaladmin" -ForegroundColor Cyan
}
Write-Host " LeafWeb: /home/piscaladmin/LeafWeb (scripts + project dirs)" -ForegroundColor Cyan
Write-Host " Storage: /home/piscaladmin/LeafWeb_storage" -ForegroundColor Cyan
Write-Host " Executable: /home/piscaladmin/piscal_executable/piscal" -ForegroundColor Cyan
Write-Host ""
Write-Host "To run: docker run -d -p 2222:22 --name piscal-server piscal:latest" -ForegroundColor Yellow
Write-Host "To SSH: ssh -p 2222 piscaladmin@localhost (password: piscaladmin)" -ForegroundColor Yellow
Write-Host "To SSH: ssh -p 2222 piscaladmin@localhost" -ForegroundColor Yellow
} else {
Write-Host "Build failed!" -ForegroundColor Red
exit $LASTEXITCODE
+25 -8
View File
@@ -3,6 +3,13 @@
set -e
# Load password from .piscal-build.env if it exists (gitignored)
if [ -f .piscal-build.env ]; then
set -a
source .piscal-build.env
set +a
fi
# Generate version tag: YYYYMMDD-gitsha
DATE_TAG=$(date +%Y%m%d)
GIT_SHA=$(git rev-parse --short HEAD)
@@ -12,12 +19,14 @@ echo "Building PISCAL Docker image..."
echo "Version: ${VERSION}"
echo ""
# Build with version tag and latest tag (using default ARGs for dev)
docker build \
-t piscal:${VERSION} \
-t piscal:latest \
-t piscal:dev \
.
# Build args: use PISCAL_SSH_PASSWORD if set (from env or .piscal-build.env)
BUILD_ARGS=(-t "piscal:${VERSION}" -t piscal:latest -t piscal:dev)
if [ -n "${PISCAL_SSH_PASSWORD:-}" ]; then
BUILD_ARGS+=(--build-arg "SSH_PASSWORD=${PISCAL_SSH_PASSWORD}")
fi
[ -n "${PISCAL_BUILD_NO_CACHE:-}" ] && BUILD_ARGS+=(--no-cache)
docker build "${BUILD_ARGS[@]}" .
echo ""
echo "Successfully built:"
@@ -25,10 +34,18 @@ echo " - piscal:${VERSION}"
echo " - piscal:latest"
echo " - piscal:dev"
echo ""
echo "Default credentials:"
if [ -n "${PISCAL_SSH_PASSWORD:-}" ]; then
echo "Credentials (from PISCAL_SSH_PASSWORD / .piscal-build.env):"
echo " Username: piscaladmin"
echo " Password: (custom)"
else
echo "Default credentials (v1 layout):"
echo " Username: piscaladmin"
echo " Password: piscaladmin"
fi
echo " LeafWeb: /home/piscaladmin/LeafWeb (scripts + project dirs)"
echo " Storage: /home/piscaladmin/LeafWeb_storage"
echo " Executable: /home/piscaladmin/piscal_executable/piscal"
echo ""
echo "To run: docker run -d -p 2222:22 --name piscal-server piscal:latest"
echo "To SSH: ssh -p 2222 piscaladmin@localhost (password: piscaladmin)"
echo "To SSH: ssh -p 2222 piscaladmin@localhost"
+8 -5
View File
@@ -1,7 +1,10 @@
# NOTE: This file is for reference only when using non-Docker deployments.
# For Docker builds, this file is generated dynamically at build time from
# Dockerfile ARG values (see Dockerfile). The Docker-generated version will
# use the configured SSH_USERNAME and STORAGE_PATH build arguments.
# v1 VM-compatible configuration
# Deploy this file to /home/piscaladmin/LeafWeb/ alongside piscal_launcher.sh,
# piscal_manager.sh, and subdir_year.sh. Project directories (e.g. 280_*,
# 311_*) live as subdirs of LeafWeb.
#
# For Docker builds, this file is NOT used; the Dockerfile generates
# Docker builds generate this file in LeafWeb at build time.
piscal_executable="/srv/piscal"
piscal_executable="/home/piscaladmin/piscal_executable/piscal"
storage_directory="/home/piscaladmin/LeafWeb_storage"