Skip to content
Open
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
31 changes: 23 additions & 8 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
FROM mcr.microsoft.com/devcontainers/base:bookworm
FROM mcr.microsoft.com/devcontainers/base:trixie

# taken from: https://github.com/LMS-Community/slimserver-platforms/blob/public/9.1/Docker/Dockerfile
# Aligned with https://github.com/LMS-Community/slimserver-platforms/blob/public/9.2/Docker/Dockerfile

# Set environment variables
ENV DEBIAN_FRONTEND=noninteractive
ENV LC_ALL="C.UTF-8" LANG="en_US.UTF-8" LANGUAGE="en_US.UTF-8"

ENV HTTP_PORT=9000

# Install packages
RUN sudo apt-get update -qq && \
sudo apt-get install --no-install-recommends -qy procps psmisc wget curl perl tzdata libcrypt-blowfish-perl libwww-perl libfont-freetype-perl liblinux-inotify2-perl \
libdata-dump-perl libio-socket-ssl-perl libnet-ssleay-perl libcrypt-ssleay-perl libcrypt-openssl-rsa-perl libssl-dev libgomp1 libasound2 lame opus-tools && \
sudo apt-get clean -qy && \
sudo rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN apt-get update -qq && \
apt-get install --no-install-recommends -qy \
# Lyrion runtime dependencies
procps psmisc wget curl perl tzdata libcrypt-blowfish-perl libwww-perl libfont-freetype-perl liblinux-inotify2-perl \
libdata-dump-perl libio-socket-ssl-perl libnet-ssleay-perl libcrypt-ssleay-perl libcrypt-openssl-rsa-perl libssl-dev libgomp1 libasound2 lame opus-tools \
# Perl Language Server dependencies (for "richterger.perl" VS Code extension)
cpanminus \
libanyevent-perl libclass-refresh-perl libcompiler-lexer-perl libdata-dump-perl libio-aio-perl libjson-perl libmoose-perl libpadwalker-perl \
libscalar-list-utils-perl libcoro-perl && \
apt-get clean -qy && \
rm -rf /var/lib/apt/lists/*

# Volume and port setup
# Permissions allow the non-root Dev Container user (vscode) to write here
# when no host folder is mounted (e.g. GitHub Codespaces).
RUN mkdir -p /music /playlist && \
chmod 777 /music /playlist

# Install Perl::LanguageServer (for "richterger.perl" VS Code extension)
RUN cpanm --notest --quiet Perl::LanguageServer
38 changes: 38 additions & 0 deletions .devcontainer/clean-folders.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env bash
# Cleans runtime-generated folders.

set -euo pipefail

readonly FORCE="${FORCE:-0}"
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"

# Runtime-generated subdirectories (Cache, Logs, prefs)
readonly FOLDERS_TO_CLEAN=(
"$REPO_ROOT/prefs"
"$REPO_ROOT/Logs"
"$REPO_ROOT/Cache"
)

if [[ "$FORCE" != "1" ]]; then
echo "[INFO] The following folders would be deleted:"
for folder in "${FOLDERS_TO_CLEAN[@]}"; do
if [[ -d "$folder" ]]; then
echo "[INFO] $folder/ (exists)"
else
echo "[INFO] $folder/ (not found, skipped)"
fi
done
echo "[INFO] Re-run with FORCE=1 to continue"
exit 0
fi

DELETED=0
for folder in "${FOLDERS_TO_CLEAN[@]}"; do
if [[ -d "$folder" ]]; then
echo "[INFO] Deleting $folder/"
rm -rf "$folder"
DELETED=$((DELETED + 1))
fi
done

echo "[INFO] Cleanup complete ($DELETED folder(s) removed)"
130 changes: 98 additions & 32 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,36 +1,102 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/debian
{
"name": "Lyrion Debian devcontainer",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
//"image": "mcr.microsoft.com/devcontainers/base:bookworm",
"dockerComposeFile": "docker-compose.yml",
"service": "lyrion-devcontainer",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [
9000,
3483,
9090
],
"portsAttributes": {
"9000": {
"label": "web interface",
"protocol": "http"
},
"3483": {
"label": "SlimProto"
},
"9090": {
"label": "CLI"
}
},
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "/workspaces/slimserver/.devcontainer/post-create.sh"
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
"name": "Lyrion Debian",

// You can use "Docker Compose file" or "Dockerfile" to build the container, but not both.
// ----------------------------------------------------
// 1) Docker Compose file
"dockerComposeFile": "docker-compose.yml",
"service": "lyrion-devcontainer",
// ----------------------------------------------------
// 2) Dockerfile
// Solves cross-drive path problem with Podman and podman compose on Windows:
// When Dev Containers adds features, it generates a temporary Dockerfile on the C: drive. When workspace is on D: drive, podman compose can't resolve relative paths across drives.
// "build": {
// "dockerfile": "Dockerfile",
// "context": "."
// },
// "runArgs": [
// "--network=lyrion_bridge",
// "--hostname=lyrion-devcontainer"
// ],
// ----------------------------------------------------

"containerEnv": {
"AUTO_START_LMS": "false" // Set to "true" to automatically start Lyrion Media Server when the container starts
// Optional startup variables (uncomment and adjust as needed):
// "LMS_EXTRA_ARGS": "--advertiseaddr=192.168.1.100"
},

// Mount host folders into the container.
// Uncomment and adjust the source paths to match your host system before (re)building the container.
// "mounts": [
// { "type": "bind", "source": "/path/to/your/music", "target": "/music" },
// { "type": "bind", "source": "/path/to/your/playlist", "target": "/playlist" }
// ],

// Dev Containers mounts the opened repository under /workspaces/<repo> by default.
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [
9000,
3483,
9090
],
"portsAttributes": {
"9000": {
"label": "Web interface",
"protocol": "http"
},
"3483": {
"label": "SlimProto"
},
"9090": {
"label": "CLI"
}
},

// initializeCommand runs on the HOST before the container starts (Windows or Unix).
// bash must be available: Git Bash / WSL2 on Windows, or native bash on Unix.
"initializeCommand": "bash .devcontainer/initialize.sh",

"postCreateCommand": "bash .devcontainer/post-create.sh",

"postStartCommand": "bash .devcontainer/post-start.sh",

// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"EditorConfig.EditorConfig",
"richterger.perl"
Comment thread
michaelherger marked this conversation as resolved.
],
"settings": {
"perl.enable": true, // Set to false to disable the Perl extension and language server features
"perl.env": {
"PERL5OPT": "-Mlib=/workspaces/slimserver/.vscode -MPerlLanguageServerBootstrap",
"PERL5LIB": "/workspaces/slimserver:/workspaces/slimserver/lib"
},
"perl.perlCmd": "/usr/bin/perl",
"perl.perlArgs": [
"-Mlib=/workspaces/slimserver/.vscode",
"-MPerlLanguageServerBootstrap"
],
"perl.logLevel": 0,
"perl.pathMap": [],
"perl.perlInc": [
"/workspaces/slimserver/.vscode",
"/workspaces/slimserver",
"/workspaces/slimserver/lib"
]
}
}
}

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
16 changes: 9 additions & 7 deletions .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
version: '3.11'

services:
lyrion-devcontainer:
# add this line so we can connect to the host machine
hostname: lyrion-devcontainer
build:
context: .
dockerfile: Dockerfile
volumes:
- lyrion-dev-volume:/workspace

# In Compose mode, Dev Containers does not auto-mount the workspace —
# this explicit mount is required.
- ../..:/workspaces:cached
# Overrides default command so things don't shut down after the process ends.
command: sleep infinity
networks:
- lyrion_bridge

volumes:
lyrion-dev-volume:
networks:
lyrion_bridge:
external: true
74 changes: 74 additions & 0 deletions .devcontainer/engine-utils.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env bash
# Shared helpers to detect a container engine command usable from shell scripts.

# Finds a container engine (podman or docker), preferring podman.
# Returns the command name or exits with error.
find_container_engine() {
# Native Linux/macOS shell lookup
if command -v podman >/dev/null 2>&1; then
echo "podman"
return 0
fi
if command -v docker >/dev/null 2>&1; then
echo "docker"
return 0
fi

# Windows executables may only be visible as *.exe from Git Bash/WSL
if command -v podman.exe >/dev/null 2>&1; then
echo "podman.exe"
return 0
fi
if command -v docker.exe >/dev/null 2>&1; then
echo "docker.exe"
return 0
fi

# Fallback via where.exe when command -v does not see Windows PATH entries
if command -v where.exe >/dev/null 2>&1; then
local resolved
resolved="$(where.exe podman 2>/dev/null | tr -d '\r' | head -n 1 || true)"
if [[ -n "$resolved" ]]; then
echo "$resolved"
return 0
fi
resolved="$(where.exe docker 2>/dev/null | tr -d '\r' | head -n 1 || true)"
if [[ -n "$resolved" ]]; then
echo "$resolved"
return 0
fi
fi

return 1
}

# Finds a container engine that supports the 'compose' subcommand.
# On Windows / Git Bash the plain 'podman' may be a shim without compose support,
# while 'podman.exe' works correctly — this function tests each candidate in order.
find_compose_engine() {
local candidates=()

# Build the candidate list: prefer plain names, then .exe variants
for name in podman docker; do
command -v "$name" >/dev/null 2>&1 && candidates+=("$name")
command -v "$name.exe" >/dev/null 2>&1 && candidates+=("$name.exe")
done

# where.exe fallback for Git Bash / MSYS environments
if command -v where.exe >/dev/null 2>&1; then
for name in podman docker; do
local resolved
resolved="$(where.exe "$name" 2>/dev/null | tr -d '\r' | head -n 1 || true)"
[[ -n "$resolved" ]] && candidates+=("$resolved")
done
fi

for candidate in "${candidates[@]}"; do
if "$candidate" compose version >/dev/null 2>&1; then
echo "$candidate"
return 0
fi
done

return 1
}
32 changes: 32 additions & 0 deletions .devcontainer/initialize.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# Creates the shared network for the Dev Container and SoftSqueeze.

set -euo pipefail

readonly NETWORK_NAME="lyrion_bridge"
ENGINE=""

source "$(dirname "$0")/engine-utils.sh"

ENGINE="$(find_container_engine || true)"

if [[ -z "$ENGINE" ]]; then
echo "[ERROR] Missing container engine (podman or docker)." >&2
echo "[ERROR] Make sure it is installed and available in the shell PATH used by initializeCommand." >&2
exit 1
fi

echo "[INFO] Using container engine: $ENGINE"

if "$ENGINE" network inspect "$NETWORK_NAME" >/dev/null 2>&1; then
echo "[INFO] Network '$NETWORK_NAME' already exists, skipping creation."
exit 0
fi

echo "[INFO] Creating network '$NETWORK_NAME'..."
if "$ENGINE" network create "$NETWORK_NAME" --driver=bridge; then
echo "[INFO] Network '$NETWORK_NAME' created successfully."
else
echo "[ERROR] Failed to create network '$NETWORK_NAME'." >&2
exit 1
fi
36 changes: 20 additions & 16 deletions .devcontainer/post-create.sh
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
#!/bin/bash
set -e
#!/usr/bin/env bash
# Downloads Slim/Utils/OS/Custom.pm from slimserver-platforms.

# get current git branch
BRANCH="$(git rev-parse --abbrev-ref HEAD)"
set -euo pipefail

URL_BRANCH="https://raw.githubusercontent.com/LMS-Community/slimserver-platforms/${BRANCH}/Docker/Slim-Utils-OS-Custom.pm"
URL_HEAD="https://raw.githubusercontent.com/LMS-Community/slimserver-platforms/HEAD/Docker/Slim-Utils-OS-Custom.pm"
TARGET_FILE="/workspaces/slimserver/Slim/Utils/OS/Custom.pm"
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
BRANCH="$(git -c safe.directory="$REPO_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo HEAD)"
BASE_URL="https://raw.githubusercontent.com/LMS-Community/slimserver-platforms"
TARGET_FILE="$REPO_ROOT/Slim/Utils/OS/Custom.pm"

echo "Detected branch: ${BRANCH}"
echo "Trying branch-specific file..."
echo "[INFO] Post-create setup"
git config --global --add safe.directory "$REPO_ROOT" 2>/dev/null || true

# Try downloading branch version
if curl -fSL "$URL_BRANCH" -o "$TARGET_FILE"; then
echo "Downloaded branch version from: $URL_BRANCH"
mkdir -p "$(dirname "$TARGET_FILE")"

echo "[INFO] Downloading Custom.pm for branch: $BRANCH"
if curl -fsSL "${BASE_URL}/${BRANCH}/Docker/Slim-Utils-OS-Custom.pm" -o "$TARGET_FILE" 2>/dev/null; then
echo "[INFO] Downloaded from branch '$BRANCH'"
elif curl -fsSL "${BASE_URL}/HEAD/Docker/Slim-Utils-OS-Custom.pm" -o "$TARGET_FILE" 2>/dev/null; then
echo "[INFO] Downloaded from fallback 'HEAD'"
else
echo "Branch file not found, falling back to HEAD..."
curl -fSL "$URL_HEAD" -o "$TARGET_FILE"
echo "Downloaded latest version from: $URL_HEAD"
fi
echo "[ERROR] Failed to download Custom.pm" >&2
exit 1
fi

Loading