music-assistant-home-assistant-addon

6.9 KBSH
entrypoint.sh
6.9 KB222 lines • bash
1#!/bin/sh
2set -e
3
4# Parse configuration
5server_repo=$(cat /data/options.json | jq -r .server_repo)
6frontend_repo=$(cat /data/options.json | jq -r .frontend_repo)
7
8echo ""
9echo "-----------------------------------------------------------"
10echo "Music Assistant Developer Add-on"
11echo "-----------------------------------------------------------"
12echo ""
13
14# Check if server_repo is empty or null
15if [ -z "$server_repo" ] || [ "$server_repo" = "null" ]; then
16    build_from_source=false
17    echo "No server_repo specified - using latest nightly release from GitHub"
18else
19    build_from_source=true
20    echo "Building from source using server_repo: $server_repo"
21fi
22echo ""
23
24# Function to parse repository reference and return owner/repo@ref
25parse_repo_ref() {
26    local input="$1"
27    local default_owner="$2"
28    local default_repo="$3"
29
30    # If input starts with "pr-", convert to pull request reference
31    if echo "$input" | grep -q "^pr-"; then
32        pr_number=$(echo "$input" | sed 's/pr-//')
33        echo "${default_owner}/${default_repo}@refs/pull/${pr_number}/head"
34        return
35    fi
36
37    # If input contains "/" (fork reference)
38    if echo "$input" | grep -q "/"; then
39        # Check if it already has @ for branch
40        if echo "$input" | grep -q "@"; then
41            echo "$input"
42        else
43            # It's just owner/repo, use default branch
44            echo "${input}@main"
45        fi
46        return
47    fi
48
49    # Otherwise, it's just a branch/commit reference
50    echo "${default_owner}/${default_repo}@${input}"
51}
52
53# Function to build git URL from parsed reference
54build_git_url() {
55    local parsed="$1"
56    echo "git+https://github.com/${parsed}"
57}
58
59# Activate virtual environment
60. $VIRTUAL_ENV/bin/activate
61
62echo "-----------------------------------------------------------"
63echo "Step 1: Installing Music Assistant Server"
64echo "-----------------------------------------------------------"
65echo ""
66
67if [ "$build_from_source" = true ]; then
68    # Parse server repository reference
69    server_ref=$(parse_repo_ref "$server_repo" "music-assistant" "server")
70    server_url=$(build_git_url "$server_ref")
71
72    echo "Server repository: $server_ref"
73    echo "Server URL: $server_url"
74    echo ""
75
76    # Install server from specified repository
77    uv pip install \
78        --no-cache \
79        --link-mode=copy \
80        "$server_url"
81else
82    # Install latest nightly wheel from GitHub releases
83    echo "Fetching latest nightly release from GitHub..."
84    echo ""
85
86    # Get the latest pre-release info from GitHub API
87    latest_release=$(curl -s https://api.github.com/repos/music-assistant/server/releases | jq -r '[.[] | select(.prerelease == true)] | first')
88    release_tag=$(echo "$latest_release" | jq -r '.tag_name')
89    wheel_url=$(echo "$latest_release" | jq -r '.assets[] | select(.name | endswith(".whl")) | .browser_download_url')
90
91    if [ -z "$wheel_url" ] || [ "$wheel_url" = "null" ]; then
92        echo "ERROR: Could not find wheel in latest nightly release"
93        echo "Falling back to stable PyPI release..."
94        uv pip install \
95            --no-cache \
96            --link-mode=copy \
97            music-assistant
98    else
99        echo "Found nightly release: $release_tag"
100        echo "Wheel URL: $wheel_url"
101        echo ""
102        echo "Downloading and installing nightly wheel..."
103        uv pip install \
104            --no-cache \
105            --link-mode=copy \
106            "$wheel_url"
107    fi
108fi
109
110echo ""
111echo "✓ Server installation complete"
112echo ""
113
114# Check if we should build frontend
115build_frontend=false
116if [ "$build_from_source" = true ]; then
117    # Building server from source - check if frontend_repo is specified
118    if [ -n "$frontend_repo" ] && [ "$frontend_repo" != "null" ]; then
119        build_frontend=true
120        # Parse frontend repository reference
121        frontend_ref=$(parse_repo_ref "$frontend_repo" "music-assistant" "frontend")
122
123        echo "-----------------------------------------------------------"
124        echo "Step 2: Building and Installing Music Assistant Frontend"
125        echo "-----------------------------------------------------------"
126        echo ""
127        echo "Frontend repository: $frontend_ref"
128        echo ""
129    else
130        echo "-----------------------------------------------------------"
131        echo "Step 2: Skipping Frontend Build"
132        echo "-----------------------------------------------------------"
133        echo ""
134        echo "No frontend_repo specified - using frontend bundled with server"
135        echo ""
136    fi
137else
138    echo "-----------------------------------------------------------"
139    echo "Step 2: Skipping Frontend Build"
140    echo "-----------------------------------------------------------"
141    echo ""
142    echo "Frontend build skipped - using frontend bundled with PyPI release"
143    echo ""
144fi
145
146if [ "$build_frontend" = true ]; then
147
148# Extract owner, repo, and ref from parsed reference
149frontend_owner=$(echo "$frontend_ref" | cut -d'/' -f1)
150frontend_repo_name=$(echo "$frontend_ref" | cut -d'/' -f2 | cut -d'@' -f1)
151frontend_branch=$(echo "$frontend_ref" | cut -d'@' -f2)
152
153# Create temporary directory for frontend build
154frontend_dir="/tmp/frontend-build"
155rm -rf "$frontend_dir"
156mkdir -p "$frontend_dir"
157
158echo "Cloning frontend repository..."
159cd "$frontend_dir"
160
161# Clone the repository
162git clone --depth 1 --branch "$frontend_branch" \
163    "https://github.com/${frontend_owner}/${frontend_repo_name}.git" . 2>/dev/null || \
164    git clone "https://github.com/${frontend_owner}/${frontend_repo_name}.git" . && \
165    git checkout "$frontend_branch"
166
167echo "✓ Frontend cloned"
168echo ""
169
170# Check if package.json exists (verify it's a valid frontend repo)
171if [ ! -f "package.json" ]; then
172    echo "ERROR: package.json not found in frontend repository!"
173    echo "This doesn't appear to be a valid Music Assistant frontend repository."
174    exit 1
175fi
176
177echo "Installing frontend dependencies...1"
178# Try to remount /tmp with exec if it's mounted noexec
179if mount | grep -q "on /tmp.*noexec"; then
180  echo "Detected /tmp mounted with noexec, attempting to remount..."
181  mount -o remount,exec /tmp 2>/dev/null || echo "Warning: Could not remount /tmp"
182fi
183yarn install --frozen-lockfile --prefer-offline
184
185echo "✓ Dependencies installed"
186echo ""
187
188echo "Building frontend..."
189yarn build
190
191echo "✓ Frontend build complete"
192echo ""
193
194# Check if the Python package structure exists
195if [ ! -f "setup.py" ] && [ ! -f "pyproject.toml" ]; then
196    echo "ERROR: No Python package configuration found!"
197    echo "Frontend repository must be installable as a Python package."
198    exit 1
199fi
200
201echo "Installing frontend as Python package..."
202cd "$frontend_dir"
203uv pip install --no-cache --link-mode=copy .
204
205echo "✓ Frontend installation complete"
206echo ""
207
208# Cleanup
209cd /
210rm -rf "$frontend_dir"
211
212fi  # End of build_frontend check
213
214echo "-----------------------------------------------------------"
215echo "Starting Music Assistant"
216echo "-----------------------------------------------------------"
217echo ""
218
219# Start Music Assistant
220exec mass --data-dir /data --cache-dir /data/.cache
221
222