From b6f7dd85aa7786669fb1b0a1f582d0a8d76d0b2a Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Tue, 11 Jul 2023 01:15:09 +0200 Subject: [PATCH] Revert to debian images but include uvloop and armv7 --- .github/workflows/release.yml | 42 +------- Dockerfile | 101 ++++++++++++++----- music_assistant/__main__.py | 9 +- pyproject.toml | 3 +- requirements_all.txt | 1 + rootfs/etc/services.d/music-assistant/finish | 30 ------ rootfs/etc/services.d/music-assistant/run | 11 -- rootfs/init | 49 --------- 8 files changed, 80 insertions(+), 166 deletions(-) delete mode 100755 rootfs/etc/services.d/music-assistant/finish delete mode 100755 rootfs/etc/services.d/music-assistant/run delete mode 100755 rootfs/init diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3d446530e..7d8659c23 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -81,16 +81,14 @@ jobs: id: meta uses: docker/metadata-action@v4 with: - # list of Docker images to use as base name for tags images: | ghcr.io/music-assistant/server - # we use 3 different jobs here due so we can pass the correct BUILD_ARCH - - name: Build and Push amd64 + - name: Build and Push images uses: docker/build-push-action@v4.1.1 with: context: . - platforms: linux/amd64 + platforms: linux/amd64,linux/arm64,linux/arm/v7 file: Dockerfile tags: |- ghcr.io/${{ github.repository_owner }}/server:${{ steps.tags.outputs.patch }}, @@ -102,38 +100,4 @@ jobs: labels: ${{ steps.meta.outputs.labels }} build-args: | "MASS_VERSION=${{ needs.build-and-publish-pypi.outputs.version }}" - "BUILD_ARCH=amd64" - - name: Build and Push arm64 - uses: docker/build-push-action@v4.1.1 - with: - context: . - platforms: linux/arm64 - file: Dockerfile - tags: |- - ghcr.io/${{ github.repository_owner }}/server:${{ steps.tags.outputs.patch }}, - ghcr.io/${{ github.repository_owner }}/server:${{ steps.tags.outputs.minor }}, - ghcr.io/${{ github.repository_owner }}/server:${{ steps.tags.outputs.major }}, - ghcr.io/${{ github.repository_owner }}/server:${{ steps.tags.outputs.channel }}, - ghcr.io/${{ github.repository_owner }}/server:latest - push: true - labels: ${{ steps.meta.outputs.labels }} - build-args: | - "MASS_VERSION=${{ needs.build-and-publish-pypi.outputs.version }}" - "BUILD_ARCH=aarch64" - - name: Build and Push armv7 - uses: docker/build-push-action@v4.1.1 - with: - context: . - platforms: linux/arm/v7 - file: Dockerfile - tags: |- - ghcr.io/${{ github.repository_owner }}/server:${{ steps.tags.outputs.patch }}, - ghcr.io/${{ github.repository_owner }}/server:${{ steps.tags.outputs.minor }}, - ghcr.io/${{ github.repository_owner }}/server:${{ steps.tags.outputs.major }}, - ghcr.io/${{ github.repository_owner }}/server:${{ steps.tags.outputs.channel }}, - ghcr.io/${{ github.repository_owner }}/server:latest - push: true - labels: ${{ steps.meta.outputs.labels }} - build-args: | - "MASS_VERSION=${{ needs.build-and-publish-pypi.outputs.version }}" - "BUILD_ARCH=armv7" + diff --git a/Dockerfile b/Dockerfile index 2c112ba40..ecba7d054 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,42 +1,90 @@ # syntax=docker/dockerfile:1 -ARG BUILD_ARCH -ARG BASE_IMAGE_VERSION="3.11-alpine3.18" +ARG TARGETPLATFORM +ARG PYTHON_VERSION="3.11" -FROM ghcr.io/home-assistant/$BUILD_ARCH-base-python:${BASE_IMAGE_VERSION} +##################################################################### +# # +# Build Wheels # +# # +##################################################################### +FROM python:${PYTHON_VERSION}-slim as wheels-builder +ARG TARGETPLATFORM -ARG MASS_VERSION -ENV S6_SERVICES_GRACETIME=220000 -ENV WHEELS_LINKS="https://wheels.home-assistant.io/musllinux/" -ARG UVLOOP_VERSION="0.17.0" +# Install buildtime packages +RUN set -x \ + && apt-get update \ + && apt-get install -y --no-install-recommends \ + build-essential \ + libffi-dev \ + cargo \ + git \ + curl + +WORKDIR /wheels +COPY requirements_all.txt . + + +# build python wheels for all dependencies +RUN set -x \ + && pip install --upgrade pip \ + && pip install build maturin \ + && pip wheel -r requirements_all.txt + +# build music assistant wheel +COPY music_assistant music_assistant +COPY pyproject.toml . +COPY MANIFEST.in . +RUN python3 -m build --wheel --outdir /wheels --skip-dependency-check -WORKDIR /usr/src +##################################################################### +# # +# Final Image # +# # +##################################################################### +FROM python:${PYTHON_VERSION}-slim AS final-build +WORKDIR /app -# Install OS requirements -RUN apk update \ - && apk add --no-cache \ +RUN set -x \ + && apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ git \ wget \ + tzdata \ ffmpeg \ + libsox-fmt-all \ + libsox3 \ sox \ cifs-utils \ - nfs-utils + libnfs-utils \ + libjemalloc2 \ + # cleanup + && rm -rf /tmp/* \ + && rm -rf /var/lib/apt/lists/* -## Setup Core dependencies -COPY requirements_all.txt . -RUN pip3 install \ - --no-cache-dir \ - --only-binary=:all: \ - --find-links ${WHEELS_LINKS} \ - -r requirements_all.txt -# Install Music Assistant +# https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md#build-mounts-run---mount +# Install all built wheels +RUN --mount=type=bind,target=/tmp/wheels,source=/wheels,from=wheels-builder,rw \ + set -x \ + && pip install --upgrade pip \ + && pip install --no-cache-dir /tmp/wheels/*.whl + +# Install Music Assistant from published wheel RUN pip3 install \ --no-cache-dir \ music-assistant[server]==${MASS_VERSION} \ && python3 -m compileall music-assistant -# Install optional uvloop if possible (will fail on armv7) -RUN pip3 install --no-cache-dir uvloop==${UVLOOP_VERSION}; exit 0 +# Enable jemalloc +RUN \ + export LD_PRELOAD="$(find /usr/lib/ -name *libjemalloc.so.2)" \ + export MALLOC_CONF="background_thread:true,metadata_thp:auto,dirty_decay_ms:20000,muzzy_decay_ms:20000" + +# Required to persist build arg +ARG MASS_VERSION +ARG TARGETPLATFORM # Set some labels LABEL \ @@ -46,16 +94,13 @@ LABEL \ org.opencontainers.image.authors="The Music Assistant Team" \ org.opencontainers.image.documentation="https://github.com/orgs/music-assistant/discussions" \ org.opencontainers.image.licenses="Apache License 2.0" \ - io.hass.version=${MASS_VERSION} \ + io.hass.version="${MASS_VERSION}" \ io.hass.type="addon" \ io.hass.name="Music Assistant" \ io.hass.description="Music Assistant Server/Core" \ - io.hass.platform="linux/${BUILD_ARCH}" \ + io.hass.platform="${TARGETPLATFORM}" \ io.hass.type="addon" VOLUME [ "/data" ] -# S6-Overlay -COPY rootfs / - -WORKDIR /data +ENTRYPOINT ["mass", "--config", "/data"] diff --git a/music_assistant/__main__.py b/music_assistant/__main__.py index 1097508da..41dd76fa4 100644 --- a/music_assistant/__main__.py +++ b/music_assistant/__main__.py @@ -20,13 +20,6 @@ from music_assistant.server import MusicAssistant from music_assistant.server.helpers.logging import activate_log_queue_handler -try: - import uvloop # noqa: F401 - - USE_UVLOOP = True -except ImportError: - USE_UVLOOP = False - FORMAT_DATE: Final = "%Y-%m-%d" FORMAT_TIME: Final = "%H:%M:%S" FORMAT_DATETIME: Final = f"{FORMAT_DATE} {FORMAT_TIME}" @@ -184,7 +177,7 @@ async def start_mass(): run( start_mass(), - use_uvloop=USE_UVLOOP, + use_uvloop=True, shutdown_callback=on_shutdown, executor_workers=64, ) diff --git a/pyproject.toml b/pyproject.toml index ff2461fad..d7c578470 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,8 @@ server = [ "shortuuid==1.0.11", "zeroconf==0.70.0", "cryptography==41.0.1", - "ifaddr==0.2.0" + "ifaddr==0.2.0", + "uvloop==0.17.0" ] test = [ "black==23.3.0", diff --git a/requirements_all.txt b/requirements_all.txt index 0efc27d29..ef28df0fb 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -29,6 +29,7 @@ python-slugify==8.0.1 shortuuid==1.0.11 soco==0.29.1 unidecode==1.3.6 +uvloop==0.17.0 xmltodict==0.13.0 ytmusicapi==1.0.0 zeroconf==0.70.0 diff --git a/rootfs/etc/services.d/music-assistant/finish b/rootfs/etc/services.d/music-assistant/finish deleted file mode 100755 index c8ef75064..000000000 --- a/rootfs/etc/services.d/music-assistant/finish +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bashio -# ============================================================================== -# Take down the S6 supervision tree when Music Assistant fails -# ============================================================================== -declare RESTART_EXIT_CODE=100 -declare SIGNAL_EXIT_CODE=256 -declare SIGTERM=15 -declare APP_EXIT_CODE=${1} -declare SIGNAL_NO=${2} -declare NEW_EXIT_CODE= - -bashio::log.info "Music Assistant Core finish process exit code ${APP_EXIT_CODE}" - -if [[ ${APP_EXIT_CODE} -eq ${RESTART_EXIT_CODE} ]]; then - exit 0 -elif [[ ${APP_EXIT_CODE} -eq ${SIGNAL_EXIT_CODE} ]]; then - bashio::log.info "Music Assistant Core finish process received signal ${SIGNAL_NO}" - - NEW_EXIT_CODE=$((128 + SIGNAL_NO)) - echo ${NEW_EXIT_CODE} > /run/s6-linux-init-container-results/exitcode - - if [[ ${SIGNAL_NO} -eq ${SIGTERM} ]]; then - /run/s6/basedir/bin/halt - fi -else - bashio::log.info "Music Assistant Core service shutdown" - - echo ${APP_EXIT_CODE} > /run/s6-linux-init-container-results/exitcode - /run/s6/basedir/bin/halt -fi diff --git a/rootfs/etc/services.d/music-assistant/run b/rootfs/etc/services.d/music-assistant/run deleted file mode 100755 index 7dd73f9a8..000000000 --- a/rootfs/etc/services.d/music-assistant/run +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/with-contenv bashio -# ============================================================================== -# Start Music Assistant service -# ============================================================================== - -cd /data || bashio::exit.nok "Can't find data folder!" - -# Enable jemalloc -export LD_PRELOAD="/usr/local/lib/libjemalloc.so.2" -export MALLOC_CONF="background_thread:true,metadata_thp:auto,dirty_decay_ms:20000,muzzy_decay_ms:20000" -exec python3 -m music_assistant --config /data diff --git a/rootfs/init b/rootfs/init deleted file mode 100755 index 0aa246c33..000000000 --- a/rootfs/init +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh -e - -# This is the first program launched at container start. -# We don't know where our binaries are and we cannot guarantee -# that the default PATH can access them. -# So this script needs to be entirely self-contained until it has -# at least /command, /usr/bin and /bin in its PATH. - -addpath () { - x="$1" - IFS=: - set -- $PATH - IFS= - while test "$#" -gt 0 ; do - if test "$1" = "$x" ; then - return - fi - shift - done - PATH="${x}:$PATH" -} - -if test -z "$PATH" ; then - PATH=/bin -fi - -addpath /bin -addpath /usr/bin -addpath /command -export PATH - -# Now we're good: s6-overlay-suexec is accessible via PATH, as are -# all our binaries. - -# Skip further init if the user has a given CMD. -# This is to prevent Home Assistant from starting twice if the user -# decided to override/start via the CMD. -if test $# -ne 0 ; then - exec "$@" -fi - -# Run preinit as root, then run stage0 as the container's user (can be -# root, can be a normal user). - -exec s6-overlay-suexec \ - ' /package/admin/s6-overlay/libexec/preinit' \ - '' \ - /package/admin/s6-overlay/libexec/stage0 \ - "$@"